diff --git a/packages/audio/alsa-lib/meta b/packages/audio/alsa-lib/meta index 3aa3d4890d..4b71f3839a 100644 --- a/packages/audio/alsa-lib/meta +++ b/packages/audio/alsa-lib/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="alsa-lib" -PKG_VERSION="1.0.25" +PKG_VERSION="1.0.26" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/audio/alsa-lib/patches/alsa-lib-1.0.25-001-asound.conf_configdir.patch b/packages/audio/alsa-lib/patches/alsa-lib-1.0.26-001-asound.conf_configdir.patch similarity index 100% rename from packages/audio/alsa-lib/patches/alsa-lib-1.0.25-001-asound.conf_configdir.patch rename to packages/audio/alsa-lib/patches/alsa-lib-1.0.26-001-asound.conf_configdir.patch diff --git a/packages/audio/alsa-plugins/meta b/packages/audio/alsa-plugins/meta index 6773f89f74..abcbcfcf56 100644 --- a/packages/audio/alsa-plugins/meta +++ b/packages/audio/alsa-plugins/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="alsa-plugins" -PKG_VERSION="1.0.25" +PKG_VERSION="1.0.26" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/audio/alsa-utils/meta b/packages/audio/alsa-utils/meta index a9f783ae65..6e199e33d5 100644 --- a/packages/audio/alsa-utils/meta +++ b/packages/audio/alsa-utils/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="alsa-utils" -PKG_VERSION="1.0.25" +PKG_VERSION="1.0.26" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/databases/sqlite/meta b/packages/databases/sqlite/meta index 16451186c1..37c82b2aee 100644 --- a/packages/databases/sqlite/meta +++ b/packages/databases/sqlite/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="sqlite" -PKG_VERSION="autoconf-3071300" +PKG_VERSION="autoconf-3071400" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="PublicDomain" diff --git a/packages/devel/readline/build b/packages/devel/readline/build new file mode 100755 index 0000000000..784a6c775d --- /dev/null +++ b/packages/devel/readline/build @@ -0,0 +1,40 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program 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 OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +. config/options $1 + +cd $PKG_BUILD +mkdir -p .build-target && cd .build-target +../configure --host=$TARGET_NAME \ + --build=$HOST_NAME \ + --prefix=/usr \ + --exec-prefix=/usr \ + --sysconfdir=/etc \ + --datadir=/usr/share \ + --enable-shared \ + --disable-static \ + --with-curses \ + --without-purify + +make + +$MAKEINSTALL diff --git a/packages/devel/readline/install b/packages/devel/readline/install new file mode 100755 index 0000000000..c9aaf70f03 --- /dev/null +++ b/packages/devel/readline/install @@ -0,0 +1,32 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2012 Stephan Raue (stephan@openelec.tv) +# +# This Program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This Program 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 OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Suite 500, Boston, MA 02110, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +. config/options $1 + +mkdir -p $INSTALL/usr/lib + cp -P $PKG_BUILD/.build-target/shlib/libreadline.so.6.2 $INSTALL/usr/lib + ln -sf /usr/lib/libreadline.so.6.2 $INSTALL/usr/lib/libreadline.so.6 + ln -sf /usr/lib/libreadline.so.6 $INSTALL/usr/lib/libreadline.so + + cp -P $PKG_BUILD/.build-target/shlib/libhistory.so.6.2 $INSTALL/usr/lib + ln -sf /usr/lib/libhistory.so.6.2 $INSTALL/usr/lib/libhistory.so.6 + ln -sf /usr/lib/libhistory.so.6 $INSTALL/usr/lib/libhistory.so diff --git a/packages/devel/readline/meta b/packages/devel/readline/meta index ad6789657a..8bb7b91238 100644 --- a/packages/devel/readline/meta +++ b/packages/devel/readline/meta @@ -25,12 +25,12 @@ PKG_ARCH="any" PKG_LICENSE="MIT" PKG_SITE="http://www.gnu.org/readline" PKG_URL="ftp://ftp.gnu.org/gnu/readline/$PKG_NAME-$PKG_VERSION.tar.gz" -PKG_DEPENDS="" -PKG_BUILD_DEPENDS="toolchain" +PKG_DEPENDS="ncurses" +PKG_BUILD_DEPENDS="toolchain ncurses" PKG_PRIORITY="optional" PKG_SECTION="devel" PKG_SHORTDESC="readline: The GNU Readline library provides a set of functions for use by applications that allow users to edit command lines as they are typed in." PKG_LONGDESC="The GNU Readline library provides a set of functions for use by applications that allow users to edit command lines as they are typed in." PKG_IS_ADDON="no" -PKG_AUTORECONF="yes" +PKG_AUTORECONF="no" diff --git a/packages/devel/readline/patches/readline-6.2-shlib_libs.patch b/packages/devel/readline/patches/readline-6.2-shlib_libs.patch new file mode 100644 index 0000000000..6bc7cc2330 --- /dev/null +++ b/packages/devel/readline/patches/readline-6.2-shlib_libs.patch @@ -0,0 +1,36 @@ +diff -Naur readline-6.2-old/configure readline-6.2-new/configure +--- a/configure 2010-11-14 14:48:06.000000000 -0800 ++++ b/configure 2012-05-02 19:38:49.000000000 -0700 +@@ -10450,10 +10450,10 @@ + $as_echo_n "checking configuration for building shared libraries... " >&6; } + eval `TERMCAP_LIB=$TERMCAP_LIB ${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}` + +-# case "$SHLIB_LIBS" in +-# *curses*|*termcap*|*termlib*) ;; +-# *) SHLIB_LIBS="$SHLIB_LIBS $TERMCAP_LIB" ;; +-# esac ++ case "$SHLIB_LIBS" in ++ *curses*|*termcap*|*termlib*) ;; ++ *) SHLIB_LIBS="$SHLIB_LIBS $TERMCAP_LIB" ;; ++ esac + + + +diff -Naur readline-6.2-old/configure.in readline-6.2-new/configure.in +--- a/configure.in 2010-11-14 14:41:48.000000000 -0800 ++++ b/configure.in 2012-05-02 19:38:41.000000000 -0700 +@@ -214,10 +214,10 @@ + AC_MSG_CHECKING(configuration for building shared libraries) + eval `TERMCAP_LIB=$TERMCAP_LIB ${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}` + +-# case "$SHLIB_LIBS" in +-# *curses*|*termcap*|*termlib*) ;; +-# *) SHLIB_LIBS="$SHLIB_LIBS $TERMCAP_LIB" ;; +-# esac ++ case "$SHLIB_LIBS" in ++ *curses*|*termcap*|*termlib*) ;; ++ *) SHLIB_LIBS="$SHLIB_LIBS $TERMCAP_LIB" ;; ++ esac + + AC_SUBST(SHOBJ_CC) + AC_SUBST(SHOBJ_CFLAGS) diff --git a/packages/graphics/bcm2835-driver/meta b/packages/graphics/bcm2835-driver/meta index 4dccdd02dc..984317e282 100644 --- a/packages/graphics/bcm2835-driver/meta +++ b/packages/graphics/bcm2835-driver/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="bcm2835-driver" -PKG_VERSION="f20e9d7" +PKG_VERSION="2997db1" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="nonfree" diff --git a/packages/linux/meta b/packages/linux/meta index 3536bfe12b..1ed14f3b9d 100644 --- a/packages/linux/meta +++ b/packages/linux/meta @@ -21,7 +21,7 @@ PKG_NAME="linux" PKG_VERSION="3.5.4" if [ "$LINUX" = "3.2" ]; then - PKG_VERSION="3.2.28" + PKG_VERSION="3.2.30" fi PKG_REV="1" PKG_ARCH="any" diff --git a/packages/linux/patches/linux-3.2.28-000_crosscompile.patch b/packages/linux/patches/linux-3.2.30-000_crosscompile.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-000_crosscompile.patch rename to packages/linux/patches/linux-3.2.30-000_crosscompile.patch diff --git a/packages/linux/patches/linux-3.2.28-003-no_dev_console.patch b/packages/linux/patches/linux-3.2.30-003-no_dev_console.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-003-no_dev_console.patch rename to packages/linux/patches/linux-3.2.30-003-no_dev_console.patch diff --git a/packages/linux/patches/linux-3.2.28-004_lower_undefined_mode_timeout.patch b/packages/linux/patches/linux-3.2.30-004_lower_undefined_mode_timeout.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-004_lower_undefined_mode_timeout.patch rename to packages/linux/patches/linux-3.2.30-004_lower_undefined_mode_timeout.patch diff --git a/packages/linux/patches/linux-3.2.28-006_enable_utf8.patch b/packages/linux/patches/linux-3.2.30-006_enable_utf8.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-006_enable_utf8.patch rename to packages/linux/patches/linux-3.2.30-006_enable_utf8.patch diff --git a/packages/linux/patches/linux-3.2.28-007_die_floppy_die.patch b/packages/linux/patches/linux-3.2.30-007_die_floppy_die.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-007_die_floppy_die.patch rename to packages/linux/patches/linux-3.2.30-007_die_floppy_die.patch diff --git a/packages/linux/patches/linux-3.2.28-009_disable_i8042_check_on_apple_mac.patch b/packages/linux/patches/linux-3.2.30-009_disable_i8042_check_on_apple_mac.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-009_disable_i8042_check_on_apple_mac.patch rename to packages/linux/patches/linux-3.2.30-009_disable_i8042_check_on_apple_mac.patch diff --git a/packages/linux/patches/linux-3.2.28-052-aureal_remote_quirk-0.1.patch b/packages/linux/patches/linux-3.2.30-052-aureal_remote_quirk-0.1.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-052-aureal_remote_quirk-0.1.patch rename to packages/linux/patches/linux-3.2.30-052-aureal_remote_quirk-0.1.patch diff --git a/packages/linux/patches/linux-3.2.28-053-spinelplus-remote-0.1.patch b/packages/linux/patches/linux-3.2.30-053-spinelplus-remote-0.1.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-053-spinelplus-remote-0.1.patch rename to packages/linux/patches/linux-3.2.30-053-spinelplus-remote-0.1.patch diff --git a/packages/linux/patches/linux-3.2.28-054-nuvoton_revert_d7b290a1056c5564eec8a1b169c6e84ff3f54c13.patch b/packages/linux/patches/linux-3.2.30-054-nuvoton_revert_d7b290a1056c5564eec8a1b169c6e84ff3f54c13.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-054-nuvoton_revert_d7b290a1056c5564eec8a1b169c6e84ff3f54c13.patch rename to packages/linux/patches/linux-3.2.30-054-nuvoton_revert_d7b290a1056c5564eec8a1b169c6e84ff3f54c13.patch diff --git a/packages/linux/patches/linux-3.2.28-056-Formosa-IR606.patch b/packages/linux/patches/linux-3.2.30-056-Formosa-IR606.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-056-Formosa-IR606.patch rename to packages/linux/patches/linux-3.2.30-056-Formosa-IR606.patch diff --git a/packages/linux/patches/linux-3.2.28-057.01-media-ati_remote-allow-specifying-a-default-keymap-s.patch b/packages/linux/patches/linux-3.2.30-057.01-media-ati_remote-allow-specifying-a-default-keymap-s.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-057.01-media-ati_remote-allow-specifying-a-default-keymap-s.patch rename to packages/linux/patches/linux-3.2.30-057.01-media-ati_remote-allow-specifying-a-default-keymap-s.patch diff --git a/packages/linux/patches/linux-3.2.28-057.02-media-ati_remote-add-support-for-Medion-X10-Digitain.patch b/packages/linux/patches/linux-3.2.30-057.02-media-ati_remote-add-support-for-Medion-X10-Digitain.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-057.02-media-ati_remote-add-support-for-Medion-X10-Digitain.patch rename to packages/linux/patches/linux-3.2.30-057.02-media-ati_remote-add-support-for-Medion-X10-Digitain.patch diff --git a/packages/linux/patches/linux-3.2.28-057.03-media-ati_remote-add-keymap-for-Medion-X10-OR2x-remo.patch b/packages/linux/patches/linux-3.2.30-057.03-media-ati_remote-add-keymap-for-Medion-X10-OR2x-remo.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-057.03-media-ati_remote-add-keymap-for-Medion-X10-OR2x-remo.patch rename to packages/linux/patches/linux-3.2.30-057.03-media-ati_remote-add-keymap-for-Medion-X10-OR2x-remo.patch diff --git a/packages/linux/patches/linux-3.2.28-057.04-media-ati_remote-add-regular-up-down-buttons-to-Medi.patch b/packages/linux/patches/linux-3.2.30-057.04-media-ati_remote-add-regular-up-down-buttons-to-Medi.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-057.04-media-ati_remote-add-regular-up-down-buttons-to-Medi.patch rename to packages/linux/patches/linux-3.2.30-057.04-media-ati_remote-add-regular-up-down-buttons-to-Medi.patch diff --git a/packages/linux/patches/linux-3.2.30-071-silence_i915_agp-module-0.1.patch b/packages/linux/patches/linux-3.2.30-071-silence_i915_agp-module-0.1.patch new file mode 100644 index 0000000000..81bbc8c362 --- /dev/null +++ b/packages/linux/patches/linux-3.2.30-071-silence_i915_agp-module-0.1.patch @@ -0,0 +1,12 @@ +diff -Naur linux-2.6.39-rc5/drivers/gpu/drm/i915/i915_drv.c linux-2.6.39-rc5.patch/drivers/gpu/drm/i915/i915_drv.c +--- linux-2.6.39-rc5/drivers/gpu/drm/i915/i915_drv.c 2011-04-27 05:48:50.000000000 +0200 ++++ linux-2.6.39-rc5.patch/drivers/gpu/drm/i915/i915_drv.c 2011-04-29 02:51:28.773622809 +0200 +@@ -760,7 +760,7 @@ + static int __init i915_init(void) + { + if (!intel_agp_enabled) { +- DRM_ERROR("drm/i915 can't work without intel_agp module!\n"); ++ DRM_INFO("drm/i915 can't work without intel_agp module!\n"); + return -ENODEV; + } + diff --git a/packages/linux/patches/linux-3.2.30-081-drm_cea_modes.patch b/packages/linux/patches/linux-3.2.30-081-drm_cea_modes.patch new file mode 100644 index 0000000000..57058c1107 --- /dev/null +++ b/packages/linux/patches/linux-3.2.30-081-drm_cea_modes.patch @@ -0,0 +1,358 @@ +diff -Naur linux-3.1.2/drivers/gpu/drm/drm_edid.c linux-3.1.2.patch/drivers/gpu/drm/drm_edid.c +--- linux-3.1.2/drivers/gpu/drm/drm_edid.c 2011-11-21 23:47:46.000000000 +0100 ++++ linux-3.1.2.patch/drivers/gpu/drm/drm_edid.c 2011-11-23 00:35:54.444938016 +0100 +@@ -1318,6 +1318,7 @@ + + #define HDMI_IDENTIFIER 0x000C03 + #define AUDIO_BLOCK 0x01 ++#define VIDEO_BLOCK 0x02 + #define VENDOR_BLOCK 0x03 + #define EDID_BASIC_AUDIO (1 << 6) + +@@ -1347,6 +1348,47 @@ + } + EXPORT_SYMBOL(drm_find_cea_extension); + ++static int ++do_cea_modes (struct drm_connector *connector, u8 *db, u8 len) ++{ ++ struct drm_device *dev = connector->dev; ++ u8 * mode, cea_mode; ++ int modes = 0; ++ ++ for (mode = db; mode < db + len; mode++) { ++ cea_mode = (*mode & 127) - 1; /* CEA modes are numbered 1..127 */ ++ if (cea_mode < drm_num_cea_modes) { ++ struct drm_display_mode *newmode; ++ newmode = drm_mode_duplicate(dev, ++ &edid_cea_modes[cea_mode]); ++ if (newmode) { ++ drm_mode_probed_add(connector, newmode); ++ modes++; ++ } ++ } ++ } ++ ++ return modes; ++} ++ ++static int ++add_cea_modes(struct drm_connector *connector, struct edid *edid) ++{ ++ u8 * cea = drm_find_cea_extension(edid); ++ u8 * db, dbl; ++ int modes = 0; ++ ++ if (cea && cea[1] >= 3) { ++ for (db = cea + 4; db < cea + cea[2]; db += dbl + 1) { ++ dbl = db[0] & 0x1f; ++ if (((db[0] & 0xe0) >> 5) == VIDEO_BLOCK) ++ modes += do_cea_modes (connector, db+1, dbl); ++ } ++ } ++ ++ return modes; ++} ++ + /** + * drm_detect_hdmi_monitor - detect whether monitor is hdmi. + * @edid: monitor EDID information +@@ -1550,6 +1592,7 @@ + num_modes += add_standard_modes(connector, edid); + num_modes += add_established_modes(connector, edid); + num_modes += add_inferred_modes(connector, edid); ++ num_modes += add_cea_modes(connector, edid); + + if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) + edid_fixup_preferred(connector, quirks); +diff -Naur linux-3.1.2/drivers/gpu/drm/drm_edid_modes.h linux-3.1.2.patch/drivers/gpu/drm/drm_edid_modes.h +--- linux-3.1.2/drivers/gpu/drm/drm_edid_modes.h 2011-11-21 23:47:46.000000000 +0100 ++++ linux-3.1.2.patch/drivers/gpu/drm/drm_edid_modes.h 2011-11-23 00:31:42.218643364 +0100 +@@ -378,3 +378,287 @@ + { 1920, 1440, 75, 0 }, + }; + static const int num_est3_modes = sizeof(est3_modes) / sizeof(est3_modes[0]); ++ ++/* ++ * Probably taken from CEA-861 spec. ++ * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c. ++ */ ++static const struct drm_display_mode edid_cea_modes[] = { ++ /* 640x480@60Hz */ ++ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, ++ 752, 800, 0, 480, 490, 492, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 720x480@60Hz */ ++ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736, ++ 798, 858, 0, 480, 489, 495, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 720x480@60Hz */ ++ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736, ++ 798, 858, 0, 480, 489, 495, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1280x720@60Hz */ ++ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390, ++ 1430, 1650, 0, 720, 725, 730, 750, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 1920x1080i@60Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008, ++ 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1440x480i@60Hz */ ++ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, ++ 1602, 1716, 0, 480, 488, 494, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1440x480i@60Hz */ ++ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, ++ 1602, 1716, 0, 480, 488, 494, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1440x240@60Hz */ ++ { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, ++ 1602, 1716, 0, 240, 244, 247, 262, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1440x240@60Hz */ ++ { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, ++ 1602, 1716, 0, 240, 244, 247, 262, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 2880x480i@60Hz */ ++ { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, ++ 3204, 3432, 0, 480, 488, 494, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 2880x480i@60Hz */ ++ { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, ++ 3204, 3432, 0, 480, 488, 494, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 2880x240@60Hz */ ++ { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, ++ 3204, 3432, 0, 240, 244, 247, 262, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 2880x240@60Hz */ ++ { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, ++ 3204, 3432, 0, 240, 244, 247, 262, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1440x480@60Hz */ ++ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472, ++ 1596, 1716, 0, 480, 489, 495, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1440x480@60Hz */ ++ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472, ++ 1596, 1716, 0, 480, 489, 495, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1920x1080@60Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, ++ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 720x576@50Hz */ ++ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, ++ 796, 864, 0, 576, 581, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 720x576@50Hz */ ++ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, ++ 796, 864, 0, 576, 581, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1280x720@50Hz */ ++ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720, ++ 1760, 1980, 0, 720, 725, 730, 750, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 1920x1080i@50Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448, ++ 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1440x576i@50Hz */ ++ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, ++ 1590, 1728, 0, 576, 580, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1440x576i@50Hz */ ++ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, ++ 1590, 1728, 0, 576, 580, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1440x288@50Hz */ ++ { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, ++ 1590, 1728, 0, 288, 290, 293, 312, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1440x288@50Hz */ ++ { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, ++ 1590, 1728, 0, 288, 290, 293, 312, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 2880x576i@50Hz */ ++ { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, ++ 3180, 3456, 0, 576, 580, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 2880x576i@50Hz */ ++ { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, ++ 3180, 3456, 0, 576, 580, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 2880x288@50Hz */ ++ { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, ++ 3180, 3456, 0, 288, 290, 293, 312, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 2880x288@50Hz */ ++ { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, ++ 3180, 3456, 0, 288, 290, 293, 312, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1440x576@50Hz */ ++ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, ++ 1592, 1728, 0, 576, 581, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1440x576@50Hz */ ++ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, ++ 1592, 1728, 0, 576, 581, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1920x1080@50Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448, ++ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 1920x1080@24Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558, ++ 2602, 2750, 0, 1080, 1084, 1089, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 1920x1080@25Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448, ++ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 1920x1080@30Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008, ++ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 2880x480@60Hz */ ++ { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944, ++ 3192, 3432, 0, 480, 489, 495, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 2880x480@60Hz */ ++ { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944, ++ 3192, 3432, 0, 480, 489, 495, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 2880x576@50Hz */ ++ { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928, ++ 3184, 3456, 0, 576, 581, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 2880x576@50Hz */ ++ { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928, ++ 3184, 3456, 0, 576, 581, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1920x1080i@50Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952, ++ 2120, 2304, 0, 1080, 1126, 1136, 1250, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1920x1080i@100Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448, ++ 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1280x720@100Hz */ ++ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720, ++ 1760, 1980, 0, 720, 725, 730, 750, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 720x576@100Hz */ ++ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, ++ 796, 864, 0, 576, 581, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 720x576@100Hz */ ++ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, ++ 796, 864, 0, 576, 581, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1440x576i@100Hz */ ++ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, ++ 1590, 1728, 0, 576, 580, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1440x576i@100Hz */ ++ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, ++ 1590, 1728, 0, 576, 580, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1920x1080i@120Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, ++ 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1280x720@120Hz */ ++ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390, ++ 1430, 1650, 0, 720, 725, 730, 750, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 720x480@120Hz */ ++ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736, ++ 798, 858, 0, 480, 489, 495, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 720x480@120Hz */ ++ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736, ++ 798, 858, 0, 480, 489, 495, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1440x480i@120Hz */ ++ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478, ++ 1602, 1716, 0, 480, 488, 494, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1440x480i@120Hz */ ++ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478, ++ 1602, 1716, 0, 480, 488, 494, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 720x576@200Hz */ ++ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, ++ 796, 864, 0, 576, 581, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 720x576@200Hz */ ++ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, ++ 796, 864, 0, 576, 581, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1440x576i@200Hz */ ++ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464, ++ 1590, 1728, 0, 576, 580, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1440x576i@200Hz */ ++ { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464, ++ 1590, 1728, 0, 576, 580, 586, 625, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 720x480@240Hz */ ++ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, ++ 798, 858, 0, 480, 489, 495, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 720x480@240Hz */ ++ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, ++ 798, 858, 0, 480, 489, 495, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, ++ /* 1440x480i@240 */ ++ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478, ++ 1602, 1716, 0, 480, 488, 494, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1440x480i@240 */ ++ { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478, ++ 1602, 1716, 0, 480, 488, 494, 525, 0, ++ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | ++ DRM_MODE_FLAG_INTERLACE) }, ++ /* 1280x720@24Hz */ ++ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040, ++ 3080, 3300, 0, 720, 725, 730, 750, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 1280x720@25Hz */ ++ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700, ++ 3740, 3960, 0, 720, 725, 730, 750, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 1280x720@30Hz */ ++ { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040, ++ 3080, 3300, 0, 720, 725, 730, 750, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 1920x1080@120Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008, ++ 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++ /* 1920x1080@100Hz */ ++ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448, ++ 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, ++ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, ++}; ++static const int drm_num_cea_modes = ++ sizeof (edid_cea_modes) / sizeof (edid_cea_modes[0]); diff --git a/packages/linux/patches/linux-3.2.30-201-add_Anysee_T2C_support-0.1.patch b/packages/linux/patches/linux-3.2.30-201-add_Anysee_T2C_support-0.1.patch new file mode 100644 index 0000000000..4242e6b337 --- /dev/null +++ b/packages/linux/patches/linux-3.2.30-201-add_Anysee_T2C_support-0.1.patch @@ -0,0 +1,845 @@ +diff -Naur linux-3.2.1/drivers/media/common/tuners/tda18212.c linux-3.2.1.patch/drivers/media/common/tuners/tda18212.c +--- linux-3.2.1/drivers/media/common/tuners/tda18212.c 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/common/tuners/tda18212.c 2012-01-22 16:07:33.176264363 +0100 +@@ -25,6 +25,8 @@ + struct tda18212_priv { + struct tda18212_config *cfg; + struct i2c_adapter *i2c; ++ ++ u32 if_frequency; + }; + + #define dbg(fmt, arg...) \ +@@ -136,12 +138,24 @@ + int ret, i; + u32 if_khz; + u8 buf[9]; ++ #define DVBT_6 0 ++ #define DVBT_7 1 ++ #define DVBT_8 2 ++ #define DVBT2_6 3 ++ #define DVBT2_7 4 ++ #define DVBT2_8 5 ++ #define DVBC_6 6 ++ #define DVBC_8 7 + static const u8 bw_params[][3] = { +- /* 0f 13 23 */ +- { 0xb3, 0x20, 0x03 }, /* DVB-T 6 MHz */ +- { 0xb3, 0x31, 0x01 }, /* DVB-T 7 MHz */ +- { 0xb3, 0x22, 0x01 }, /* DVB-T 8 MHz */ +- { 0x92, 0x53, 0x03 }, /* DVB-C */ ++ /* reg: 0f 13 23 */ ++ [DVBT_6] = { 0xb3, 0x20, 0x03 }, ++ [DVBT_7] = { 0xb3, 0x31, 0x01 }, ++ [DVBT_8] = { 0xb3, 0x22, 0x01 }, ++ [DVBT2_6] = { 0xbc, 0x20, 0x03 }, ++ [DVBT2_7] = { 0xbc, 0x72, 0x03 }, ++ [DVBT2_8] = { 0xbc, 0x22, 0x01 }, ++ [DVBC_6] = { 0x92, 0x50, 0x03 }, ++ [DVBC_8] = { 0x92, 0x53, 0x03 }, + }; + + dbg("delsys=%d RF=%d BW=%d\n", +@@ -155,15 +169,34 @@ + switch (c->bandwidth_hz) { + case 6000000: + if_khz = priv->cfg->if_dvbt_6; +- i = 0; ++ i = DVBT_6; + break; + case 7000000: + if_khz = priv->cfg->if_dvbt_7; +- i = 1; ++ i = DVBT_7; + break; + case 8000000: + if_khz = priv->cfg->if_dvbt_8; +- i = 2; ++ i = DVBT_8; ++ break; ++ default: ++ ret = -EINVAL; ++ goto error; ++ } ++ break; ++ case SYS_DVBT2: ++ switch (c->bandwidth_hz) { ++ case 6000000: ++ if_khz = priv->cfg->if_dvbt2_6; ++ i = DVBT2_6; ++ break; ++ case 7000000: ++ if_khz = priv->cfg->if_dvbt2_7; ++ i = DVBT2_7; ++ break; ++ case 8000000: ++ if_khz = priv->cfg->if_dvbt2_8; ++ i = DVBT2_8; + break; + default: + ret = -EINVAL; +@@ -172,7 +205,7 @@ + break; + case SYS_DVBC_ANNEX_AC: + if_khz = priv->cfg->if_dvbc; +- i = 3; ++ i = DVBC_8; + break; + default: + ret = -EINVAL; +@@ -194,7 +227,7 @@ + buf[0] = 0x02; + buf[1] = bw_params[i][1]; + buf[2] = 0x03; /* default value */ +- buf[3] = if_khz / 50; ++ buf[3] = DIV_ROUND_CLOSEST(if_khz, 50); + buf[4] = ((c->frequency / 1000) >> 16) & 0xff; + buf[5] = ((c->frequency / 1000) >> 8) & 0xff; + buf[6] = ((c->frequency / 1000) >> 0) & 0xff; +@@ -204,6 +237,9 @@ + if (ret) + goto error; + ++ /* actual IF rounded as it is on register */ ++ priv->if_frequency = buf[3] * 50 * 1000; ++ + exit: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ +@@ -215,6 +251,15 @@ + goto exit; + } + ++static int tda18212_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) ++{ ++ struct tda18212_priv *priv = fe->tuner_priv; ++ ++ *frequency = priv->if_frequency; ++ ++ return 0; ++} ++ + static int tda18212_release(struct dvb_frontend *fe) + { + kfree(fe->tuner_priv); +@@ -234,6 +279,7 @@ + .release = tda18212_release, + + .set_params = tda18212_set_params, ++ .get_if_frequency = tda18212_get_if_frequency, + }; + + struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe, +diff -Naur linux-3.2.1/drivers/media/common/tuners/tda18212.h linux-3.2.1.patch/drivers/media/common/tuners/tda18212.h +--- linux-3.2.1/drivers/media/common/tuners/tda18212.h 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/common/tuners/tda18212.h 2012-01-22 16:07:33.176264363 +0100 +@@ -29,6 +29,10 @@ + u16 if_dvbt_6; + u16 if_dvbt_7; + u16 if_dvbt_8; ++ u16 if_dvbt2_5; ++ u16 if_dvbt2_6; ++ u16 if_dvbt2_7; ++ u16 if_dvbt2_8; + u16 if_dvbc; + }; + +diff -Naur linux-3.2.1/drivers/media/dvb/dvb-usb/anysee.c linux-3.2.1.patch/drivers/media/dvb/dvb-usb/anysee.c +--- linux-3.2.1/drivers/media/dvb/dvb-usb/anysee.c 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/dvb/dvb-usb/anysee.c 2012-01-22 16:09:04.983927302 +0100 +@@ -41,6 +41,7 @@ + #include "stv0900.h" + #include "stv6110.h" + #include "isl6423.h" ++#include "cxd2820r.h" + + /* debug */ + static int dvb_usb_anysee_debug; +@@ -66,10 +67,12 @@ + if (mutex_lock_interruptible(&anysee_usb_mutex) < 0) + return -EAGAIN; + ++ deb_xfer(">>> "); ++ debug_dump(buf, slen, deb_xfer); ++ + /* We need receive one message more after dvb_usb_generic_rw due + to weird transaction flow, which is 1 x send + 2 x receive. */ + ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); +- + if (!ret) { + /* receive 2nd answer */ + ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, +@@ -79,7 +82,10 @@ + err("%s: recv bulk message failed: %d", __func__, ret); + else { + deb_xfer("<<< "); +- debug_dump(buf, act_len, deb_xfer); ++ debug_dump(buf, rlen, deb_xfer); ++ ++ if (buf[63] != 0x4f) ++ deb_info("%s: cmd failed\n", __func__); + } + } + +@@ -129,6 +135,29 @@ + return anysee_write_reg(d, reg, val); + } + ++/* read single register with mask */ ++static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val, ++ u8 mask) ++{ ++ int ret, i; ++ u8 tmp; ++ ++ ret = anysee_read_reg(d, reg, &tmp); ++ if (ret) ++ return ret; ++ ++ tmp &= mask; ++ ++ /* find position of the first bit */ ++ for (i = 0; i < 8; i++) { ++ if ((mask >> i) & 0x01) ++ break; ++ } ++ *val = tmp >> i; ++ ++ return 0; ++} ++ + static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) + { + u8 buf[] = {CMD_GET_HW_INFO}; +@@ -156,22 +185,6 @@ + return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); + } + +-static int anysee_init(struct dvb_usb_device *d) +-{ +- int ret; +- /* LED light */ +- ret = anysee_led_ctrl(d, 0x01, 0x03); +- if (ret) +- return ret; +- +- /* enable IR */ +- ret = anysee_ir_ctrl(d, 1); +- if (ret) +- return ret; +- +- return 0; +-} +- + /* I2C */ + static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, + int num) +@@ -297,7 +310,7 @@ + .pll_m = 12, + .pll_p = 3, + .pll_n = 1, +- .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C, ++ .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B, + .deltaf = 0xba02, + }; + +@@ -309,6 +322,17 @@ + .if_dvbc = 5000, + }; + ++static struct tda18212_config anysee_tda18212_config2 = { ++ .i2c_address = 0x60 /* (0xc0 >> 1) */, ++ .if_dvbt_6 = 3550, ++ .if_dvbt_7 = 3700, ++ .if_dvbt_8 = 4150, ++ .if_dvbt2_6 = 3250, ++ .if_dvbt2_7 = 4000, ++ .if_dvbt2_8 = 4000, ++ .if_dvbc = 5000, ++}; ++ + static struct cx24116_config anysee_cx24116_config = { + .demod_address = (0xaa >> 1), + .mpg_clk_pos_pol = 0x00, +@@ -339,6 +363,18 @@ + .addr = (0x10 >> 1), + }; + ++static struct cxd2820r_config anysee_cxd2820r_config = { ++ .i2c_address = 0x6d, /* (0xda >> 1) */ ++ .ts_mode = 0x38, ++ .if_dvbt_6 = 3550, ++ .if_dvbt_7 = 3700, ++ .if_dvbt_8 = 4150, ++ .if_dvbt2_6 = 3250, ++ .if_dvbt2_7 = 4000, ++ .if_dvbt2_8 = 4000, ++ .if_dvbc = 5000, ++}; ++ + /* + * New USB device strings: Mfr=1, Product=2, SerialNumber=0 + * Manufacturer: AMT.CO.KR +@@ -421,6 +457,14 @@ + * IOA[7] TS 1=enabled + * IOE[5] STV0903 1=enabled + * ++ * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)" ++ * PCB: 508T2C (rev0.3) ++ * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024 ++ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff ++ * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4 ++ * IOA[7] TS 1=enabled ++ * IOE[5] CXD2820R 1=enabled ++ * + * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)" + * PCB: 508PTC (rev0.5) + * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212) +@@ -437,7 +481,7 @@ + * IOD[6] ZL10353 1=enabled + * IOE[0] IF 0=enabled + * +- * E7 S2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)" ++ * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)" + * PCB: 508PS2 (rev0.4) + * parts: DNBU10512IST(STV0903, STV6110), ISL6423 + * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff +@@ -446,6 +490,16 @@ + * IOE[5] STV0903 1=enabled + */ + ++ ++/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */ ++static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) ++{ ++ struct dvb_usb_adapter *adap = fe->dvb->priv; ++ ++ /* enable / disable tuner access on IOE[4] */ ++ return anysee_wr_reg_mask(adap->dev, REG_IOE, (enable << 4), 0x10); ++} ++ + static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff) + { + struct dvb_usb_adapter *adap = fe->dvb->priv; +@@ -577,7 +631,8 @@ + /* detect hardware only once */ + if (adap->fe_adap[0].fe == NULL) { + /* Check which hardware we have. +- * We must do this call two times to get reliable values (hw bug). ++ * We must do this call two times to get reliable values ++ * (hw/fw bug). + */ + ret = anysee_get_hw_info(adap->dev, hw_info); + if (ret) +@@ -606,14 +661,14 @@ + break; + + /* attach demod */ +- adap->fe_adap[0].fe = dvb_attach(mt352_attach, &anysee_mt352_config, +- &adap->dev->i2c_adap); ++ adap->fe_adap[0].fe = dvb_attach(mt352_attach, ++ &anysee_mt352_config, &adap->dev->i2c_adap); + if (adap->fe_adap[0].fe) + break; + + /* attach demod */ +- adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, +- &adap->dev->i2c_adap); ++ adap->fe_adap[0].fe = dvb_attach(zl10353_attach, ++ &anysee_zl10353_config, &adap->dev->i2c_adap); + + break; + case ANYSEE_HW_507CD: /* 6 */ +@@ -665,8 +720,8 @@ + goto error; + + /* attach demod */ +- adap->fe_adap[0].fe = dvb_attach(cx24116_attach, &anysee_cx24116_config, +- &adap->dev->i2c_adap); ++ adap->fe_adap[0].fe = dvb_attach(cx24116_attach, ++ &anysee_cx24116_config, &adap->dev->i2c_adap); + + break; + case ANYSEE_HW_507FA: /* 15 */ +@@ -747,17 +802,19 @@ + } + } + ++ /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */ ++ if (tmp == 0xc7) { ++ if (adap->fe_adap[state->fe_id].fe) ++ adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = ++ anysee_i2c_gate_ctrl; ++ } ++ + break; + case ANYSEE_HW_508TC: /* 18 */ + case ANYSEE_HW_508PTC: /* 21 */ + /* E7 TC */ + /* E7 PTC */ + +- /* enable transport stream on IOA[7] */ +- ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); +- if (ret) +- goto error; +- + if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) { + /* disable DVB-T demod on IOD[6] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), +@@ -772,7 +829,8 @@ + goto error; + + /* attach demod */ +- adap->fe_adap[state->fe_id].fe = dvb_attach(tda10023_attach, ++ adap->fe_adap[state->fe_id].fe = ++ dvb_attach(tda10023_attach, + &anysee_tda10023_tda18212_config, + &adap->dev->i2c_adap, 0x48); + } else { +@@ -789,11 +847,19 @@ + goto error; + + /* attach demod */ +- adap->fe_adap[state->fe_id].fe = dvb_attach(zl10353_attach, ++ adap->fe_adap[state->fe_id].fe = ++ dvb_attach(zl10353_attach, + &anysee_zl10353_tda18212_config, + &adap->dev->i2c_adap); + } + ++ /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */ ++ if (adap->fe_adap[state->fe_id].fe) ++ adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl = ++ anysee_i2c_gate_ctrl; ++ ++ state->has_ci = true; ++ + break; + case ANYSEE_HW_508S2: /* 19 */ + case ANYSEE_HW_508PS2: /* 22 */ +@@ -803,19 +869,35 @@ + if (state->fe_id) + break; + +- /* enable transport stream on IOA[7] */ +- ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); ++ /* enable DVB-S/S2 demod on IOE[5] */ ++ ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); + if (ret) + goto error; + +- /* enable DVB-S/S2 demod on IOE[5] */ ++ /* attach demod */ ++ adap->fe_adap[0].fe = dvb_attach(stv0900_attach, ++ &anysee_stv0900_config, &adap->dev->i2c_adap, 0); ++ ++ state->has_ci = true; ++ ++ break; ++ case ANYSEE_HW_508T2C: /* 20 */ ++ /* E7 T2C */ ++ ++ if (state->fe_id) ++ break; ++ ++ /* enable DVB-T/T2/C demod on IOE[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20); + if (ret) + goto error; + + /* attach demod */ +- adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config, +- &adap->dev->i2c_adap, 0); ++ adap->fe_adap[state->fe_id].fe = dvb_attach(cxd2820r_attach, ++ &anysee_cxd2820r_config, &adap->dev->i2c_adap, ++ NULL); ++ ++ state->has_ci = true; + + break; + } +@@ -842,24 +924,26 @@ + /* E30 */ + + /* attach tuner */ +- fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), +- NULL, DVB_PLL_THOMSON_DTT7579); ++ fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, ++ (0xc2 >> 1), NULL, DVB_PLL_THOMSON_DTT7579); + + break; + case ANYSEE_HW_507CD: /* 6 */ + /* E30 Plus */ + + /* attach tuner */ +- fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), +- &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579); ++ fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, ++ (0xc2 >> 1), &adap->dev->i2c_adap, ++ DVB_PLL_THOMSON_DTT7579); + + break; + case ANYSEE_HW_507DC: /* 10 */ + /* E30 C Plus */ + + /* attach tuner */ +- fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc0 >> 1), +- &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); ++ fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, ++ (0xc0 >> 1), &adap->dev->i2c_adap, ++ DVB_PLL_SAMSUNG_DTOS403IH102A); + + break; + case ANYSEE_HW_507SI: /* 11 */ +@@ -877,22 +961,12 @@ + /* Try first attach TDA18212 silicon tuner on IOE[4], if that + * fails attach old simple PLL. */ + +- /* enable tuner on IOE[4] */ +- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10); +- if (ret) +- goto error; +- + /* attach tuner */ + fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, + &adap->dev->i2c_adap, &anysee_tda18212_config); + if (fe) + break; + +- /* disable tuner on IOE[4] */ +- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10); +- if (ret) +- goto error; +- + /* attach tuner */ + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe, + (0xc0 >> 1), &adap->dev->i2c_adap, +@@ -904,11 +978,6 @@ + /* E7 TC */ + /* E7 PTC */ + +- /* enable tuner on IOE[4] */ +- ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10); +- if (ret) +- goto error; +- + /* attach tuner */ + fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, + &adap->dev->i2c_adap, &anysee_tda18212_config); +@@ -930,6 +999,15 @@ + } + + break; ++ ++ case ANYSEE_HW_508T2C: /* 20 */ ++ /* E7 T2C */ ++ ++ /* attach tuner */ ++ fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, ++ &adap->dev->i2c_adap, &anysee_tda18212_config2); ++ ++ break; + default: + fe = NULL; + } +@@ -939,7 +1017,6 @@ + else + ret = -ENODEV; + +-error: + return ret; + } + +@@ -969,6 +1046,201 @@ + return 0; + } + ++static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot, ++ int addr) ++{ ++ struct dvb_usb_device *d = ci->data; ++ int ret; ++ u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1}; ++ u8 val; ++ ++ ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1); ++ if (ret) ++ return ret; ++ ++ return val; ++} ++ ++static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot, ++ int addr, u8 val) ++{ ++ struct dvb_usb_device *d = ci->data; ++ int ret; ++ u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val}; ++ ++ ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot, ++ u8 addr) ++{ ++ struct dvb_usb_device *d = ci->data; ++ int ret; ++ u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1}; ++ u8 val; ++ ++ ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1); ++ if (ret) ++ return ret; ++ ++ return val; ++} ++ ++static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot, ++ u8 addr, u8 val) ++{ ++ struct dvb_usb_device *d = ci->data; ++ int ret; ++ u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val}; ++ ++ ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot) ++{ ++ struct dvb_usb_device *d = ci->data; ++ int ret; ++ struct anysee_state *state = d->priv; ++ ++ state->ci_cam_ready = jiffies + msecs_to_jiffies(1000); ++ ++ ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80); ++ if (ret) ++ return ret; ++ ++ msleep(300); ++ ++ ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot) ++{ ++ struct dvb_usb_device *d = ci->data; ++ int ret; ++ ++ ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80); ++ if (ret) ++ return ret; ++ ++ msleep(30); ++ ++ ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot) ++{ ++ struct dvb_usb_device *d = ci->data; ++ int ret; ++ ++ ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot, ++ int open) ++{ ++ struct dvb_usb_device *d = ci->data; ++ struct anysee_state *state = d->priv; ++ int ret; ++ u8 tmp; ++ ++ ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40); ++ if (ret) ++ return ret; ++ ++ if (tmp == 0) { ++ ret = DVB_CA_EN50221_POLL_CAM_PRESENT; ++ if (time_after(jiffies, state->ci_cam_ready)) ++ ret |= DVB_CA_EN50221_POLL_CAM_READY; ++ } ++ ++ return ret; ++} ++ ++static int anysee_ci_init(struct dvb_usb_device *d) ++{ ++ struct anysee_state *state = d->priv; ++ int ret; ++ ++ state->ci.owner = THIS_MODULE; ++ state->ci.read_attribute_mem = anysee_ci_read_attribute_mem; ++ state->ci.write_attribute_mem = anysee_ci_write_attribute_mem; ++ state->ci.read_cam_control = anysee_ci_read_cam_control; ++ state->ci.write_cam_control = anysee_ci_write_cam_control; ++ state->ci.slot_reset = anysee_ci_slot_reset; ++ state->ci.slot_shutdown = anysee_ci_slot_shutdown; ++ state->ci.slot_ts_enable = anysee_ci_slot_ts_enable; ++ state->ci.poll_slot_status = anysee_ci_poll_slot_status; ++ state->ci.data = d; ++ ++ ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80); ++ if (ret) ++ return ret; ++ ++ ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void anysee_ci_release(struct dvb_usb_device *d) ++{ ++ struct anysee_state *state = d->priv; ++ ++ /* detach CI */ ++ if (state->has_ci) ++ dvb_ca_en50221_release(&state->ci); ++ ++ return; ++} ++ ++static int anysee_init(struct dvb_usb_device *d) ++{ ++ struct anysee_state *state = d->priv; ++ int ret; ++ ++ /* LED light */ ++ ret = anysee_led_ctrl(d, 0x01, 0x03); ++ if (ret) ++ return ret; ++ ++ /* enable IR */ ++ ret = anysee_ir_ctrl(d, 1); ++ if (ret) ++ return ret; ++ ++ /* attach CI */ ++ if (state->has_ci) { ++ ret = anysee_ci_init(d); ++ if (ret) { ++ state->has_ci = false; ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ + /* DVB USB Driver stuff */ + static struct dvb_usb_device_properties anysee_properties; + +@@ -1010,6 +1282,16 @@ + return anysee_init(d); + } + ++static void anysee_disconnect(struct usb_interface *intf) ++{ ++ struct dvb_usb_device *d = usb_get_intfdata(intf); ++ ++ anysee_ci_release(d); ++ dvb_usb_device_exit(intf); ++ ++ return; ++} ++ + static struct usb_device_id anysee_table[] = { + { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) }, + { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) }, +@@ -1029,7 +1311,7 @@ + { + .num_frontends = 2, + .frontend_ctrl = anysee_frontend_ctrl, +- .fe = {{ ++ .fe = { { + .streaming_ctrl = anysee_streaming_ctrl, + .frontend_attach = anysee_frontend_attach, + .tuner_attach = anysee_tuner_attach, +@@ -1057,7 +1339,7 @@ + } + } + }, +- }}, ++ } }, + } + }, + +@@ -1087,7 +1369,7 @@ + static struct usb_driver anysee_driver = { + .name = "dvb_usb_anysee", + .probe = anysee_probe, +- .disconnect = dvb_usb_device_exit, ++ .disconnect = anysee_disconnect, + .id_table = anysee_table, + }; + +diff -Naur linux-3.2.1/drivers/media/dvb/dvb-usb/anysee.h linux-3.2.1.patch/drivers/media/dvb/dvb-usb/anysee.h +--- linux-3.2.1/drivers/media/dvb/dvb-usb/anysee.h 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/dvb/dvb-usb/anysee.h 2012-01-22 16:07:33.178264400 +0100 +@@ -36,6 +36,7 @@ + + #define DVB_USB_LOG_PREFIX "anysee" + #include "dvb-usb.h" ++#include "dvb_ca_en50221.h" + + #define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args) + #define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args) +@@ -54,12 +55,16 @@ + CMD_GET_IR_CODE = 0x41, + CMD_GET_HW_INFO = 0x19, + CMD_SMARTCARD = 0x34, ++ CMD_CI = 0x37, + }; + + struct anysee_state { + u8 hw; /* PCB ID */ + u8 seq; + u8 fe_id:1; /* frondend ID */ ++ u8 has_ci:1; ++ struct dvb_ca_en50221 ci; ++ unsigned long ci_cam_ready; /* jiffies */ + }; + + #define ANYSEE_HW_507T 2 /* E30 */ +@@ -69,6 +74,7 @@ + #define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */ + #define ANYSEE_HW_508TC 18 /* E7 TC */ + #define ANYSEE_HW_508S2 19 /* E7 S2 */ ++#define ANYSEE_HW_508T2C 20 /* E7 T2C */ + #define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */ + #define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */ + +diff -Naur linux-3.2.1/drivers/media/dvb/dvb-usb/Kconfig linux-3.2.1.patch/drivers/media/dvb/dvb-usb/Kconfig +--- linux-3.2.1/drivers/media/dvb/dvb-usb/Kconfig 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/dvb/dvb-usb/Kconfig 2012-01-22 16:07:33.179264419 +0100 +@@ -311,6 +311,7 @@ + select DVB_STV0900 if !DVB_FE_CUSTOMISE + select DVB_STV6110 if !DVB_FE_CUSTOMISE + select DVB_ISL6423 if !DVB_FE_CUSTOMISE ++ select DVB_CXD2820R if !DVB_FE_CUSTOMISE + help + Say Y here to support the Anysee E30, Anysee E30 Plus or + Anysee E30 C Plus DVB USB2.0 receiver. diff --git a/packages/linux/patches/linux-3.2.30-202-add_HVR930C_support-0.1.patch b/packages/linux/patches/linux-3.2.30-202-add_HVR930C_support-0.1.patch new file mode 100644 index 0000000000..d6aaf40408 --- /dev/null +++ b/packages/linux/patches/linux-3.2.30-202-add_HVR930C_support-0.1.patch @@ -0,0 +1,649 @@ +diff -Naur linux-3.2.1/Documentation/DocBook/media/dvb/dvbproperty.xml linux-3.2.1.patch/Documentation/DocBook/media/dvb/dvbproperty.xml +--- linux-3.2.1/Documentation/DocBook/media/dvb/dvbproperty.xml 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/Documentation/DocBook/media/dvb/dvbproperty.xml 2012-01-22 15:52:29.773509131 +0100 +@@ -311,6 +311,8 @@ + ROLLOFF_20, + ROLLOFF_25, + ROLLOFF_AUTO, ++ ROLLOFF_15, /* DVB-C Annex A */ ++ ROLLOFF_13, /* DVB-C Annex C */ + } fe_rolloff_t; + + +@@ -778,8 +780,10 @@ + DTV_MODULATION + DTV_INVERSION + DTV_SYMBOL_RATE ++ DTV_ROLLOFF + DTV_INNER_FEC + ++ The Rolloff of 0.15 (ROLLOFF_15) is assumed, as ITU-T J.83 Annex A is more common. For Annex C, rolloff should be 0.13 (ROLLOFF_13). All other values are invalid. + +
+ DVB-C Annex B delivery system +diff -Naur linux-3.2.1/Documentation/dvb/get_dvb_firmware linux-3.2.1.patch/Documentation/dvb/get_dvb_firmware +--- linux-3.2.1/Documentation/dvb/get_dvb_firmware 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/Documentation/dvb/get_dvb_firmware 2012-01-22 15:38:50.939309809 +0100 +@@ -27,8 +27,8 @@ + "or51211", "or51132_qam", "or51132_vsb", "bluebird", + "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718", + "af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395", +- "lme2510c_s7395_old", "drxk", "drxk_terratec_h5", "tda10071", +- "it9135" ); ++ "lme2510c_s7395_old", "drxk", "drxk_terratec_h5", ++ "drxk_hauppauge_hvr930c", "tda10071", "it9135" ); + + # Check args + syntax() if (scalar(@ARGV) != 1); +@@ -643,6 +643,24 @@ + + "$fwfile" + } ++ ++sub drxk_hauppauge_hvr930c { ++ my $url = "http://www.wintvcd.co.uk/drivers/"; ++ my $zipfile = "HVR-9x0_5_10_325_28153_SIGNED.zip"; ++ my $hash = "83ab82e7e9480ec8bf1ae0155ca63c88"; ++ my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); ++ my $drvfile = "HVR-900/emOEM.sys"; ++ my $fwfile = "dvb-usb-hauppauge-hvr930c-drxk.fw"; ++ ++ checkstandard(); ++ ++ wgetfile($zipfile, $url . $zipfile); ++ verify($zipfile, $hash); ++ unzip($zipfile, $tmpdir); ++ extract("$tmpdir/$drvfile", 0x117b0, 42692, "$fwfile"); ++ ++ "$fwfile" ++} + + sub drxk_terratec_h5 { + my $url = "http://www.linuxtv.org/downloads/firmware/"; +diff -Naur linux-3.2.1/drivers/media/common/tuners/xc5000.c linux-3.2.1.patch/drivers/media/common/tuners/xc5000.c +--- linux-3.2.1/drivers/media/common/tuners/xc5000.c 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/common/tuners/xc5000.c 2012-01-22 15:38:54.115367896 +0100 +@@ -628,20 +628,12 @@ + dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality); + } + +-/* +- * As defined on EN 300 429, the DVB-C roll-off factor is 0.15. +- * So, the amount of the needed bandwith is given by: +- * Bw = Symbol_rate * (1 + 0.15) +- * As such, the maximum symbol rate supported by 6 MHz is given by: +- * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds +- */ +-#define MAX_SYMBOL_RATE_6MHz 5217391 +- + static int xc5000_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) + { + struct xc5000_priv *priv = fe->tuner_priv; + int ret; ++ u32 bw; + + if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { + if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) { +@@ -684,8 +676,10 @@ + priv->freq_hz = params->frequency - 1750000; + break; + case BANDWIDTH_7_MHZ: +- printk(KERN_ERR "xc5000 bandwidth 7MHz not supported\n"); +- return -EINVAL; ++ priv->bandwidth = BANDWIDTH_7_MHZ; ++ priv->video_standard = DTV7; ++ priv->freq_hz = params->frequency - 2250000; ++ break; + case BANDWIDTH_8_MHZ: + priv->bandwidth = BANDWIDTH_8_MHZ; + priv->video_standard = DTV8; +@@ -707,14 +701,26 @@ + dprintk(1, "%s() QAM modulation\n", __func__); + priv->rf_mode = XC_RF_MODE_CABLE; + /* +- * Using a 8MHz bandwidth sometimes fail +- * with 6MHz-spaced channels, due to inter-carrier +- * interference. So, use DTV6 firmware ++ * Using a higher bandwidth at the tuner filter may ++ * allow inter-carrier interference. ++ * So, determine the minimal channel spacing, in order ++ * to better adjust the tuner filter. ++ * According with ITU-T J.83, the bandwidth is given by: ++ * bw = Simbol Rate * (1 + roll_off), where the roll_off ++ * is equal to 0.15 for Annex A, and 0.13 for annex C + */ +- if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz) { ++ if (fe->dtv_property_cache.rolloff == ROLLOFF_13) ++ bw = (params->u.qam.symbol_rate * 13) / 10; ++ else ++ bw = (params->u.qam.symbol_rate * 15) / 10; ++ if (bw <= 6000000) { + priv->bandwidth = BANDWIDTH_6_MHZ; + priv->video_standard = DTV6; + priv->freq_hz = params->frequency - 1750000; ++ } else if (bw <= 7000000) { ++ priv->bandwidth = BANDWIDTH_7_MHZ; ++ priv->video_standard = DTV7; ++ priv->freq_hz = params->frequency - 2250000; + } else { + priv->bandwidth = BANDWIDTH_8_MHZ; + priv->video_standard = DTV7_8; +@@ -996,6 +1002,8 @@ + struct xc5000_priv *priv = fe->tuner_priv; + int ret = 0; + ++ mutex_lock(&xc5000_list_mutex); ++ + if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { + ret = xc5000_fwupload(fe); + if (ret != XC_RESULT_SUCCESS) +@@ -1015,6 +1023,8 @@ + /* Default to "CABLE" mode */ + ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); + ++ mutex_unlock(&xc5000_list_mutex); ++ + return ret; + } + +diff -Naur linux-3.2.1/drivers/media/dvb/dvb-core/dvb_frontend.c linux-3.2.1.patch/drivers/media/dvb/dvb-core/dvb_frontend.c +--- linux-3.2.1/drivers/media/dvb/dvb-core/dvb_frontend.c 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/dvb/dvb-core/dvb_frontend.c 2012-01-22 15:52:29.774509149 +0100 +@@ -876,6 +876,7 @@ + c->symbol_rate = QAM_AUTO; + c->code_rate_HP = FEC_AUTO; + c->code_rate_LP = FEC_AUTO; ++ c->rolloff = ROLLOFF_AUTO; + + c->isdbt_partial_reception = -1; + c->isdbt_sb_mode = -1; +@@ -1030,6 +1031,7 @@ + break; + case FE_QAM: + c->delivery_system = SYS_DVBC_ANNEX_AC; ++ c->rolloff = ROLLOFF_15; /* implied for Annex A */ + break; + case FE_OFDM: + c->delivery_system = SYS_DVBT; +diff -Naur linux-3.2.1/drivers/media/dvb/frontends/drxk.h linux-3.2.1.patch/drivers/media/dvb/frontends/drxk.h +--- linux-3.2.1/drivers/media/dvb/frontends/drxk.h 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/dvb/frontends/drxk.h 2012-01-22 15:38:45.923218078 +0100 +@@ -26,6 +26,8 @@ + bool antenna_dvbt; + u16 antenna_gpio; + ++ int chunk_size; ++ + const char *microcode_name; + }; + +diff -Naur linux-3.2.1/drivers/media/dvb/frontends/drxk_hard.c linux-3.2.1.patch/drivers/media/dvb/frontends/drxk_hard.c +--- linux-3.2.1/drivers/media/dvb/frontends/drxk_hard.c 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/dvb/frontends/drxk_hard.c 2012-01-22 15:39:13.797727862 +0100 +@@ -681,7 +681,8 @@ + state->m_hasOOB = false; + state->m_hasAudio = false; + +- state->m_ChunkSize = 124; ++ if (!state->m_ChunkSize) ++ state->m_ChunkSize = 124; + + state->m_oscClockFreq = 0; + state->m_smartAntInverted = false; +@@ -1846,6 +1847,7 @@ + */ + switch (oMode) { + case OM_DVBT: ++ dprintk(1, ": DVB-T\n"); + state->m_OperationMode = oMode; + status = SetDVBTStandard(state, oMode); + if (status < 0) +@@ -1853,6 +1855,8 @@ + break; + case OM_QAM_ITU_A: /* fallthrough */ + case OM_QAM_ITU_C: ++ dprintk(1, ": DVB-C Annex %c\n", ++ (state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C'); + state->m_OperationMode = oMode; + status = SetQAMStandard(state, oMode); + if (status < 0) +@@ -6182,7 +6186,10 @@ + dprintk(1, "\n"); + if (mutex_trylock(&state->ctlock) == 0) + return -EBUSY; +- SetOperationMode(state, OM_QAM_ITU_A); ++ if (state->m_itut_annex_c) ++ SetOperationMode(state, OM_QAM_ITU_C); ++ else ++ SetOperationMode(state, OM_QAM_ITU_A); + return 0; + } + +@@ -6218,6 +6225,12 @@ + return -EINVAL; + } + ++ if (fe->ops.info.type == FE_QAM) { ++ if (fe->dtv_property_cache.rolloff == ROLLOFF_13) ++ state->m_itut_annex_c = true; ++ else ++ state->m_itut_annex_c = false; ++ } + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); +@@ -6423,6 +6436,7 @@ + state->no_i2c_bridge = config->no_i2c_bridge; + state->antenna_gpio = config->antenna_gpio; + state->antenna_dvbt = config->antenna_dvbt; ++ state->m_ChunkSize = config->chunk_size; + + /* NOTE: as more UIO bits will be used, add them to the mask */ + state->UIO_mask = config->antenna_gpio; +diff -Naur linux-3.2.1/drivers/media/dvb/frontends/drxk_hard.h linux-3.2.1.patch/drivers/media/dvb/frontends/drxk_hard.h +--- linux-3.2.1/drivers/media/dvb/frontends/drxk_hard.h 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/dvb/frontends/drxk_hard.h 2012-01-22 15:39:13.798727880 +0100 +@@ -263,6 +263,8 @@ + u8 m_TSDataStrength; + u8 m_TSClockkStrength; + ++ bool m_itut_annex_c; /* If true, uses ITU-T DVB-C Annex C, instead of Annex A */ ++ + enum DRXMPEGStrWidth_t m_widthSTR; /**< MPEG start width */ + u32 m_mpegTsStaticBitrate; /**< Maximum bitrate in b/s in case + static clockrate is selected */ +diff -Naur linux-3.2.1/drivers/media/dvb/frontends/tda18271c2dd.c linux-3.2.1.patch/drivers/media/dvb/frontends/tda18271c2dd.c +--- linux-3.2.1/drivers/media/dvb/frontends/tda18271c2dd.c 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/dvb/frontends/tda18271c2dd.c 2012-01-22 15:38:39.024091895 +0100 +@@ -1123,20 +1123,6 @@ + return 0; + } + +-/* +- * As defined on EN 300 429 Annex A and on ITU-T J.83 annex A, the DVB-C +- * roll-off factor is 0.15. +- * According with the specs, the amount of the needed bandwith is given by: +- * Bw = Symbol_rate * (1 + 0.15) +- * As such, the maximum symbol rate supported by 6 MHz is +- * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds +- *NOTE: For ITU-T J.83 Annex C, the roll-off factor is 0.13. So: +- * max_symbol_rate = 6 MHz / 1.13 = 5309735 Baud +- * That means that an adjustment is needed for Japan, +- * but, as currently DRX-K is hardcoded to Annex A, let's stick +- * with 0.15 roll-off factor. +- */ +-#define MAX_SYMBOL_RATE_6MHz 5217391 + + static int set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +@@ -1144,6 +1130,7 @@ + struct tda_state *state = fe->tuner_priv; + int status = 0; + int Standard; ++ u32 bw; + + state->m_Frequency = params->frequency; + +@@ -1161,8 +1148,23 @@ + break; + } + else if (fe->ops.info.type == FE_QAM) { +- if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz) ++ /* ++ * Using a higher bandwidth at the tuner filter may ++ * allow inter-carrier interference. ++ * So, determine the minimal channel spacing, in order ++ * to better adjust the tuner filter. ++ * According with ITU-T J.83, the bandwidth is given by: ++ * bw = Simbol Rate * (1 + roll_off), where the roll_off ++ * is equal to 0.15 for Annex A, and 0.13 for annex C ++ */ ++ if (fe->dtv_property_cache.rolloff == ROLLOFF_13) ++ bw = (params->u.qam.symbol_rate * 13) / 10; ++ else ++ bw = (params->u.qam.symbol_rate * 15) / 10; ++ if (bw <= 6000000) + Standard = HF_DVBC_6MHZ; ++ else if (bw <= 7000000) ++ Standard = HF_DVBC_7MHZ; + else + Standard = HF_DVBC_8MHZ; + } else +diff -Naur linux-3.2.1/drivers/media/rc/keymaps/rc-hauppauge.c linux-3.2.1.patch/drivers/media/rc/keymaps/rc-hauppauge.c +--- linux-3.2.1/drivers/media/rc/keymaps/rc-hauppauge.c 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/rc/keymaps/rc-hauppauge.c 2012-01-22 15:39:04.767562712 +0100 +@@ -183,6 +183,57 @@ + { 0x1d3f, KEY_HOME }, + + /* ++ * Keycodes for PT# R-005 remote bundled with Haupauge HVR-930C ++ * Keycodes start with address = 0x1c ++ */ ++ { 0x1c3b, KEY_GOTO }, ++ { 0x1c3d, KEY_POWER }, ++ ++ { 0x1c14, KEY_UP }, ++ { 0x1c15, KEY_DOWN }, ++ { 0x1c16, KEY_LEFT }, ++ { 0x1c17, KEY_RIGHT }, ++ { 0x1c25, KEY_OK }, ++ ++ { 0x1c00, KEY_0 }, ++ { 0x1c01, KEY_1 }, ++ { 0x1c02, KEY_2 }, ++ { 0x1c03, KEY_3 }, ++ { 0x1c04, KEY_4 }, ++ { 0x1c05, KEY_5 }, ++ { 0x1c06, KEY_6 }, ++ { 0x1c07, KEY_7 }, ++ { 0x1c08, KEY_8 }, ++ { 0x1c09, KEY_9 }, ++ ++ { 0x1c1f, KEY_EXIT }, /* BACK */ ++ { 0x1c0d, KEY_MENU }, ++ { 0x1c1c, KEY_TV }, ++ ++ { 0x1c10, KEY_VOLUMEUP }, ++ { 0x1c11, KEY_VOLUMEDOWN }, ++ ++ { 0x1c20, KEY_CHANNELUP }, ++ { 0x1c21, KEY_CHANNELDOWN }, ++ ++ { 0x1c0f, KEY_MUTE }, ++ { 0x1c12, KEY_PREVIOUS }, /* Prev */ ++ ++ { 0x1c36, KEY_STOP }, ++ { 0x1c37, KEY_RECORD }, ++ ++ { 0x1c24, KEY_LAST }, /* <| */ ++ { 0x1c1e, KEY_NEXT }, /* >| */ ++ ++ { 0x1c0a, KEY_TEXT }, ++ { 0x1c0e, KEY_SUBTITLE }, /* CC */ ++ ++ { 0x1c32, KEY_REWIND }, ++ { 0x1c30, KEY_PAUSE }, ++ { 0x1c35, KEY_PLAY }, ++ { 0x1c34, KEY_FASTFORWARD }, ++ ++ /* + * Keycodes for the old Black Remote Controller + * This one also uses RC-5 protocol + * Keycodes start with address = 0x00 +diff -Naur linux-3.2.1/drivers/media/video/em28xx/em28xx-cards.c linux-3.2.1.patch/drivers/media/video/em28xx/em28xx-cards.c +--- linux-3.2.1/drivers/media/video/em28xx/em28xx-cards.c 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/video/em28xx/em28xx-cards.c 2012-01-22 15:39:04.921565528 +0100 +@@ -336,6 +336,23 @@ + { -1, -1, -1, -1}, + }; + ++static struct em28xx_reg_seq hauppauge_930c_gpio[] = { ++ {EM2874_R80_GPIO, 0x6f, 0xff, 10}, ++ {EM2874_R80_GPIO, 0x4f, 0xff, 10}, /* xc5000 reset */ ++ {EM2874_R80_GPIO, 0x6f, 0xff, 10}, ++ {EM2874_R80_GPIO, 0x4f, 0xff, 10}, ++ { -1, -1, -1, -1}, ++}; ++ ++#if 0 ++static struct em28xx_reg_seq hauppauge_930c_digital[] = { ++ {EM2874_R80_GPIO, 0xf6, 0xff, 10}, ++ {EM2874_R80_GPIO, 0xe6, 0xff, 100}, ++ {EM2874_R80_GPIO, 0xa6, 0xff, 10}, ++ { -1, -1, -1, -1}, ++}; ++#endif ++ + /* + * Board definitions + */ +@@ -887,7 +904,25 @@ + .tuner_addr = 0x41, + .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */ + .tuner_gpio = terratec_h5_gpio, ++#else ++ .tuner_type = TUNER_ABSENT, ++#endif ++ .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | ++ EM28XX_I2C_CLK_WAIT_ENABLE | ++ EM28XX_I2C_FREQ_400_KHZ, ++ }, ++ [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = { ++ .name = "Hauppauge WinTV HVR 930C", ++ .has_dvb = 1, ++#if 0 /* FIXME: Add analog support */ ++ .tuner_type = TUNER_XC5000, ++ .tuner_addr = 0x41, ++ .dvb_gpio = hauppauge_930c_digital, ++ .tuner_gpio = hauppauge_930c_gpio, ++#else ++ .tuner_type = TUNER_ABSENT, + #endif ++ .ir_codes = RC_MAP_HAUPPAUGE, + .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | + EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_400_KHZ, +@@ -1975,6 +2010,8 @@ + .driver_info = EM28174_BOARD_PCTV_290E }, + { USB_DEVICE(0x2013, 0x024c), + .driver_info = EM28174_BOARD_PCTV_460E }, ++ { USB_DEVICE(0x2040, 0x1605), ++ .driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C }, + { }, + }; + MODULE_DEVICE_TABLE(usb, em28xx_id_table); +@@ -2028,10 +2065,10 @@ + int rc = 0; + struct em28xx *dev = ptr; + +- if (dev->tuner_type != TUNER_XC2028) ++ if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000) + return 0; + +- if (command != XC2028_TUNER_RESET) ++ if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET) + return 0; + + rc = em28xx_gpio_set(dev, dev->board.tuner_gpio); +diff -Naur linux-3.2.1/drivers/media/video/em28xx/em28xx-dvb.c linux-3.2.1.patch/drivers/media/video/em28xx/em28xx-dvb.c +--- linux-3.2.1/drivers/media/video/em28xx/em28xx-dvb.c 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/video/em28xx/em28xx-dvb.c 2012-01-22 15:39:13.799727898 +0100 +@@ -316,6 +316,14 @@ + .microcode_name = "dvb-usb-terratec-h5-drxk.fw", + }; + ++struct drxk_config hauppauge_930c_drxk = { ++ .adr = 0x29, ++ .single_master = 1, ++ .no_i2c_bridge = 1, ++ .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw", ++ .chunk_size = 56, ++}; ++ + static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) + { + struct em28xx_dvb *dvb = fe->sec_priv; +@@ -334,6 +342,73 @@ + return status; + } + ++static void hauppauge_hvr930c_init(struct em28xx *dev) ++{ ++ int i; ++ ++ struct em28xx_reg_seq hauppauge_hvr930c_init[] = { ++ {EM2874_R80_GPIO, 0xff, 0xff, 0x65}, ++ {EM2874_R80_GPIO, 0xfb, 0xff, 0x32}, ++ {EM2874_R80_GPIO, 0xff, 0xff, 0xb8}, ++ { -1, -1, -1, -1}, ++ }; ++ struct em28xx_reg_seq hauppauge_hvr930c_end[] = { ++ {EM2874_R80_GPIO, 0xef, 0xff, 0x01}, ++ {EM2874_R80_GPIO, 0xaf, 0xff, 0x65}, ++ {EM2874_R80_GPIO, 0xef, 0xff, 0x76}, ++ {EM2874_R80_GPIO, 0xef, 0xff, 0x01}, ++ {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b}, ++ {EM2874_R80_GPIO, 0xef, 0xff, 0x40}, ++ ++ {EM2874_R80_GPIO, 0xcf, 0xff, 0x65}, ++ {EM2874_R80_GPIO, 0xef, 0xff, 0x65}, ++ {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b}, ++ {EM2874_R80_GPIO, 0xef, 0xff, 0x65}, ++ ++ { -1, -1, -1, -1}, ++ }; ++ ++ struct { ++ unsigned char r[4]; ++ int len; ++ } regs[] = { ++ {{ 0x06, 0x02, 0x00, 0x31 }, 4}, ++ {{ 0x01, 0x02 }, 2}, ++ {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, ++ {{ 0x01, 0x00 }, 2}, ++ {{ 0x01, 0x00, 0xff, 0xaf }, 4}, ++ {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, ++ {{ 0x01, 0x00 }, 2}, ++ {{ 0x01, 0x00, 0x73, 0xaf }, 4}, ++ {{ 0x04, 0x00 }, 2}, ++ {{ 0x00, 0x04 }, 2}, ++ {{ 0x00, 0x04, 0x00, 0x0a }, 4}, ++ {{ 0x04, 0x14 }, 2}, ++ {{ 0x04, 0x14, 0x00, 0x00 }, 4}, ++ }; ++ ++ em28xx_gpio_set(dev, hauppauge_hvr930c_init); ++ em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); ++ msleep(10); ++ em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); ++ msleep(10); ++ ++ dev->i2c_client.addr = 0x82 >> 1; ++ ++ for (i = 0; i < ARRAY_SIZE(regs); i++) ++ i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); ++ em28xx_gpio_set(dev, hauppauge_hvr930c_end); ++ ++ msleep(100); ++ ++ em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); ++ msleep(30); ++ ++ em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); ++ msleep(10); ++ ++} ++ + static void terratec_h5_init(struct em28xx *dev) + { + int i; +@@ -788,6 +863,51 @@ + mfe_shared = 1; + } + break; ++ case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: ++ hauppauge_hvr930c_init(dev); ++ ++ dvb->dont_attach_fe1 = 1; ++ ++ dvb->fe[0] = dvb_attach(drxk_attach, ++ &hauppauge_930c_drxk, &dev->i2c_adap, ++ &dvb->fe[1]); ++ if (!dvb->fe[0]) { ++ result = -EINVAL; ++ goto out_free; ++ } ++ /* FIXME: do we need a pll semaphore? */ ++ dvb->fe[0]->sec_priv = dvb; ++ sema_init(&dvb->pll_mutex, 1); ++ dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; ++ dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; ++ dvb->fe[1]->id = 1; ++ ++ /* Attach xc5000 */ ++ struct xc5000_config cfg; ++ memset(&cfg, 0, sizeof(cfg)); ++ cfg.i2c_address = 0x61; ++ cfg.if_khz = 4000; ++ ++ if (dvb->fe[0]->ops.i2c_gate_ctrl) ++ dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); ++ if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap, ++ &cfg)) { ++ result = -EINVAL; ++ goto out_free; ++ } ++ ++ if (dvb->fe[0]->ops.i2c_gate_ctrl) ++ dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); ++ ++ /* Hack - needed by drxk/tda18271c2dd */ ++ dvb->fe[1]->tuner_priv = dvb->fe[0]->tuner_priv; ++ memcpy(&dvb->fe[1]->ops.tuner_ops, ++ &dvb->fe[0]->ops.tuner_ops, ++ sizeof(dvb->fe[0]->ops.tuner_ops)); ++ ++ mfe_shared = 1; ++ ++ break; + case EM2884_BOARD_TERRATEC_H5: + terratec_h5_init(dev); + +@@ -798,7 +918,6 @@ + result = -EINVAL; + goto out_free; + } +- + /* FIXME: do we need a pll semaphore? */ + dvb->fe[0]->sec_priv = dvb; + sema_init(&dvb->pll_mutex, 1); +@@ -822,6 +941,8 @@ + &dvb->fe[0]->ops.tuner_ops, + sizeof(dvb->fe[0]->ops.tuner_ops)); + ++ mfe_shared = 1; ++ + break; + case EM28174_BOARD_PCTV_460E: + /* attach demod */ +@@ -845,6 +966,8 @@ + } + /* define general-purpose callback pointer */ + dvb->fe[0]->callback = em28xx_tuner_callback; ++ if (dvb->fe[1]) ++ dvb->fe[1]->callback = em28xx_tuner_callback; + + /* register everything */ + result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); +diff -Naur linux-3.2.1/drivers/media/video/em28xx/em28xx.h linux-3.2.1.patch/drivers/media/video/em28xx/em28xx.h +--- linux-3.2.1/drivers/media/video/em28xx/em28xx.h 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/drivers/media/video/em28xx/em28xx.h 2012-01-22 15:38:45.930218200 +0100 +@@ -38,6 +38,7 @@ + #include + #endif + #include "tuner-xc2028.h" ++#include "xc5000.h" + #include "em28xx-reg.h" + + /* Boards supported by driver */ +@@ -121,6 +122,7 @@ + #define EM28174_BOARD_PCTV_290E 78 + #define EM2884_BOARD_TERRATEC_H5 79 + #define EM28174_BOARD_PCTV_460E 80 ++#define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81 + + /* Limits minimum and default number of buffers */ + #define EM28XX_MIN_BUF 4 +diff -Naur linux-3.2.1/include/linux/dvb/frontend.h linux-3.2.1.patch/include/linux/dvb/frontend.h +--- linux-3.2.1/include/linux/dvb/frontend.h 2012-01-12 20:42:45.000000000 +0100 ++++ linux-3.2.1.patch/include/linux/dvb/frontend.h 2012-01-22 15:52:29.793509493 +0100 +@@ -329,6 +329,8 @@ + ROLLOFF_20, + ROLLOFF_25, + ROLLOFF_AUTO, ++ ROLLOFF_15, /* DVB-C Annex A */ ++ ROLLOFF_13, /* DVB-C Annex C */ + } fe_rolloff_t; + + typedef enum fe_delivery_system { diff --git a/packages/linux/patches/linux-3.2.28-203-stb0899_enable_low_symbol_rate.patch b/packages/linux/patches/linux-3.2.30-203-stb0899_enable_low_symbol_rate.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-203-stb0899_enable_low_symbol_rate.patch rename to packages/linux/patches/linux-3.2.30-203-stb0899_enable_low_symbol_rate.patch diff --git a/packages/linux/patches/linux-3.2.28-204-add_Formosa_eHome_Infrared_Receiver.patch b/packages/linux/patches/linux-3.2.30-204-add_Formosa_eHome_Infrared_Receiver.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-204-add_Formosa_eHome_Infrared_Receiver.patch rename to packages/linux/patches/linux-3.2.30-204-add_Formosa_eHome_Infrared_Receiver.patch diff --git a/packages/linux/patches/linux-3.2.30-210-add_DVBSky_support.patch b/packages/linux/patches/linux-3.2.30-210-add_DVBSky_support.patch new file mode 100644 index 0000000000..90521d185b --- /dev/null +++ b/packages/linux/patches/linux-3.2.30-210-add_DVBSky_support.patch @@ -0,0 +1,4215 @@ +diff -uprN linux-3.2.10.orig/drivers/media/dvb/dvb-usb/dw2102.c linux-3.2.10/drivers/media/dvb/dvb-usb/dw2102.c +--- linux-3.2.10.orig/drivers/media/dvb/dvb-usb/dw2102.c 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/dvb/dvb-usb/dw2102.c 2012-03-16 10:55:52.000000000 +0100 +@@ -3,6 +3,7 @@ + * TeVii S600, S630, S650, S660, S480, + * Prof 1100, 7500, + * Geniatech SU3000 Cards ++ * DVBSKY S860 + * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by) + * + * This program is free software; you can redistribute it and/or modify it +@@ -19,6 +20,7 @@ + #include "stb6000.h" + #include "eds1547.h" + #include "cx24116.h" ++#include "m88ds3103.h" + #include "tda1002x.h" + #include "mt312.h" + #include "zl10039.h" +@@ -80,6 +82,9 @@ + #define DW2102_RC_QUERY (0x1a00) + #define DW2102_LED_CTRL (0x1b00) + ++/*Bst device index in table*/ ++#define BST_6830_Index 15 ++ + #define err_str "did not find the firmware file. (%s) " \ + "Please see linux/Documentation/dvb/ for more details " \ + "on firmware-problems." +@@ -881,6 +886,44 @@ static int s660_set_voltage(struct dvb_f + + return 0; + } ++ ++static int bstusb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ ++ struct dvb_usb_adapter *udev_adap = ++ (struct dvb_usb_adapter *)(fe->dvb->priv); ++ ++ u8 obuf[3] = { 0xe, 0x80, 0 }; ++ u8 ibuf[] = { 0 }; ++ ++ info("US6830: %s!\n", __func__); ++ ++ if (voltage == SEC_VOLTAGE_OFF) ++ obuf[2] = 0; ++ else ++ obuf[2] = 1; ++ ++ if (dvb_usb_generic_rw(udev_adap->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ return 0; ++} ++ ++static int bstusb_restart(struct dvb_frontend *fe) ++{ ++ ++ struct dvb_usb_adapter *udev_adap = ++ (struct dvb_usb_adapter *)(fe->dvb->priv); ++ ++ u8 obuf[3] = { 0x36, 3, 0 }; ++ u8 ibuf[] = { 0 }; ++ ++ ++ if (dvb_usb_generic_rw(udev_adap->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x36 transfer failed."); ++ ++ return 0; ++} + + static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) + { +@@ -987,6 +1030,24 @@ static struct ds3000_config su3000_ds300 + .ci_mode = 1, + }; + ++static struct m88ds3103_config US6830_ds3103_config = { ++ .demod_address = 0x68, ++ .ci_mode = 1, ++ .pin_ctrl = 0x83, ++ .ts_mode = 0, ++ .start_ctrl = bstusb_restart, ++ .set_voltage = bstusb_set_voltage, ++}; ++ ++static struct m88ds3103_config US6832_ds3103_config = { ++ .demod_address = 0x68, ++ .ci_mode = 1, ++ .pin_ctrl = 0x80, ++ .ts_mode = 0, ++ .start_ctrl = bstusb_restart, ++ .set_voltage = bstusb_set_voltage, ++}; ++ + static int dw2104_frontend_attach(struct dvb_usb_adapter *d) + { + struct dvb_tuner_ops *tuner_ops = NULL; +@@ -1214,6 +1275,72 @@ static int su3000_frontend_attach(struct + return 0; + } + ++static int US6830_frontend_attach(struct dvb_usb_adapter *d) ++{ ++ u8 obuf[3] = { 0xe, 0x83, 0 }; ++ u8 ibuf[] = { 0 }; ++ ++ ++ info("US6830: %s!\n", __func__); ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ obuf[0] = 0xe; ++ obuf[1] = 0x83; ++ obuf[2] = 1; ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ obuf[0] = 0x51; ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) ++ err("command 0x51 transfer failed."); ++ ++ d->fe_adap[0].fe = dvb_attach(m88ds3103_attach, &US6830_ds3103_config, ++ &d->dev->i2c_adap); ++ if (d->fe_adap[0].fe == NULL) ++ return -EIO; ++ ++ info("Attached DS3000!\n"); ++ ++ return 0; ++} ++ ++static int US6832_frontend_attach(struct dvb_usb_adapter *d) ++{ ++ u8 obuf[3] = { 0xe, 0x83, 0 }; ++ u8 ibuf[] = { 0 }; ++ ++ ++ info("US6832: %s!\n", __func__); ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ obuf[0] = 0xe; ++ obuf[1] = 0x83; ++ obuf[2] = 1; ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ obuf[0] = 0x51; ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) ++ err("command 0x51 transfer failed."); ++ ++ d->fe_adap[0].fe = dvb_attach(m88ds3103_attach, &US6832_ds3103_config, ++ &d->dev->i2c_adap); ++ if (d->fe_adap[0].fe == NULL) ++ return -EIO; ++ ++ info("Attached DS3000!\n"); ++ ++ return 0; ++} ++ + static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) + { + dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, +@@ -1451,6 +1578,9 @@ static struct usb_device_id dw2102_table + {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, + {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, + {USB_DEVICE(0x1f4d, 0x3100)}, ++ {USB_DEVICE(0x0572, 0x6830)}, ++ {USB_DEVICE(0x0572, 0x6831)}, ++ {USB_DEVICE(0x0572, 0x6832)}, + { } + }; + +@@ -1856,6 +1986,107 @@ static struct dvb_usb_device_properties + } + }; + ++static struct dvb_usb_device_properties US6830_properties = { ++ .caps = DVB_USB_IS_AN_I2C_ADAPTER, ++ .usb_ctrl = DEVICE_SPECIFIC, ++ .size_of_priv = sizeof(struct su3000_state), ++ .power_ctrl = su3000_power_ctrl, ++ .num_adapters = 1, ++ .identify_state = su3000_identify_state, ++ .i2c_algo = &su3000_i2c_algo, ++ ++ .rc.legacy = { ++ .rc_map_table = rc_map_su3000_table, ++ .rc_map_size = ARRAY_SIZE(rc_map_su3000_table), ++ .rc_interval = 150, ++ .rc_query = dw2102_rc_query, ++ }, ++ ++ .read_mac_address = su3000_read_mac_address, ++ ++ .generic_bulk_ctrl_endpoint = 0x01, ++ ++ .adapter = { ++ { ++ .num_frontends = 1, ++ .fe = {{ ++ .streaming_ctrl = su3000_streaming_ctrl, ++ .frontend_attach = US6830_frontend_attach, ++ .stream = { ++ .type = USB_BULK, ++ .count = 8, ++ .endpoint = 0x82, ++ .u = { ++ .bulk = { ++ .buffersize = 4096, ++ } ++ } ++ } ++ }}, ++ } ++ }, ++ .num_device_descs = 2, ++ .devices = { ++ { "Bestunar US6830 HD", ++ { &dw2102_table[BST_6830_Index], NULL }, ++ { NULL }, ++ }, ++ { "Bestunar US6831 HD", ++ { &dw2102_table[BST_6830_Index+1], NULL }, ++ { NULL }, ++ }, ++ } ++}; ++ ++static struct dvb_usb_device_properties US6832_properties = { ++ .caps = DVB_USB_IS_AN_I2C_ADAPTER, ++ .usb_ctrl = DEVICE_SPECIFIC, ++ .size_of_priv = sizeof(struct su3000_state), ++ .power_ctrl = su3000_power_ctrl, ++ .num_adapters = 1, ++ .identify_state = su3000_identify_state, ++ .i2c_algo = &su3000_i2c_algo, ++ ++ .rc.legacy = { ++ .rc_map_table = rc_map_su3000_table, ++ .rc_map_size = ARRAY_SIZE(rc_map_su3000_table), ++ .rc_interval = 150, ++ .rc_query = dw2102_rc_query, ++ }, ++ ++ .read_mac_address = su3000_read_mac_address, ++ ++ .generic_bulk_ctrl_endpoint = 0x01, ++ ++ .adapter = { ++ { ++ .num_frontends = 1, ++ .fe = {{ ++ .streaming_ctrl = su3000_streaming_ctrl, ++ .frontend_attach = US6832_frontend_attach, ++ .stream = { ++ .type = USB_BULK, ++ .count = 8, ++ .endpoint = 0x82, ++ .u = { ++ .bulk = { ++ .buffersize = 4096, ++ } ++ } ++ } ++ }}, ++ } ++ }, ++ .num_device_descs = 1, ++ .devices = { ++ { "Bestunar US6832 HD", ++ { &dw2102_table[BST_6830_Index+2], NULL }, ++ { NULL }, ++ }, ++ ++ } ++}; ++ + static int dw2102_probe(struct usb_interface *intf, + const struct usb_device_id *id) + { +@@ -1915,6 +2146,10 @@ static int dw2102_probe(struct usb_inter + 0 == dvb_usb_device_init(intf, p7500, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &su3000_properties, ++ THIS_MODULE, NULL, adapter_nr) || ++ 0 == dvb_usb_device_init(intf, &US6830_properties, ++ THIS_MODULE, NULL, adapter_nr) || ++ 0 == dvb_usb_device_init(intf, &US6832_properties, + THIS_MODULE, NULL, adapter_nr)) + return 0; + +diff -uprN linux-3.2.10.orig/drivers/media/dvb/dvb-usb/Kconfig linux-3.2.10/drivers/media/dvb/dvb-usb/Kconfig +--- linux-3.2.10.orig/drivers/media/dvb/dvb-usb/Kconfig 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/dvb/dvb-usb/Kconfig 2012-03-16 10:55:52.000000000 +0100 +@@ -279,6 +279,7 @@ config DVB_USB_DW2102 + select DVB_STV0288 if !DVB_FE_CUSTOMISE + select DVB_STB6000 if !DVB_FE_CUSTOMISE + select DVB_CX24116 if !DVB_FE_CUSTOMISE ++ select DVB_M88DS3103 if !DVB_FE_CUSTOMISE + select DVB_SI21XX if !DVB_FE_CUSTOMISE + select DVB_TDA10023 if !DVB_FE_CUSTOMISE + select DVB_MT312 if !DVB_FE_CUSTOMISE +diff -uprN linux-3.2.10.orig/drivers/media/dvb/frontends/Kconfig linux-3.2.10/drivers/media/dvb/frontends/Kconfig +--- linux-3.2.10.orig/drivers/media/dvb/frontends/Kconfig 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/dvb/frontends/Kconfig 2012-03-16 10:55:57.000000000 +0100 +@@ -214,6 +214,13 @@ config DVB_CX24116 + help + A DVB-S/S2 tuner module. Say Y when you want to support this frontend. + ++config DVB_M88DS3103 ++ tristate "Montage DS3103 based" ++ depends on DVB_CORE && I2C ++ default m if DVB_FE_CUSTOMISE ++ help ++ A DVB-S/S2 tuner module. Say Y when you want to support this frontend. ++ + config DVB_SI21XX + tristate "Silicon Labs SI21XX based" + depends on DVB_CORE && I2C +diff -uprN linux-3.2.10.orig/drivers/media/dvb/frontends/m88ds3103.c linux-3.2.10/drivers/media/dvb/frontends/m88ds3103.c +--- linux-3.2.10.orig/drivers/media/dvb/frontends/m88ds3103.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.2.10/drivers/media/dvb/frontends/m88ds3103.c 2012-03-16 10:55:57.000000000 +0100 +@@ -0,0 +1,1811 @@ ++/* ++ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver ++ Copyright (C) 2011 Max nibble ++ Copyright (C) 2010 Montage Technology ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program 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 this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++#include "m88ds3103.h" ++ ++static int debug; ++module_param(debug, int, 0644); ++MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); ++ ++#define dprintk(args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_INFO "m88ds3103: " args); \ ++ } while (0) ++ ++#define FW_DOWN_SIZE 32 ++#define FW_DOWN_LOOP (8192/FW_DOWN_SIZE) ++#define DS3103_DEFAULT_FIRMWARE "dvb-fe-ds3103.fw" ++#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds300x.fw" ++#define MT_FE_MCLK_KHZ 96000 /* in kHz */ ++#define MT_FE_CRYSTAL_KHZ 27000 /* in kHz */ ++#define FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz 3000 ++#define DS3000_ID 0x3000 ++#define DS3103_ID 0x3103 ++#define TS2020_ID 0x2020 ++#define TS2022_ID 0x2022 ++#define UNKNOW_ID 0x0000 ++ ++/* For M88DS3103 demod dvbs mode.*/ ++static u8 ds3103_dvbs_init_tab[] = { ++ 0x23, 0x07, ++ 0x08, 0x03, ++ 0x0c, 0x02, ++ 0x21, 0x54, ++ 0x25, 0x82, ++ 0x27, 0x31, ++ 0x30, 0x08, ++ 0x31, 0x40, ++ 0x32, 0x32, ++ 0x33, 0x35, ++ 0x35, 0xff, ++ 0x3a, 0x00, ++ 0x37, 0x10, ++ 0x38, 0x10, ++ 0x39, 0x02, ++ 0x42, 0x60, ++ 0x4a, 0x80, ++ 0x4b, 0x04, ++ 0x4d, 0x91, ++ 0x5d, 0xc8, ++ 0x50, 0x36, ++ 0x51, 0x36, ++ 0x52, 0x36, ++ 0x53, 0x36, ++ 0x63, 0x0f, ++ 0x64, 0x30, ++ 0x65, 0x40, ++ 0x68, 0x26, ++ 0x69, 0x4c, ++ 0x70, 0x20, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x40, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x60, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x80, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0xa0, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x1f, ++ 0x76, 0x38, ++ 0x77, 0xa6, ++ 0x78, 0x0c, ++ 0x79, 0x80, ++ 0x7f, 0x14, ++ 0x7c, 0x00, ++ 0xae, 0x82, ++ 0x80, 0x64, ++ 0x81, 0x66, ++ 0x82, 0x44, ++ 0x85, 0x04, ++ 0xcd, 0xf4, ++ 0x90, 0x33, ++ 0xa0, 0x44, ++ 0xc0, 0x08, ++ 0xc3, 0x10, ++ 0xc4, 0x08, ++ 0xc5, 0xf0, ++ 0xc6, 0xff, ++ 0xc7, 0x00, ++ 0xc8, 0x1a, ++ 0xc9, 0x80, ++ 0xe0, 0xf8, ++ 0xe6, 0x8b, ++ 0xd0, 0x40, ++ 0xf8, 0x20, ++ 0xfa, 0x0f, ++ 0x00, 0x00, ++ 0xbd, 0x01, ++ 0xb8, 0x00, ++}; ++/* For M88DS3103 demod dvbs2 mode.*/ ++static u8 ds3103_dvbs2_init_tab[] = { ++ 0x23, 0x07, ++ 0x08, 0x07, ++ 0x0c, 0x02, ++ 0x21, 0x54, ++ 0x25, 0x82, ++ 0x27, 0x31, ++ 0x30, 0x08, ++ 0x32, 0x32, ++ 0x33, 0x35, ++ 0x35, 0xff, ++ 0x3a, 0x00, ++ 0x37, 0x10, ++ 0x38, 0x10, ++ 0x39, 0x02, ++ 0x42, 0x60, ++ 0x4a, 0x80, ++ 0x4b, 0x04, ++ 0x4d, 0x91, ++ 0x5d, 0xc8, ++ 0x50, 0x36, ++ 0x51, 0x36, ++ 0x52, 0x36, ++ 0x53, 0x36, ++ 0x63, 0x0f, ++ 0x64, 0x10, ++ 0x65, 0x20, ++ 0x68, 0x46, ++ 0x69, 0xcd, ++ 0x70, 0x20, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x40, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x60, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x80, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0xa0, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x1f, ++ 0x76, 0x38, ++ 0x77, 0xa6, ++ 0x78, 0x0c, ++ 0x79, 0x80, ++ 0x7f, 0x14, ++ 0x85, 0x08, ++ 0xcd, 0xf4, ++ 0x90, 0x33, ++ 0x86, 0x00, ++ 0x87, 0x0f, ++ 0x89, 0x00, ++ 0x8b, 0x44, ++ 0x8c, 0x66, ++ 0x9d, 0xc1, ++ 0x8a, 0x10, ++ 0xad, 0x40, ++ 0xa0, 0x44, ++ 0xc0, 0x08, ++ 0xc1, 0x10, ++ 0xc2, 0x08, ++ 0xc3, 0x10, ++ 0xc4, 0x08, ++ 0xc5, 0xf0, ++ 0xc6, 0xff, ++ 0xc7, 0x00, ++ 0xc8, 0x1a, ++ 0xc9, 0x80, ++ 0xca, 0x23, ++ 0xcb, 0x24, ++ 0xcc, 0xf4, ++ 0xce, 0x74, ++ 0x00, 0x00, ++ 0xbd, 0x01, ++ 0xb8, 0x00, ++}; ++ ++/* For M88DS3000 demod dvbs mode.*/ ++static u8 ds3000_dvbs_init_tab[] = { ++ 0x23, 0x05, ++ 0x08, 0x03, ++ 0x0c, 0x02, ++ 0x21, 0x54, ++ 0x25, 0x82, ++ 0x27, 0x31, ++ 0x30, 0x08, ++ 0x31, 0x40, ++ 0x32, 0x32, ++ 0x33, 0x35, ++ 0x35, 0xff, ++ 0x3a, 0x00, ++ 0x37, 0x10, ++ 0x38, 0x10, ++ 0x39, 0x02, ++ 0x42, 0x60, ++ 0x4a, 0x40, ++ 0x4b, 0x04, ++ 0x4d, 0x91, ++ 0x5d, 0xc8, ++ 0x50, 0x77, ++ 0x51, 0x77, ++ 0x52, 0x36, ++ 0x53, 0x36, ++ 0x56, 0x01, ++ 0x63, 0x47, ++ 0x64, 0x30, ++ 0x65, 0x40, ++ 0x68, 0x26, ++ 0x69, 0x4c, ++ 0x70, 0x20, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x40, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x60, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x80, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0xa0, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x1f, ++ 0x76, 0x00, ++ 0x77, 0xd1, ++ 0x78, 0x0c, ++ 0x79, 0x80, ++ 0x7f, 0x04, ++ 0x7c, 0x00, ++ 0x80, 0x86, ++ 0x81, 0xa6, ++ 0x85, 0x04, ++ 0xcd, 0xf4, ++ 0x90, 0x33, ++ 0xa0, 0x44, ++ 0xc0, 0x18, ++ 0xc3, 0x10, ++ 0xc4, 0x08, ++ 0xc5, 0x80, ++ 0xc6, 0x80, ++ 0xc7, 0x0a, ++ 0xc8, 0x1a, ++ 0xc9, 0x80, ++ 0xfe, 0xb6, ++ 0xe0, 0xf8, ++ 0xe6, 0x8b, ++ 0xd0, 0x40, ++ 0xf8, 0x20, ++ 0xfa, 0x0f, ++ 0xad, 0x20, ++ 0xae, 0x07, ++ 0xb8, 0x00, ++}; ++ ++/* For M88DS3000 demod dvbs2 mode.*/ ++static u8 ds3000_dvbs2_init_tab[] = { ++ 0x23, 0x0f, ++ 0x08, 0x07, ++ 0x0c, 0x02, ++ 0x21, 0x54, ++ 0x25, 0x82, ++ 0x27, 0x31, ++ 0x30, 0x08, ++ 0x31, 0x32, ++ 0x32, 0x32, ++ 0x33, 0x35, ++ 0x35, 0xff, ++ 0x3a, 0x00, ++ 0x37, 0x10, ++ 0x38, 0x10, ++ 0x39, 0x02, ++ 0x42, 0x60, ++ 0x4a, 0x80, ++ 0x4b, 0x04, ++ 0x4d, 0x91, ++ 0x5d, 0x88, ++ 0x50, 0x36, ++ 0x51, 0x36, ++ 0x52, 0x36, ++ 0x53, 0x36, ++ 0x63, 0x60, ++ 0x64, 0x10, ++ 0x65, 0x10, ++ 0x68, 0x04, ++ 0x69, 0x29, ++ 0x70, 0x20, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x40, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x60, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x80, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0xa0, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x1f, ++ 0xa0, 0x44, ++ 0xc0, 0x08, ++ 0xc1, 0x10, ++ 0xc2, 0x08, ++ 0xc3, 0x10, ++ 0xc4, 0x08, ++ 0xc5, 0xf0, ++ 0xc6, 0xf0, ++ 0xc7, 0x0a, ++ 0xc8, 0x1a, ++ 0xc9, 0x80, ++ 0xca, 0x23, ++ 0xcb, 0x24, ++ 0xce, 0x74, ++ 0x56, 0x01, ++ 0x90, 0x03, ++ 0x76, 0x80, ++ 0x77, 0x42, ++ 0x78, 0x0a, ++ 0x79, 0x80, ++ 0xad, 0x40, ++ 0xae, 0x07, ++ 0x7f, 0xd4, ++ 0x7c, 0x00, ++ 0x80, 0xa8, ++ 0x81, 0xda, ++ 0x7c, 0x01, ++ 0x80, 0xda, ++ 0x81, 0xec, ++ 0x7c, 0x02, ++ 0x80, 0xca, ++ 0x81, 0xeb, ++ 0x7c, 0x03, ++ 0x80, 0xba, ++ 0x81, 0xdb, ++ 0x85, 0x08, ++ 0x86, 0x00, ++ 0x87, 0x02, ++ 0x89, 0x80, ++ 0x8b, 0x44, ++ 0x8c, 0xaa, ++ 0x8a, 0x10, ++ 0xba, 0x00, ++ 0xf5, 0x04, ++ 0xd2, 0x32, ++ 0xb8, 0x00, ++}; ++ ++struct m88ds3103_state { ++ struct i2c_adapter *i2c; ++ const struct m88ds3103_config *config; ++ ++ struct dvb_frontend frontend; ++ ++ u32 preBer; ++ u8 skip_fw_load; ++ u8 first_lock; /* The first time of signal lock */ ++ u16 demod_id; /* demod chip type */ ++ u16 tuner_id; /* tuner chip type */ ++}; ++ ++/*demod register operations.*/ ++static int m88ds3103_writereg(struct m88ds3103_state *state, int reg, int data) ++{ ++ u8 buf[] = { reg, data }; ++ struct i2c_msg msg = { .addr = state->config->demod_address, ++ .flags = 0, .buf = buf, .len = 2 }; ++ int err; ++ ++ if (debug > 1) ++ printk("m88ds3103: %s: write reg 0x%02x, value 0x%02x\n", ++ __func__, reg, data); ++ ++ err = i2c_transfer(state->i2c, &msg, 1); ++ if (err != 1) { ++ printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x," ++ " value == 0x%02x)\n", __func__, err, reg, data); ++ return -EREMOTEIO; ++ } ++ return 0; ++} ++ ++static int m88ds3103_readreg(struct m88ds3103_state *state, u8 reg) ++{ ++ int ret; ++ u8 b0[] = { reg }; ++ u8 b1[] = { 0 }; ++ struct i2c_msg msg[] = { ++ { .addr = state->config->demod_address, .flags = 0, ++ .buf = b0, .len = 1 }, ++ { .addr = state->config->demod_address, .flags = I2C_M_RD, ++ .buf = b1, .len = 1 } ++ }; ++ ret = i2c_transfer(state->i2c, msg, 2); ++ ++ if (ret != 2) { ++ printk(KERN_ERR "%s: reg=0x%x (error=%d)\n", ++ __func__, reg, ret); ++ return ret; ++ } ++ ++ if (debug > 1) ++ printk(KERN_INFO "m88ds3103: read reg 0x%02x, value 0x%02x\n", ++ reg, b1[0]); ++ ++ return b1[0]; ++} ++ ++/*tuner register operations.*/ ++static int m88ds3103_tuner_writereg(struct m88ds3103_state *state, int reg, int data) ++{ ++ u8 buf[] = { reg, data }; ++ struct i2c_msg msg = { .addr = 0x60, ++ .flags = 0, .buf = buf, .len = 2 }; ++ int err; ++ ++ m88ds3103_writereg(state, 0x03, 0x11); ++ err = i2c_transfer(state->i2c, &msg, 1); ++ ++ if (err != 1) { ++ printk("%s: writereg error(err == %i, reg == 0x%02x," ++ " value == 0x%02x)\n", __func__, err, reg, data); ++ return -EREMOTEIO; ++ } ++ ++ return 0; ++} ++ ++static int m88ds3103_tuner_readreg(struct m88ds3103_state *state, u8 reg) ++{ ++ int ret; ++ u8 b0[] = { reg }; ++ u8 b1[] = { 0 }; ++ struct i2c_msg msg[] = { ++ { .addr = 0x60, .flags = 0, ++ .buf = b0, .len = 1 }, ++ { .addr = 0x60, .flags = I2C_M_RD, ++ .buf = b1, .len = 1 } ++ }; ++ ++ m88ds3103_writereg(state, 0x03, 0x11); ++ ret = i2c_transfer(state->i2c, msg, 2); ++ ++ if (ret != 2) { ++ printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret); ++ return ret; ++ } ++ ++ return b1[0]; ++} ++ ++/* Bulk demod I2C write, for firmware download. */ ++static int m88ds3103_writeregN(struct m88ds3103_state *state, int reg, ++ const u8 *data, u16 len) ++{ ++ int ret = -EREMOTEIO; ++ struct i2c_msg msg; ++ u8 *buf; ++ ++ buf = kmalloc(len + 1, GFP_KERNEL); ++ if (buf == NULL) { ++ printk("Unable to kmalloc\n"); ++ ret = -ENOMEM; ++ goto error; ++ } ++ ++ *(buf) = reg; ++ memcpy(buf + 1, data, len); ++ ++ msg.addr = state->config->demod_address; ++ msg.flags = 0; ++ msg.buf = buf; ++ msg.len = len + 1; ++ ++ if (debug > 1) ++ printk(KERN_INFO "m88ds3103: %s: write regN 0x%02x, len = %d\n", ++ __func__, reg, len); ++ ++ ret = i2c_transfer(state->i2c, &msg, 1); ++ if (ret != 1) { ++ printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n", ++ __func__, ret, reg); ++ ret = -EREMOTEIO; ++ } ++ ++error: ++ kfree(buf); ++ ++ return ret; ++} ++ ++static int m88ds3103_load_firmware(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ const struct firmware *fw; ++ int i, ret = 0; ++ ++ dprintk("%s()\n", __func__); ++ ++ if (state->skip_fw_load) ++ return 0; ++ /* Load firmware */ ++ /* request the firmware, this will block until someone uploads it */ ++ if(state->demod_id == DS3000_ID){ ++ printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__, ++ DS3000_DEFAULT_FIRMWARE); ++ ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE, ++ state->i2c->dev.parent); ++ }else if(state->demod_id == DS3103_ID){ ++ printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__, ++ DS3103_DEFAULT_FIRMWARE); ++ ret = request_firmware(&fw, DS3103_DEFAULT_FIRMWARE, ++ state->i2c->dev.parent); ++ } ++ ++ printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__); ++ if (ret) { ++ printk(KERN_ERR "%s: No firmware uploaded (timeout or file not " ++ "found?)\n", __func__); ++ return ret; ++ } ++ ++ /* Make sure we don't recurse back through here during loading */ ++ state->skip_fw_load = 1; ++ ++ dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n", ++ fw->size, ++ fw->data[0], ++ fw->data[1], ++ fw->data[fw->size - 2], ++ fw->data[fw->size - 1]); ++ ++ /* stop internal mcu. */ ++ m88ds3103_writereg(state, 0xb2, 0x01); ++ /* split firmware to download.*/ ++ for(i = 0; i < FW_DOWN_LOOP; i++){ ++ ret = m88ds3103_writeregN(state, 0xb0, &(fw->data[FW_DOWN_SIZE*i]), FW_DOWN_SIZE); ++ if(ret != 1) break; ++ } ++ /* start internal mcu. */ ++ if(ret == 1) ++ m88ds3103_writereg(state, 0xb2, 0x00); ++ ++ release_firmware(fw); ++ ++ dprintk("%s: Firmware upload %s\n", __func__, ++ ret == 1 ? "complete" : "failed"); ++ ++ if(ret == 1) ret = 0; ++ ++ /* Ensure firmware is always loaded if required */ ++ state->skip_fw_load = 0; ++ ++ return ret; ++} ++ ++ ++static int m88ds3103_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 data; ++ ++ dprintk("%s(%d)\n", __func__, voltage); ++ ++ dprintk("m88ds3103:pin_ctrl = (%02x)\n", state->config->pin_ctrl); ++ ++ if(state->config->set_voltage) ++ state->config->set_voltage(fe, voltage); ++ ++ data = m88ds3103_readreg(state, 0xa2); ++ ++ if(state->config->pin_ctrl & 0x80){ /*If control pin is assigned.*/ ++ data &= ~0x03; /* bit0 V/H, bit1 off/on */ ++ if(state->config->pin_ctrl & 0x02) ++ data |= 0x02; ++ ++ switch (voltage) { ++ case SEC_VOLTAGE_18: ++ if((state->config->pin_ctrl & 0x01) == 0) ++ data |= 0x01; ++ break; ++ case SEC_VOLTAGE_13: ++ if(state->config->pin_ctrl & 0x01) ++ data |= 0x01; ++ break; ++ case SEC_VOLTAGE_OFF: ++ if(state->config->pin_ctrl & 0x02) ++ data &= ~0x02; ++ else ++ data |= 0x02; ++ break; ++ } ++ } ++ ++ m88ds3103_writereg(state, 0xa2, data); ++ ++ return 0; ++} ++ ++static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t* status) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ *status = 0; ++ dprintk("%s()\n", __func__); ++ ++ switch (c->delivery_system){ ++ case SYS_DVBS: ++ if ((m88ds3103_readreg(state, 0xd1) & 0x07) == 0x07){ ++ if((m88ds3103_readreg(state, 0x0d) & 0x07) == 0x07) ++ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER ++ | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; ++ } ++ break; ++ case SYS_DVBS2: ++ if ((m88ds3103_readreg(state, 0x0d) & 0x8f) == 0x8f) ++ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER ++ | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++static int m88ds3103_read_ber(struct dvb_frontend *fe, u32* ber) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ u8 tmp1, tmp2, tmp3; ++ u32 ldpc_frame_cnt, pre_err_packags, code_rate_fac = 0; ++ ++ dprintk("%s()\n", __func__); ++ ++ switch (c->delivery_system) { ++ case SYS_DVBS: ++ m88ds3103_writereg(state, 0xf9, 0x04); ++ tmp3 = m88ds3103_readreg(state, 0xf8); ++ if ((tmp3&0x10) == 0){ ++ tmp1 = m88ds3103_readreg(state, 0xf7); ++ tmp2 = m88ds3103_readreg(state, 0xf6); ++ tmp3 |= 0x10; ++ m88ds3103_writereg(state, 0xf8, tmp3); ++ state->preBer = (tmp1<<8) | tmp2; ++ } ++ break; ++ case SYS_DVBS2: ++ tmp1 = m88ds3103_readreg(state, 0x7e) & 0x0f; ++ switch(tmp1){ ++ case 0: code_rate_fac = 16008 - 80; break; ++ case 1: code_rate_fac = 21408 - 80; break; ++ case 2: code_rate_fac = 25728 - 80; break; ++ case 3: code_rate_fac = 32208 - 80; break; ++ case 4: code_rate_fac = 38688 - 80; break; ++ case 5: code_rate_fac = 43040 - 80; break; ++ case 6: code_rate_fac = 48408 - 80; break; ++ case 7: code_rate_fac = 51648 - 80; break; ++ case 8: code_rate_fac = 53840 - 80; break; ++ case 9: code_rate_fac = 57472 - 80; break; ++ case 10: code_rate_fac = 58192 - 80; break; ++ } ++ ++ tmp1 = m88ds3103_readreg(state, 0xd7) & 0xff; ++ tmp2 = m88ds3103_readreg(state, 0xd6) & 0xff; ++ tmp3 = m88ds3103_readreg(state, 0xd5) & 0xff; ++ ldpc_frame_cnt = (tmp1 << 16) | (tmp2 << 8) | tmp3; ++ ++ tmp1 = m88ds3103_readreg(state, 0xf8) & 0xff; ++ tmp2 = m88ds3103_readreg(state, 0xf7) & 0xff; ++ pre_err_packags = tmp1<<8 | tmp2; ++ ++ if (ldpc_frame_cnt > 1000){ ++ m88ds3103_writereg(state, 0xd1, 0x01); ++ m88ds3103_writereg(state, 0xf9, 0x01); ++ m88ds3103_writereg(state, 0xf9, 0x00); ++ m88ds3103_writereg(state, 0xd1, 0x00); ++ state->preBer = pre_err_packags; ++ } ++ break; ++ default: ++ break; ++ } ++ *ber = state->preBer; ++ ++ return 0; ++} ++ ++static int m88ds3103_read_signal_strength(struct dvb_frontend *fe, ++ u16 *signal_strength) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u16 gain; ++ u8 gain1, gain2, gain3 = 0; ++ ++ dprintk("%s()\n", __func__); ++ ++ gain1 = m88ds3103_tuner_readreg(state, 0x3d) & 0x1f; ++ dprintk("%s: gain1 = 0x%02x \n", __func__, gain1); ++ ++ if (gain1 > 15) gain1 = 15; ++ gain2 = m88ds3103_tuner_readreg(state, 0x21) & 0x1f; ++ dprintk("%s: gain2 = 0x%02x \n", __func__, gain2); ++ ++ if(state->tuner_id == TS2022_ID){ ++ gain3 = (m88ds3103_tuner_readreg(state, 0x66)>>3) & 0x07; ++ dprintk("%s: gain3 = 0x%02x \n", __func__, gain3); ++ ++ if (gain2 > 16) gain2 = 16; ++ if (gain2 < 2) gain2 = 2; ++ if (gain3 > 6) gain3 = 6; ++ }else{ ++ if (gain2 > 13) gain2 = 13; ++ gain3 = 0; ++ } ++ ++ gain = gain1*23 + gain2*35 + gain3*29; ++ *signal_strength = 60000 - gain*55; ++ ++ return 0; ++} ++ ++ ++static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *p_snr) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ u8 val, npow1, npow2, spow1, cnt; ++ u16 tmp, snr; ++ u32 npow, spow, snr_total; ++ static const u16 mes_log10[] ={ ++ 0, 3010, 4771, 6021, 6990, 7781, 8451, 9031, 9542, 10000, ++ 10414, 10792, 11139, 11461, 11761, 12041, 12304, 12553, 12788, 13010, ++ 13222, 13424, 13617, 13802, 13979, 14150, 14314, 14472, 14624, 14771, ++ 14914, 15052, 15185, 15315, 15441, 15563, 15682, 15798, 15911, 16021, ++ 16128, 16232, 16335, 16435, 16532, 16628, 16721, 16812, 16902, 16990, ++ 17076, 17160, 17243, 17324, 17404, 17482, 17559, 17634, 17709, 17782, ++ 17853, 17924, 17993, 18062, 18129, 18195, 18261, 18325, 18388, 18451, ++ 18513, 18573, 18633, 18692, 18751, 18808, 18865, 18921, 18976, 19031 ++ }; ++ static const u16 mes_loge[] ={ ++ 0, 6931, 10986, 13863, 16094, 17918, 19459, 20794, 21972, 23026, ++ 23979, 24849, 25649, 26391, 27081, 27726, 28332, 28904, 29444, 29957, ++ 30445, 30910, 31355, 31781, 32189, 32581, 32958, 33322, 33673, 34012, ++ 34340, 34657, ++ }; ++ ++ dprintk("%s()\n", __func__); ++ ++ switch (c->delivery_system){ ++ case SYS_DVBS: ++ cnt = 10; snr_total = 0; ++ while(cnt > 0){ ++ val = m88ds3103_readreg(state, 0xff); ++ snr_total += val; ++ cnt--; ++ } ++ tmp = (u16)(snr_total/80); ++ if(tmp > 0){ ++ if (tmp > 32) tmp = 32; ++ snr = (mes_loge[tmp - 1] * 100) / 45; ++ }else{ ++ snr = 0; ++ } ++ break; ++ case SYS_DVBS2: ++ cnt = 10; npow = 0; spow = 0; ++ while(cnt >0){ ++ npow1 = m88ds3103_readreg(state, 0x8c) & 0xff; ++ npow2 = m88ds3103_readreg(state, 0x8d) & 0xff; ++ npow += (((npow1 & 0x3f) + (u16)(npow2 << 6)) >> 2); ++ ++ spow1 = m88ds3103_readreg(state, 0x8e) & 0xff; ++ spow += ((spow1 * spow1) >> 1); ++ cnt--; ++ } ++ npow /= 10; spow /= 10; ++ if(spow == 0){ ++ snr = 0; ++ }else if(npow == 0){ ++ snr = 19; ++ }else{ ++ if(spow > npow){ ++ tmp = (u16)(spow / npow); ++ if (tmp > 80) tmp = 80; ++ snr = mes_log10[tmp - 1]*3; ++ }else{ ++ tmp = (u16)(npow / spow); ++ if (tmp > 80) tmp = 80; ++ snr = -(mes_log10[tmp - 1] / 1000); ++ } ++ } ++ break; ++ default: ++ break; ++ } ++ *p_snr = snr; ++ ++ return 0; ++} ++ ++ ++static int m88ds3103_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ u8 tmp1, tmp2, tmp3, data; ++ ++ dprintk("%s()\n", __func__); ++ ++ switch (c->delivery_system) { ++ case SYS_DVBS: ++ data = m88ds3103_readreg(state, 0xf8); ++ data |= 0x40; ++ m88ds3103_writereg(state, 0xf8, data); ++ tmp1 = m88ds3103_readreg(state, 0xf5); ++ tmp2 = m88ds3103_readreg(state, 0xf4); ++ *ucblocks = (tmp1 <<8) | tmp2; ++ data &= ~0x20; ++ m88ds3103_writereg(state, 0xf8, data); ++ data |= 0x20; ++ m88ds3103_writereg(state, 0xf8, data); ++ data &= ~0x40; ++ m88ds3103_writereg(state, 0xf8, data); ++ break; ++ case SYS_DVBS2: ++ tmp1 = m88ds3103_readreg(state, 0xda); ++ tmp2 = m88ds3103_readreg(state, 0xd9); ++ tmp3 = m88ds3103_readreg(state, 0xd8); ++ *ucblocks = (tmp1 <<16)|(tmp2 <<8)|tmp3; ++ data = m88ds3103_readreg(state, 0xd1); ++ data |= 0x01; ++ m88ds3103_writereg(state, 0xd1, data); ++ data &= ~0x01; ++ m88ds3103_writereg(state, 0xd1, data); ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static int m88ds3103_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 data_a1, data_a2; ++ ++ dprintk("%s(%d)\n", __func__, tone); ++ if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { ++ printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone); ++ return -EINVAL; ++ } ++ ++ data_a1 = m88ds3103_readreg(state, 0xa1); ++ data_a2 = m88ds3103_readreg(state, 0xa2); ++ if(state->demod_id == DS3103_ID) ++ data_a2 &= 0xdf; /* Normal mode */ ++ switch (tone) { ++ case SEC_TONE_ON: ++ dprintk("%s: SEC_TONE_ON\n", __func__); ++ data_a1 |= 0x04; ++ data_a1 &= ~0x03; ++ data_a1 &= ~0x40; ++ data_a2 &= ~0xc0; ++ break; ++ case SEC_TONE_OFF: ++ dprintk("%s: SEC_TONE_OFF\n", __func__); ++ data_a2 &= ~0xc0; ++ data_a2 |= 0x80; ++ break; ++ } ++ m88ds3103_writereg(state, 0xa2, data_a2); ++ m88ds3103_writereg(state, 0xa1, data_a1); ++ return 0; ++} ++ ++static int m88ds3103_send_diseqc_msg(struct dvb_frontend *fe, ++ struct dvb_diseqc_master_cmd *d) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ int i, ret = 0; ++ u8 tmp, time_out; ++ ++ /* Dump DiSEqC message */ ++ if (debug) { ++ printk(KERN_INFO "m88ds3103: %s(", __func__); ++ for (i = 0 ; i < d->msg_len ;) { ++ printk(KERN_INFO "0x%02x", d->msg[i]); ++ if (++i < d->msg_len) ++ printk(KERN_INFO ", "); ++ } ++ } ++ ++ tmp = m88ds3103_readreg(state, 0xa2); ++ tmp &= ~0xc0; ++ if(state->demod_id == DS3103_ID) ++ tmp &= ~0x20; ++ m88ds3103_writereg(state, 0xa2, tmp); ++ ++ for (i = 0; i < d->msg_len; i ++) ++ m88ds3103_writereg(state, (0xa3+i), d->msg[i]); ++ ++ tmp = m88ds3103_readreg(state, 0xa1); ++ tmp &= ~0x38; ++ tmp &= ~0x40; ++ tmp |= ((d->msg_len-1) << 3) | 0x07; ++ tmp &= ~0x80; ++ m88ds3103_writereg(state, 0xa1, tmp); ++ /* 1.5 * 9 * 8 = 108ms */ ++ time_out = 150; ++ while (time_out > 0){ ++ msleep(10); ++ time_out -= 10; ++ tmp = m88ds3103_readreg(state, 0xa1); ++ if ((tmp & 0x40) == 0) ++ break; ++ } ++ if (time_out == 0){ ++ tmp = m88ds3103_readreg(state, 0xa1); ++ tmp &= ~0x80; ++ tmp |= 0x40; ++ m88ds3103_writereg(state, 0xa1, tmp); ++ ret = 1; ++ } ++ tmp = m88ds3103_readreg(state, 0xa2); ++ tmp &= ~0xc0; ++ tmp |= 0x80; ++ m88ds3103_writereg(state, 0xa2, tmp); ++ return ret; ++} ++ ++ ++static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, ++ fe_sec_mini_cmd_t burst) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 val, time_out; ++ ++ dprintk("%s()\n", __func__); ++ ++ val = m88ds3103_readreg(state, 0xa2); ++ val &= ~0xc0; ++ if(state->demod_id == DS3103_ID) ++ val &= 0xdf; /* Normal mode */ ++ m88ds3103_writereg(state, 0xa2, val); ++ /* DiSEqC burst */ ++ if (burst == SEC_MINI_B) ++ m88ds3103_writereg(state, 0xa1, 0x01); ++ else ++ m88ds3103_writereg(state, 0xa1, 0x02); ++ ++ msleep(13); ++ ++ time_out = 5; ++ do{ ++ val = m88ds3103_readreg(state, 0xa1); ++ if ((val & 0x40) == 0) ++ break; ++ msleep(1); ++ time_out --; ++ } while (time_out > 0); ++ ++ val = m88ds3103_readreg(state, 0xa2); ++ val &= ~0xc0; ++ val |= 0x80; ++ m88ds3103_writereg(state, 0xa2, val); ++ ++ return 0; ++} ++ ++static void m88ds3103_release(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ ++ dprintk("%s\n", __func__); ++ kfree(state); ++} ++ ++static int m88ds3103_check_id(struct m88ds3103_state *state) ++{ ++ int val_00, val_01; ++ ++ /*check demod id*/ ++ val_01 = m88ds3103_readreg(state, 0x01); ++ printk(KERN_INFO "DS3000 chip version: %x attached.\n", val_01); ++ ++ if(val_01 == 0xD0) ++ state->demod_id = DS3103_ID; ++ else if(val_01 == 0xC0) ++ state->demod_id = DS3000_ID; ++ else ++ state->demod_id = UNKNOW_ID; ++ ++ /*check tuner id*/ ++ val_00 = m88ds3103_tuner_readreg(state, 0x00); ++ printk(KERN_INFO "TS202x chip version[1]: %x attached.\n", val_00); ++ val_00 &= 0x03; ++ if(val_00 == 0) ++ { ++ m88ds3103_tuner_writereg(state, 0x00, 0x01); ++ msleep(3); ++ } ++ m88ds3103_tuner_writereg(state, 0x00, 0x03); ++ msleep(5); ++ ++ val_00 = m88ds3103_tuner_readreg(state, 0x00); ++ printk(KERN_INFO "TS202x chip version[2]: %x attached.\n", val_00); ++ val_00 &= 0xff; ++ if((val_00 == 0x01) || (val_00 == 0x41) || (val_00 == 0x81)) ++ state->tuner_id = TS2020_ID; ++ else if(((val_00 & 0xc0)== 0xc0) || (val_00 == 0x83)) ++ state->tuner_id = TS2022_ID; ++ else ++ state->tuner_id = UNKNOW_ID; ++ ++ return state->demod_id; ++} ++ ++static struct dvb_frontend_ops m88ds3103_ops; ++static int m88ds3103_initilaze(struct dvb_frontend *fe); ++ ++struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *config, ++ struct i2c_adapter *i2c) ++{ ++ struct m88ds3103_state *state = NULL; ++ ++ dprintk("%s\n", __func__); ++ ++ /* allocate memory for the internal state */ ++ state = kzalloc(sizeof(struct m88ds3103_state), GFP_KERNEL); ++ if (state == NULL) { ++ printk(KERN_ERR "Unable to kmalloc\n"); ++ goto error2; ++ } ++ ++ state->config = config; ++ state->i2c = i2c; ++ state->preBer = 0xffff; ++ ++ /* check demod id */ ++ if(m88ds3103_check_id(state) == UNKNOW_ID){ ++ printk(KERN_ERR "Unable to find Montage chip\n"); ++ goto error3; ++ } ++ ++ memcpy(&state->frontend.ops, &m88ds3103_ops, ++ sizeof(struct dvb_frontend_ops)); ++ state->frontend.demodulator_priv = state; ++ ++ m88ds3103_initilaze(&state->frontend); ++ ++ return &state->frontend; ++ ++error3: ++ kfree(state); ++error2: ++ return NULL; ++} ++EXPORT_SYMBOL(m88ds3103_attach); ++ ++static int m88ds3103_set_property(struct dvb_frontend *fe, ++ struct dtv_property *tvp) ++{ ++ dprintk("%s(..)\n", __func__); ++ return 0; ++} ++ ++static int m88ds3103_get_property(struct dvb_frontend *fe, ++ struct dtv_property *tvp) ++{ ++ dprintk("%s(..)\n", __func__); ++ return 0; ++} ++ ++static int m88ds3103_set_carrier_offset(struct dvb_frontend *fe, ++ s32 carrier_offset_khz) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ s32 tmp; ++ ++ tmp = carrier_offset_khz; ++ tmp *= 65536; ++ ++ tmp = (2*tmp + MT_FE_MCLK_KHZ) / (2*MT_FE_MCLK_KHZ); ++ ++ if (tmp < 0) ++ tmp += 65536; ++ ++ m88ds3103_writereg(state, 0x5f, tmp >> 8); ++ m88ds3103_writereg(state, 0x5e, tmp & 0xff); ++ ++ return 0; ++} ++ ++static int m88ds3103_set_symrate(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ u16 value; ++ ++ value = (((c->symbol_rate / 1000) << 15) + (MT_FE_MCLK_KHZ / 4)) / (MT_FE_MCLK_KHZ / 2); ++ m88ds3103_writereg(state, 0x61, value & 0x00ff); ++ m88ds3103_writereg(state, 0x62, (value & 0xff00) >> 8); ++ ++ return 0; ++} ++ ++static int m88ds3103_set_CCI(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 tmp; ++ ++ tmp = m88ds3103_readreg(state, 0x56); ++ tmp &= ~0x01; ++ m88ds3103_writereg(state, 0x56, tmp); ++ ++ tmp = m88ds3103_readreg(state, 0x76); ++ tmp &= ~0x80; ++ m88ds3103_writereg(state, 0x76, tmp); ++ ++ return 0; ++} ++ ++static int m88ds3103_init_reg(struct m88ds3103_state *state, const u8 *p_reg_tab, u32 size) ++{ ++ u32 i; ++ ++ for(i = 0; i < size; i+=2) ++ m88ds3103_writereg(state, p_reg_tab[i], p_reg_tab[i+1]); ++ ++ return 0; ++} ++ ++static int m88ds3103_set_frontend(struct dvb_frontend *fe, ++ struct dvb_frontend_parameters *p) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ ++ int i; ++ fe_status_t status; ++ u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf, div4, capCode, changePLL; ++ s32 offset_khz; ++ u16 value, ndiv, lpf_coeff; ++ u32 f3db, gdiv28; ++ u8 val1,val2,data, RFgain; ++ ++ dprintk("%s() ", __func__); ++ ++ if (state->config->set_ts_params) ++ state->config->set_ts_params(fe, 0); ++ ++ div4 = 0; ++ if(state->tuner_id == TS2022_ID){ ++ m88ds3103_tuner_writereg(state, 0x10, 0x0a); ++ m88ds3103_tuner_writereg(state, 0x11, 0x40); ++ if (p->frequency < 1103000) { ++ m88ds3103_tuner_writereg(state, 0x10, 0x1b); ++ div4 = 1; ++ ndiv = (p->frequency * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ; ++ }else { ++ ndiv = (p->frequency * (6 + 8) * 2)/MT_FE_CRYSTAL_KHZ; ++ } ++ ndiv = ndiv + ndiv%2; ++ if(ndiv < 4095) ++ ndiv = ndiv - 1024; ++ else if (ndiv < 6143) ++ ndiv = ndiv + 1024; ++ else ++ ndiv = ndiv + 3072; ++ ++ m88ds3103_tuner_writereg(state, 0x01, (ndiv & 0x3f00) >> 8); ++ }else{ ++ m88ds3103_tuner_writereg(state, 0x10, 0x00); ++ if (p->frequency < 1146000){ ++ m88ds3103_tuner_writereg(state, 0x10, 0x11); ++ div4 = 1; ++ ndiv = (p->frequency * (6 + 8) * 4) / MT_FE_CRYSTAL_KHZ; ++ }else{ ++ m88ds3103_tuner_writereg(state, 0x10, 0x01); ++ ndiv = (p->frequency * (6 + 8) * 2) / MT_FE_CRYSTAL_KHZ; ++ } ++ ndiv = ndiv + ndiv%2; ++ ndiv = ndiv - 1024; ++ m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8)&0x0f); ++ } ++ /* set pll */ ++ m88ds3103_tuner_writereg(state, 0x02, ndiv & 0x00ff); ++ m88ds3103_tuner_writereg(state, 0x03, 0x06); ++ m88ds3103_tuner_writereg(state, 0x51, 0x0f); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x10); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ ++ if(state->tuner_id == TS2022_ID){ ++ if(( p->frequency >= 1650000 ) && (p->frequency <= 1850000)){ ++ msleep(5); ++ value = m88ds3103_tuner_readreg(state, 0x14); ++ value &= 0x7f; ++ if(value < 64){ ++ m88ds3103_tuner_writereg(state, 0x10, 0x82); ++ m88ds3103_tuner_writereg(state, 0x11, 0x6f); ++ ++ m88ds3103_tuner_writereg(state, 0x51, 0x0f); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x10); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ } ++ } ++ msleep(5); ++ value = m88ds3103_tuner_readreg(state, 0x14); ++ value &= 0x1f; ++ ++ if(value > 19){ ++ value = m88ds3103_tuner_readreg(state, 0x10); ++ value &= 0x1d; ++ m88ds3103_tuner_writereg(state, 0x10, value); ++ } ++ }else{ ++ msleep(5); ++ value = m88ds3103_tuner_readreg(state, 0x66); ++ changePLL = (((value & 0x80) >> 7) != div4); ++ ++ if(changePLL){ ++ m88ds3103_tuner_writereg(state, 0x10, 0x11); ++ div4 = 1; ++ ndiv = (p->frequency * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ; ++ ndiv = ndiv + ndiv%2; ++ ndiv = ndiv - 1024; ++ ++ m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8) & 0x0f); ++ m88ds3103_tuner_writereg(state, 0x02, ndiv & 0xff); ++ ++ m88ds3103_tuner_writereg(state, 0x51, 0x0f); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x10); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ } ++ } ++ /*set the RF gain*/ ++ if(state->tuner_id == TS2020_ID) ++ m88ds3103_tuner_writereg(state, 0x60, 0x79); ++ ++ m88ds3103_tuner_writereg(state, 0x51, 0x17); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x08); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ msleep(5); ++ ++ if(state->tuner_id == TS2020_ID){ ++ RFgain = m88ds3103_tuner_readreg(state, 0x3d); ++ RFgain &= 0x0f; ++ if(RFgain < 15){ ++ if(RFgain < 4) ++ RFgain = 0; ++ else ++ RFgain = RFgain -3; ++ value = ((RFgain << 3) | 0x01) & 0x79; ++ m88ds3103_tuner_writereg(state, 0x60, value); ++ m88ds3103_tuner_writereg(state, 0x51, 0x17); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x08); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ } ++ } ++ ++ /* set the LPF */ ++ if(state->tuner_id == TS2022_ID){ ++ m88ds3103_tuner_writereg(state, 0x25, 0x00); ++ m88ds3103_tuner_writereg(state, 0x27, 0x70); ++ m88ds3103_tuner_writereg(state, 0x41, 0x09); ++ m88ds3103_tuner_writereg(state, 0x08, 0x0b); ++ } ++ ++ f3db = ((c->symbol_rate / 1000) *135) / 200 + 2000; ++ f3db += FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz; ++ if (f3db < 7000) ++ f3db = 7000; ++ if (f3db > 40000) ++ f3db = 40000; ++ ++ gdiv28 = (MT_FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000; ++ m88ds3103_tuner_writereg(state, 0x04, gdiv28 & 0xff); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1b); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x04); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ msleep(5); ++ ++ value = m88ds3103_tuner_readreg(state, 0x26); ++ capCode = value & 0x3f; ++ if(state->tuner_id == TS2022_ID){ ++ m88ds3103_tuner_writereg(state, 0x41, 0x0d); ++ ++ m88ds3103_tuner_writereg(state, 0x51, 0x1b); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x04); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ ++ msleep(2); ++ ++ value = m88ds3103_tuner_readreg(state, 0x26); ++ value &= 0x3f; ++ value = (capCode + value) / 2; ++ } ++ else ++ value = capCode; ++ ++ gdiv28 = gdiv28 * 207 / (value * 2 + 151); ++ mlpf_max = gdiv28 * 135 / 100; ++ mlpf_min = gdiv28 * 78 / 100; ++ if (mlpf_max > 63) ++ mlpf_max = 63; ++ ++ if(state->tuner_id == TS2022_ID) ++ lpf_coeff = 3200; ++ else ++ lpf_coeff = 2766; ++ ++ nlpf = (f3db * gdiv28 * 2 / lpf_coeff / (MT_FE_CRYSTAL_KHZ / 1000) + 1) / 2 ; ++ if (nlpf > 23) nlpf = 23; ++ if (nlpf < 1) nlpf = 1; ++ ++ lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2; ++ ++ if (lpf_mxdiv < mlpf_min){ ++ nlpf++; ++ lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2; ++ } ++ ++ if (lpf_mxdiv > mlpf_max) ++ lpf_mxdiv = mlpf_max; ++ ++ m88ds3103_tuner_writereg(state, 0x04, lpf_mxdiv); ++ m88ds3103_tuner_writereg(state, 0x06, nlpf); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1b); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x04); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ msleep(5); ++ ++ if(state->tuner_id == TS2022_ID){ ++ msleep(2); ++ value = m88ds3103_tuner_readreg(state, 0x26); ++ capCode = value & 0x3f; ++ ++ m88ds3103_tuner_writereg(state, 0x41, 0x09); ++ ++ m88ds3103_tuner_writereg(state, 0x51, 0x1b); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x04); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ ++ msleep(2); ++ value = m88ds3103_tuner_readreg(state, 0x26); ++ value &= 0x3f; ++ value = (capCode + value) / 2; ++ ++ value = value | 0x80; ++ m88ds3103_tuner_writereg(state, 0x25, value); ++ m88ds3103_tuner_writereg(state, 0x27, 0x30); ++ ++ m88ds3103_tuner_writereg(state, 0x08, 0x09); ++ } ++ ++ /* Set the BB gain */ ++ m88ds3103_tuner_writereg(state, 0x51, 0x1e); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x01); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ if(state->tuner_id == TS2020_ID){ ++ if(RFgain == 15){ ++ msleep(40); ++ value = m88ds3103_tuner_readreg(state, 0x21); ++ value &= 0x0f; ++ if(value < 3){ ++ m88ds3103_tuner_writereg(state, 0x60, 0x61); ++ m88ds3103_tuner_writereg(state, 0x51, 0x17); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x08); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ } ++ } ++ } ++ msleep(60); ++ ++ offset_khz = (ndiv - ndiv % 2 + 1024) * MT_FE_CRYSTAL_KHZ ++ / (6 + 8) / (div4 + 1) / 2 - p->frequency; ++ ++ /* ds3000 global reset */ ++ m88ds3103_writereg(state, 0x07, 0x80); ++ m88ds3103_writereg(state, 0x07, 0x00); ++ /* ds3000 build-in uC reset */ ++ m88ds3103_writereg(state, 0xb2, 0x01); ++ /* ds3000 software reset */ ++ m88ds3103_writereg(state, 0x00, 0x01); ++ ++ switch (c->delivery_system) { ++ case SYS_DVBS: ++ /* initialise the demod in DVB-S mode */ ++ if(state->demod_id == DS3000_ID){ ++ m88ds3103_init_reg(state, ds3000_dvbs_init_tab, sizeof(ds3000_dvbs_init_tab)); ++ ++ value = m88ds3103_readreg(state, 0xfe); ++ value &= 0xc0; ++ value |= 0x1b; ++ m88ds3103_writereg(state, 0xfe, value); ++ ++ if(state->config->ci_mode) ++ val1 = 0x80; ++ else if(state->config->ts_mode) ++ val1 = 0x60; ++ else ++ val1 = 0x20; ++ m88ds3103_writereg(state, 0xfd, val1); ++ ++ }else if(state->demod_id == DS3103_ID){ ++ m88ds3103_init_reg(state, ds3103_dvbs_init_tab, sizeof(ds3103_dvbs_init_tab)); ++ ++ /* set ts clock */ ++ if(state->config->ts_mode == 0) { ++ val1 = 3; val2 = 3; ++ }else{ ++ val1 = 0; val2 = 0; ++ } ++ val1 -= 1; val2 -= 1; ++ val1 &= 0x3f; val2 &= 0x3f; ++ data = m88ds3103_readreg(state, 0xfe); ++ data &= 0xf0; ++ data |= (val2 >> 2) & 0x0f; ++ m88ds3103_writereg(state, 0xfe, data); ++ data = (val2 & 0x03) << 6; ++ data |= val1; ++ m88ds3103_writereg(state, 0xea, data); ++ ++ m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d)); ++ m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30)); ++ ++ /* set master clock */ ++ val1 = m88ds3103_readreg(state, 0x22); ++ val2 = m88ds3103_readreg(state, 0x24); ++ ++ val1 &= 0x3f; ++ val2 &= 0x3f; ++ val1 |= 0x80; ++ val2 |= 0x40; ++ ++ m88ds3103_writereg(state, 0x22, val1); ++ m88ds3103_writereg(state, 0x24, val2); ++ ++ if(state->config->ci_mode) ++ val1 = 0x03; ++ else if(state->config->ts_mode) ++ val1 = 0x06; ++ else ++ val1 = 0x42; ++ m88ds3103_writereg(state, 0xfd, val1); ++ } ++ break; ++ case SYS_DVBS2: ++ /* initialise the demod in DVB-S2 mode */ ++ if(state->demod_id == DS3000_ID){ ++ m88ds3103_init_reg(state, ds3000_dvbs2_init_tab, sizeof(ds3000_dvbs2_init_tab)); ++ ++ if (c->symbol_rate >= 30000000) ++ m88ds3103_writereg(state, 0xfe, 0x54); ++ else ++ m88ds3103_writereg(state, 0xfe, 0x98); ++ ++ }else if(state->demod_id == DS3103_ID){ ++ m88ds3103_init_reg(state, ds3103_dvbs2_init_tab, sizeof(ds3103_dvbs2_init_tab)); ++ ++ /* set ts clock */ ++ if(state->config->ts_mode == 0){ ++ val1 = 5; val2 = 4; ++ }else{ ++ val1 = 0; val2 = 0; ++ } ++ val1 -= 1; val2 -= 1; ++ val1 &= 0x3f; val2 &= 0x3f; ++ data = m88ds3103_readreg(state, 0xfe); ++ data &= 0xf0; ++ data |= (val2 >> 2) & 0x0f; ++ m88ds3103_writereg(state, 0xfe, data); ++ data = (val2 & 0x03) << 6; ++ data |= val1; ++ m88ds3103_writereg(state, 0xea, data); ++ ++ m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d)); ++ m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30)); ++ ++ /* set master clock */ ++ val1 = m88ds3103_readreg(state, 0x22); ++ val2 = m88ds3103_readreg(state, 0x24); ++ ++ val1 &= 0x3f; ++ val2 &= 0x3f; ++ if(state->config->ts_mode == 1){ ++ val1 |= 0x80; ++ val2 |= 0x40; ++ }else{ ++ if (c->symbol_rate >= 28000000){ ++ val1 |= 0xc0; ++ }else if (c->symbol_rate >= 18000000){ ++ val2 |= 0x40; ++ }else{ ++ val1 |= 0x80; ++ val2 |= 0x40; ++ } ++ } ++ m88ds3103_writereg(state, 0x22, val1); ++ m88ds3103_writereg(state, 0x24, val2); ++ } ++ ++ if(state->config->ci_mode) ++ val1 = 0x03; ++ else if(state->config->ts_mode) ++ val1 = 0x06; ++ else ++ val1 = 0x42; ++ m88ds3103_writereg(state, 0xfd, val1); ++ ++ break; ++ default: ++ return 1; ++ } ++ /* disable 27MHz clock output */ ++ m88ds3103_writereg(state, 0x29, 0x80); ++ /* enable ac coupling */ ++ m88ds3103_writereg(state, 0x25, 0x8a); ++ ++ if ((c->symbol_rate / 1000) <= 3000){ ++ m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 32 * 100 / 64 = 400*/ ++ m88ds3103_writereg(state, 0xc8, 0x20); ++ m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/ ++ m88ds3103_writereg(state, 0xc7, 0x00); ++ }else if((c->symbol_rate / 1000) <= 10000){ ++ m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 16 * 100 / 64 = 200*/ ++ m88ds3103_writereg(state, 0xc8, 0x10); ++ m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/ ++ m88ds3103_writereg(state, 0xc7, 0x00); ++ }else{ ++ m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 6 * 100 / 64 = 75*/ ++ m88ds3103_writereg(state, 0xc8, 0x06); ++ m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/ ++ m88ds3103_writereg(state, 0xc7, 0x00); ++ } ++ ++ m88ds3103_set_symrate(fe); ++ ++ m88ds3103_set_CCI(fe); ++ ++ m88ds3103_set_carrier_offset(fe, offset_khz); ++ ++ /* ds3000 out of software reset */ ++ m88ds3103_writereg(state, 0x00, 0x00); ++ /* start ds3000 build-in uC */ ++ m88ds3103_writereg(state, 0xb2, 0x00); ++ ++ for (i = 0; i < 30 ; i++) { ++ m88ds3103_read_status(fe, &status); ++ if (status && FE_HAS_LOCK){ ++ if(state->config->start_ctrl){ ++ if(state->first_lock == 0){ ++ state->config->start_ctrl(fe); ++ state->first_lock = 1; ++ } ++ } ++ break; ++ } ++ msleep(10); ++ } ++ return 0; ++} ++ ++static int m88ds3103_tune(struct dvb_frontend *fe, ++ struct dvb_frontend_parameters *params, ++ unsigned int mode_flags, ++ unsigned int *delay, ++ fe_status_t *status) ++{ ++ *delay = HZ / 5; ++ if (params) { ++ int ret = m88ds3103_set_frontend(fe, params); ++ if (ret) ++ return ret; ++ } ++ return m88ds3103_read_status(fe, status); ++} ++ ++static enum dvbfe_algo m88ds3103_get_algo(struct dvb_frontend *fe) ++{ ++ return DVBFE_ALGO_HW; ++} ++ ++ /* ++ * Power config will reset and load initial firmware if required ++ */ ++static int m88ds3103_initilaze(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ int ret; ++ ++ dprintk("%s()\n", __func__); ++ /* hard reset */ ++ m88ds3103_writereg(state, 0x07, 0x80); ++ m88ds3103_writereg(state, 0x07, 0x00); ++ msleep(1); ++ ++ m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08)); ++ msleep(1); ++ ++ if(state->tuner_id == TS2020_ID){ ++ /* TS2020 init */ ++ m88ds3103_tuner_writereg(state, 0x42, 0x73); ++ msleep(2); ++ m88ds3103_tuner_writereg(state, 0x05, 0x01); ++ m88ds3103_tuner_writereg(state, 0x62, 0xb5); ++ m88ds3103_tuner_writereg(state, 0x07, 0x02); ++ m88ds3103_tuner_writereg(state, 0x08, 0x01); ++ } ++ else if(state->tuner_id == TS2022_ID){ ++ /* TS2022 init */ ++ m88ds3103_tuner_writereg(state, 0x62, 0x6c); ++ msleep(2); ++ m88ds3103_tuner_writereg(state, 0x42, 0x6c); ++ msleep(2); ++ m88ds3103_tuner_writereg(state, 0x7d, 0x9d); ++ m88ds3103_tuner_writereg(state, 0x7c, 0x9a); ++ m88ds3103_tuner_writereg(state, 0x7a, 0x76); ++ ++ m88ds3103_tuner_writereg(state, 0x3b, 0x01); ++ m88ds3103_tuner_writereg(state, 0x63, 0x88); ++ ++ m88ds3103_tuner_writereg(state, 0x61, 0x85); ++ m88ds3103_tuner_writereg(state, 0x22, 0x30); ++ m88ds3103_tuner_writereg(state, 0x30, 0x40); ++ m88ds3103_tuner_writereg(state, 0x20, 0x23); ++ m88ds3103_tuner_writereg(state, 0x24, 0x02); ++ m88ds3103_tuner_writereg(state, 0x12, 0xa0); ++ } ++ ++ if(state->demod_id == DS3103_ID){ ++ m88ds3103_writereg(state, 0x07, 0xe0); ++ m88ds3103_writereg(state, 0x07, 0x00); ++ msleep(1); ++ } ++ m88ds3103_writereg(state, 0xb2, 0x01); ++ ++ /* Load the firmware if required */ ++ ret = m88ds3103_load_firmware(fe); ++ if (ret != 0){ ++ printk(KERN_ERR "%s: Unable initialize firmware\n", __func__); ++ return ret; ++ } ++ if(state->demod_id == DS3103_ID){ ++ m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d)); ++ m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30)); ++ } ++ ++ return 0; ++} ++ ++/* ++ * Initialise or wake up device ++ */ ++static int m88ds3103_initfe(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 val; ++ ++ dprintk("%s()\n", __func__); ++ ++ /* 1st step to wake up demod */ ++ m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08)); ++ m88ds3103_writereg(state, 0x04, 0xfe & m88ds3103_readreg(state, 0x04)); ++ m88ds3103_writereg(state, 0x23, 0xef & m88ds3103_readreg(state, 0x23)); ++ ++ /* 2nd step to wake up tuner */ ++ val = m88ds3103_tuner_readreg(state, 0x00) & 0xff; ++ if((val & 0x01) == 0){ ++ m88ds3103_tuner_writereg(state, 0x00, 0x01); ++ msleep(50); ++ } ++ m88ds3103_tuner_writereg(state, 0x00, 0x03); ++ msleep(50); ++ ++ return 0; ++} ++ ++/* Put device to sleep */ ++static int m88ds3103_sleep(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ ++ dprintk("%s()\n", __func__); ++ ++ /* 1st step to sleep tuner */ ++ m88ds3103_tuner_writereg(state, 0x00, 0x00); ++ ++ /* 2nd step to sleep demod */ ++ m88ds3103_writereg(state, 0x08, 0xfe & m88ds3103_readreg(state, 0x08)); ++ m88ds3103_writereg(state, 0x04, 0x01 | m88ds3103_readreg(state, 0x04)); ++ m88ds3103_writereg(state, 0x23, 0x10 | m88ds3103_readreg(state, 0x23)); ++ ++ ++ return 0; ++} ++ ++static struct dvb_frontend_ops m88ds3103_ops = { ++ ++ .info = { ++ .name = "Montage DS3103/TS2022", ++ .type = FE_QPSK, ++ .frequency_min = 950000, ++ .frequency_max = 2150000, ++ .frequency_stepsize = 1011, /* kHz for QPSK frontends */ ++ .frequency_tolerance = 5000, ++ .symbol_rate_min = 1000000, ++ .symbol_rate_max = 45000000, ++ .caps = FE_CAN_INVERSION_AUTO | ++ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | ++ FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | ++ FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | ++ FE_CAN_2G_MODULATION | ++ FE_CAN_QPSK | FE_CAN_RECOVER ++ }, ++ ++ .release = m88ds3103_release, ++ ++ .init = m88ds3103_initfe, ++ .sleep = m88ds3103_sleep, ++ .read_status = m88ds3103_read_status, ++ .read_ber = m88ds3103_read_ber, ++ .read_signal_strength = m88ds3103_read_signal_strength, ++ .read_snr = m88ds3103_read_snr, ++ .read_ucblocks = m88ds3103_read_ucblocks, ++ .set_tone = m88ds3103_set_tone, ++ .set_voltage = m88ds3103_set_voltage, ++ .diseqc_send_master_cmd = m88ds3103_send_diseqc_msg, ++ .diseqc_send_burst = m88ds3103_diseqc_send_burst, ++ .get_frontend_algo = m88ds3103_get_algo, ++ .tune = m88ds3103_tune, ++ ++ .set_property = m88ds3103_set_property, ++ .get_property = m88ds3103_get_property, ++ .set_frontend = m88ds3103_set_frontend, ++}; ++ ++MODULE_DESCRIPTION("DVB Frontend module for Montage DS3103/TS2022 hardware"); ++MODULE_AUTHOR("Max nibble"); ++MODULE_LICENSE("GPL"); +diff -uprN linux-3.2.10.orig/drivers/media/dvb/frontends/m88ds3103.h linux-3.2.10/drivers/media/dvb/frontends/m88ds3103.h +--- linux-3.2.10.orig/drivers/media/dvb/frontends/m88ds3103.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.2.10/drivers/media/dvb/frontends/m88ds3103.h 2012-03-16 10:55:57.000000000 +0100 +@@ -0,0 +1,54 @@ ++/* ++ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver ++ Copyright (C) 2011 Max nibble ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program 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 this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef M88DS3103_H ++#define M88DS3103_H ++ ++#include ++ ++struct m88ds3103_config { ++ /* the demodulator's i2c address */ ++ u8 demod_address; ++ u8 ci_mode; ++ u8 pin_ctrl; ++ u8 ts_mode; /* 0: Parallel, 1: Serial */ ++ ++ /* Set device param to start dma */ ++ int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); ++ /* Start to transfer data */ ++ int (*start_ctrl)(struct dvb_frontend *fe); ++ /* Set LNB voltage */ ++ int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); ++}; ++ ++#if defined(CONFIG_DVB_M88DS3103) || \ ++ (defined(CONFIG_DVB_M88DS3103_MODULE) && defined(MODULE)) ++extern struct dvb_frontend *m88ds3103_attach( ++ const struct m88ds3103_config *config, ++ struct i2c_adapter *i2c); ++#else ++static inline struct dvb_frontend *m88ds3103_attach( ++ const struct m88ds3103_config *config, ++ struct i2c_adapter *i2c) ++{ ++ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); ++ return NULL; ++} ++#endif /* CONFIG_DVB_M88DS3103 */ ++#endif /* M88DS3103_H */ +diff -uprN linux-3.2.10.orig/drivers/media/dvb/frontends/Makefile linux-3.2.10/drivers/media/dvb/frontends/Makefile +--- linux-3.2.10.orig/drivers/media/dvb/frontends/Makefile 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/dvb/frontends/Makefile 2012-03-16 10:55:57.000000000 +0100 +@@ -95,4 +95,5 @@ obj-$(CONFIG_DVB_TDA18271C2DD) += tda182 + obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o + obj-$(CONFIG_DVB_A8293) += a8293.o + obj-$(CONFIG_DVB_TDA10071) += tda10071.o ++obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o + +diff -uprN linux-3.2.10.orig/drivers/media/rc/keymaps/Makefile linux-3.2.10/drivers/media/rc/keymaps/Makefile +--- linux-3.2.10.orig/drivers/media/rc/keymaps/Makefile 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/rc/keymaps/Makefile 2012-03-16 10:56:16.000000000 +0100 +@@ -26,6 +26,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t + rc-dm1105-nec.o \ + rc-dntv-live-dvb-t.o \ + rc-dntv-live-dvbt-pro.o \ ++ rc-dvbsky.o \ + rc-em-terratec.o \ + rc-encore-enltv2.o \ + rc-encore-enltv.o \ +diff -uprN linux-3.2.10.orig/drivers/media/rc/keymaps/rc-dvbsky.c linux-3.2.10/drivers/media/rc/keymaps/rc-dvbsky.c +--- linux-3.2.10.orig/drivers/media/rc/keymaps/rc-dvbsky.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.2.10/drivers/media/rc/keymaps/rc-dvbsky.c 2012-03-16 11:57:45.000000000 +0100 +@@ -0,0 +1,80 @@ ++/* rc-dvbsky.c - Keytable for Dvbsky Remote Controllers ++ * ++ * keymap imported from ir-keymaps.c ++ * ++ * ++ * Copyright (c) 2010-2011 by Mauro Carvalho Chehab ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++ ++/* ++ * This table contains the complete RC5 code, instead of just the data part ++ */ ++ ++static struct rc_map_table rc5_dvbsky[] = { ++ { 0x0000, KEY_0 }, ++ { 0x0001, KEY_1 }, ++ { 0x0002, KEY_2 }, ++ { 0x0003, KEY_3 }, ++ { 0x0004, KEY_4 }, ++ { 0x0005, KEY_5 }, ++ { 0x0006, KEY_6 }, ++ { 0x0007, KEY_7 }, ++ { 0x0008, KEY_8 }, ++ { 0x0009, KEY_9 }, ++ { 0x000a, KEY_MUTE }, ++ { 0x000d, KEY_OK }, ++ { 0x000b, KEY_STOP }, ++ { 0x000c, KEY_EXIT }, ++ { 0x000e, KEY_CAMERA }, /*Snap shot*/ ++ { 0x000f, KEY_SUBTITLE }, /*PIP*/ ++ { 0x0010, KEY_VOLUMEUP }, ++ { 0x0011, KEY_VOLUMEDOWN }, ++ { 0x0012, KEY_FAVORITES }, ++ { 0x0013, KEY_LIST }, /*Info*/ ++ { 0x0016, KEY_PAUSE }, ++ { 0x0017, KEY_PLAY }, ++ { 0x001f, KEY_RECORD }, ++ { 0x0020, KEY_CHANNELDOWN }, ++ { 0x0021, KEY_CHANNELUP }, ++ { 0x0025, KEY_POWER2 }, ++ { 0x0026, KEY_REWIND }, ++ { 0x0027, KEY_FASTFORWARD }, ++ { 0x0029, KEY_LAST }, ++ { 0x002b, KEY_MENU }, ++ { 0x002c, KEY_EPG }, ++ { 0x002d, KEY_ZOOM }, ++}; ++ ++static struct rc_map_list rc5_dvbsky_map = { ++ .map = { ++ .scan = rc5_dvbsky, ++ .size = ARRAY_SIZE(rc5_dvbsky), ++ .rc_type = RC_TYPE_RC5, ++ .name = RC_MAP_DVBSKY, ++ } ++}; ++ ++static int __init init_rc_map_rc5_dvbsky(void) ++{ ++ return rc_map_register(&rc5_dvbsky_map); ++} ++ ++static void __exit exit_rc_map_rc5_dvbsky(void) ++{ ++ rc_map_unregister(&rc5_dvbsky_map); ++} ++ ++module_init(init_rc_map_rc5_dvbsky) ++module_exit(exit_rc_map_rc5_dvbsky) ++ ++/* outcommented cause build error ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Mauro Carvalho Chehab "); ++*/ +diff -uprN linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-cards.c linux-3.2.10/drivers/media/video/cx23885/cx23885-cards.c +--- linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-cards.c 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx23885/cx23885-cards.c 2012-03-16 10:55:17.000000000 +0100 +@@ -437,7 +437,21 @@ struct cx23885_board cx23885_boards[] = + .amux = CX25840_AUDIO7, + .gpio0 = 0, + } }, ++ }, ++ [CX23885_BOARD_BST_PS8512] = { ++ .name = "Bestunar PS8512", ++ .portb = CX23885_MPEG_DVB, ++ }, ++ [CX23885_BOARD_DVBSKY_S950] = { ++ .name = "DVBSKY S950", ++ .portb = CX23885_MPEG_DVB, + }, ++ [CX23885_BOARD_DVBSKY_S952] = { ++ .name = "DVBSKY S952", ++ .portb = CX23885_MPEG_DVB, ++ .portc = CX23885_MPEG_DVB, ++ }, ++ + }; + const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); + +@@ -637,6 +651,18 @@ struct cx23885_subid cx23885_subids[] = + .subvendor = 0x1b55, + .subdevice = 0xe2e4, + .card = CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF, ++ }, { ++ .subvendor = 0x14f1, ++ .subdevice = 0x8512, ++ .card = CX23885_BOARD_BST_PS8512, ++ }, { ++ .subvendor = 0x4254, ++ .subdevice = 0x0950, ++ .card = CX23885_BOARD_DVBSKY_S950, ++ }, { ++ .subvendor = 0x4254, ++ .subdevice = 0x0952, ++ .card = CX23885_BOARD_DVBSKY_S952, + }, + }; + const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); +@@ -1147,9 +1173,57 @@ void cx23885_gpio_setup(struct cx23885_d + /* enable irq */ + cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ + break; ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_BST_PS8512: ++ cx23885_gpio_enable(dev, GPIO_2, 1); ++ cx23885_gpio_clear(dev, GPIO_2); ++ msleep(100); ++ cx23885_gpio_set(dev, GPIO_2); ++ break; ++ case CX23885_BOARD_DVBSKY_S952: ++ cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */ ++ ++ cx23885_gpio_enable(dev, GPIO_2, 1); ++ cx23885_gpio_enable(dev, GPIO_11, 1); ++ ++ cx23885_gpio_clear(dev, GPIO_2); ++ cx23885_gpio_clear(dev, GPIO_11); ++ msleep(100); ++ cx23885_gpio_set(dev, GPIO_2); ++ cx23885_gpio_set(dev, GPIO_11); ++ ++ break; + } + } + ++static int cx23885_ir_patch(struct i2c_adapter *i2c, u8 reg, u8 mask) ++{ ++ struct i2c_msg msgs[2]; ++ u8 tx_buf[2], rx_buf[1]; ++ /* Write register address */ ++ tx_buf[0] = reg; ++ msgs[0].addr = 0x4c; ++ msgs[0].flags = 0; ++ msgs[0].len = 1; ++ msgs[0].buf = (char *) tx_buf; ++ /* Read data from register */ ++ msgs[1].addr = 0x4c; ++ msgs[1].flags = I2C_M_RD; ++ msgs[1].len = 1; ++ msgs[1].buf = (char *) rx_buf; ++ ++ i2c_transfer(i2c, msgs, 2); ++ ++ tx_buf[0] = reg; ++ tx_buf[1] = rx_buf[0] | mask; ++ msgs[0].addr = 0x4c; ++ msgs[0].flags = 0; ++ msgs[0].len = 2; ++ msgs[0].buf = (char *) tx_buf; ++ ++ return i2c_transfer(i2c, msgs, 1); ++} ++ + int cx23885_ir_init(struct cx23885_dev *dev) + { + static struct v4l2_subdev_io_pin_config ir_rxtx_pin_cfg[] = { +@@ -1181,7 +1255,7 @@ int cx23885_ir_init(struct cx23885_dev * + const size_t ir_rx_pin_cfg_count = ARRAY_SIZE(ir_rx_pin_cfg); + + struct v4l2_subdev_ir_parameters params; +- int ret = 0; ++ int ret = 0; + switch (dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1500: + case CX23885_BOARD_HAUPPAUGE_HVR1500Q: +@@ -1232,6 +1306,20 @@ int cx23885_ir_init(struct cx23885_dev * + v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, + ir_rx_pin_cfg_count, ir_rx_pin_cfg); + break; ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: ++ dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); ++ if (dev->sd_ir == NULL) { ++ ret = -ENODEV; ++ break; ++ } ++ v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, ++ ir_rx_pin_cfg_count, ir_rx_pin_cfg); ++ ++ cx23885_ir_patch(&(dev->i2c_bus[2].i2c_adap),0x1f,0x80); ++ cx23885_ir_patch(&(dev->i2c_bus[2].i2c_adap),0x23,0x80); ++ break; + case CX23885_BOARD_HAUPPAUGE_HVR1250: + if (!enable_885_ir) + break; +@@ -1263,6 +1351,9 @@ void cx23885_ir_fini(struct cx23885_dev + break; + case CX23885_BOARD_TEVII_S470: + case CX23885_BOARD_HAUPPAUGE_HVR1250: ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: + cx23885_irq_remove(dev, PCI_MSK_AV_CORE); + /* sd_ir is a duplicate pointer to the AV Core, just clear it */ + dev->sd_ir = NULL; +@@ -1306,6 +1397,9 @@ void cx23885_ir_pci_int_enable(struct cx + break; + case CX23885_BOARD_TEVII_S470: + case CX23885_BOARD_HAUPPAUGE_HVR1250: ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: + if (dev->sd_ir) + cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); + break; +@@ -1388,6 +1482,8 @@ void cx23885_card_setup(struct cx23885_d + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: + case CX23885_BOARD_TEVII_S470: + case CX23885_BOARD_DVBWORLD_2005: + ts1->gen_ctrl_val = 0x5; /* Parallel */ +@@ -1417,6 +1513,14 @@ void cx23885_card_setup(struct cx23885_d + ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; ++ case CX23885_BOARD_DVBSKY_S952: ++ ts1->gen_ctrl_val = 0x5; /* Parallel */ ++ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ++ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; ++ ts2->gen_ctrl_val = 0xe; /* Serial bus + punctured clock */ ++ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ++ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; ++ break; + case CX23885_BOARD_HAUPPAUGE_HVR1250: + case CX23885_BOARD_HAUPPAUGE_HVR1500: + case CX23885_BOARD_HAUPPAUGE_HVR1500Q: +@@ -1468,6 +1572,9 @@ void cx23885_card_setup(struct cx23885_d + case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: + case CX23885_BOARD_HAUPPAUGE_HVR1500: + case CX23885_BOARD_MPX885: ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: + dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, + &dev->i2c_bus[2].i2c_adap, + "cx25840", 0x88 >> 1, NULL); +diff -uprN linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-dvb.c linux-3.2.10/drivers/media/video/cx23885/cx23885-dvb.c +--- linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-dvb.c 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx23885/cx23885-dvb.c 2012-03-16 10:55:17.000000000 +0100 +@@ -51,6 +51,7 @@ + #include "stv6110.h" + #include "lnbh24.h" + #include "cx24116.h" ++#include "m88ds3103.h" + #include "cimax2.h" + #include "lgs8gxx.h" + #include "netup-eeprom.h" +@@ -479,6 +480,30 @@ static struct xc5000_config mygica_x8506 + .if_khz = 5380, + }; + ++/* bestunar single dvb-s2 */ ++static struct m88ds3103_config bst_ds3103_config = { ++ .demod_address = 0x68, ++ .ci_mode = 0, ++ .pin_ctrl = 0x82, ++ .ts_mode = 0, ++ .set_voltage = bst_set_voltage, ++}; ++/* DVBSKY dual dvb-s2 */ ++static struct m88ds3103_config dvbsky_ds3103_config_pri = { ++ .demod_address = 0x68, ++ .ci_mode = 0, ++ .pin_ctrl = 0x82, ++ .ts_mode = 0, ++ .set_voltage = bst_set_voltage, ++}; ++static struct m88ds3103_config dvbsky_ds3103_config_sec = { ++ .demod_address = 0x68, ++ .ci_mode = 0, ++ .pin_ctrl = 0x82, ++ .ts_mode = 1, ++ .set_voltage = dvbsky_set_voltage_sec, ++}; ++ + static int cx23885_dvb_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *param) + { +@@ -1123,6 +1148,32 @@ static int dvb_register(struct cx23885_t + goto frontend_detach; + } + break; ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ i2c_bus = &dev->i2c_bus[1]; ++ fe0->dvb.frontend = dvb_attach(m88ds3103_attach, ++ &bst_ds3103_config, ++ &i2c_bus->i2c_adap); ++ break; ++ ++ case CX23885_BOARD_DVBSKY_S952: ++ switch (port->nr) { ++ /* port B */ ++ case 1: ++ i2c_bus = &dev->i2c_bus[1]; ++ fe0->dvb.frontend = dvb_attach(m88ds3103_attach, ++ &dvbsky_ds3103_config_pri, ++ &i2c_bus->i2c_adap); ++ break; ++ /* port C */ ++ case 2: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(m88ds3103_attach, ++ &dvbsky_ds3103_config_sec, ++ &i2c_bus->i2c_adap); ++ break; ++ } ++ break; + default: + printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " + " isn't supported yet\n", +diff -uprN linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-dvb.c.orig linux-3.2.10/drivers/media/video/cx23885/cx23885-dvb.c.orig +--- linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-dvb.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx23885/cx23885-dvb.c.orig 2012-03-16 10:14:15.000000000 +0100 +@@ -0,0 +1,1294 @@ ++/* ++ * Driver for the Conexant CX23885 PCIe bridge ++ * ++ * Copyright (c) 2006 Steven Toth ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program 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 this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "cx23885.h" ++#include ++ ++#include "dvb_ca_en50221.h" ++#include "s5h1409.h" ++#include "s5h1411.h" ++#include "mt2131.h" ++#include "tda8290.h" ++#include "tda18271.h" ++#include "lgdt330x.h" ++#include "xc4000.h" ++#include "xc5000.h" ++#include "max2165.h" ++#include "tda10048.h" ++#include "tuner-xc2028.h" ++#include "tuner-simple.h" ++#include "dib7000p.h" ++#include "dibx000_common.h" ++#include "zl10353.h" ++#include "stv0900.h" ++#include "stv0900_reg.h" ++#include "stv6110.h" ++#include "lnbh24.h" ++#include "cx24116.h" ++#include "cimax2.h" ++#include "lgs8gxx.h" ++#include "netup-eeprom.h" ++#include "netup-init.h" ++#include "lgdt3305.h" ++#include "atbm8830.h" ++#include "ds3000.h" ++#include "cx23885-f300.h" ++#include "altera-ci.h" ++#include "stv0367.h" ++ ++static unsigned int debug; ++ ++#define dprintk(level, fmt, arg...)\ ++ do { if (debug >= level)\ ++ printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ ++ } while (0) ++ ++/* ------------------------------------------------------------------ */ ++ ++static unsigned int alt_tuner; ++module_param(alt_tuner, int, 0644); ++MODULE_PARM_DESC(alt_tuner, "Enable alternate tuner configuration"); ++ ++DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); ++ ++/* ------------------------------------------------------------------ */ ++ ++static int dvb_buf_setup(struct videobuf_queue *q, ++ unsigned int *count, unsigned int *size) ++{ ++ struct cx23885_tsport *port = q->priv_data; ++ ++ port->ts_packet_size = 188 * 4; ++ port->ts_packet_count = 32; ++ ++ *size = port->ts_packet_size * port->ts_packet_count; ++ *count = 32; ++ return 0; ++} ++ ++static int dvb_buf_prepare(struct videobuf_queue *q, ++ struct videobuf_buffer *vb, enum v4l2_field field) ++{ ++ struct cx23885_tsport *port = q->priv_data; ++ return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field); ++} ++ ++static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) ++{ ++ struct cx23885_tsport *port = q->priv_data; ++ cx23885_buf_queue(port, (struct cx23885_buffer *)vb); ++} ++ ++static void dvb_buf_release(struct videobuf_queue *q, ++ struct videobuf_buffer *vb) ++{ ++ cx23885_free_buffer(q, (struct cx23885_buffer *)vb); ++} ++ ++static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open) ++{ ++ struct videobuf_dvb_frontends *f; ++ struct videobuf_dvb_frontend *fe; ++ ++ f = &port->frontends; ++ ++ if (f->gate <= 1) /* undefined or fe0 */ ++ fe = videobuf_dvb_get_frontend(f, 1); ++ else ++ fe = videobuf_dvb_get_frontend(f, f->gate); ++ ++ if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) ++ fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open); ++} ++ ++static struct videobuf_queue_ops dvb_qops = { ++ .buf_setup = dvb_buf_setup, ++ .buf_prepare = dvb_buf_prepare, ++ .buf_queue = dvb_buf_queue, ++ .buf_release = dvb_buf_release, ++}; ++ ++static struct s5h1409_config hauppauge_generic_config = { ++ .demod_address = 0x32 >> 1, ++ .output_mode = S5H1409_SERIAL_OUTPUT, ++ .gpio = S5H1409_GPIO_ON, ++ .qam_if = 44000, ++ .inversion = S5H1409_INVERSION_OFF, ++ .status_mode = S5H1409_DEMODLOCKING, ++ .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, ++}; ++ ++static struct tda10048_config hauppauge_hvr1200_config = { ++ .demod_address = 0x10 >> 1, ++ .output_mode = TDA10048_SERIAL_OUTPUT, ++ .fwbulkwritelen = TDA10048_BULKWRITE_200, ++ .inversion = TDA10048_INVERSION_ON, ++ .dtv6_if_freq_khz = TDA10048_IF_3300, ++ .dtv7_if_freq_khz = TDA10048_IF_3800, ++ .dtv8_if_freq_khz = TDA10048_IF_4300, ++ .clk_freq_khz = TDA10048_CLK_16000, ++}; ++ ++static struct tda10048_config hauppauge_hvr1210_config = { ++ .demod_address = 0x10 >> 1, ++ .output_mode = TDA10048_SERIAL_OUTPUT, ++ .fwbulkwritelen = TDA10048_BULKWRITE_200, ++ .inversion = TDA10048_INVERSION_ON, ++ .dtv6_if_freq_khz = TDA10048_IF_3300, ++ .dtv7_if_freq_khz = TDA10048_IF_3500, ++ .dtv8_if_freq_khz = TDA10048_IF_4000, ++ .clk_freq_khz = TDA10048_CLK_16000, ++}; ++ ++static struct s5h1409_config hauppauge_ezqam_config = { ++ .demod_address = 0x32 >> 1, ++ .output_mode = S5H1409_SERIAL_OUTPUT, ++ .gpio = S5H1409_GPIO_OFF, ++ .qam_if = 4000, ++ .inversion = S5H1409_INVERSION_ON, ++ .status_mode = S5H1409_DEMODLOCKING, ++ .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, ++}; ++ ++static struct s5h1409_config hauppauge_hvr1800lp_config = { ++ .demod_address = 0x32 >> 1, ++ .output_mode = S5H1409_SERIAL_OUTPUT, ++ .gpio = S5H1409_GPIO_OFF, ++ .qam_if = 44000, ++ .inversion = S5H1409_INVERSION_OFF, ++ .status_mode = S5H1409_DEMODLOCKING, ++ .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, ++}; ++ ++static struct s5h1409_config hauppauge_hvr1500_config = { ++ .demod_address = 0x32 >> 1, ++ .output_mode = S5H1409_SERIAL_OUTPUT, ++ .gpio = S5H1409_GPIO_OFF, ++ .inversion = S5H1409_INVERSION_OFF, ++ .status_mode = S5H1409_DEMODLOCKING, ++ .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, ++}; ++ ++static struct mt2131_config hauppauge_generic_tunerconfig = { ++ 0x61 ++}; ++ ++static struct lgdt330x_config fusionhdtv_5_express = { ++ .demod_address = 0x0e, ++ .demod_chip = LGDT3303, ++ .serial_mpeg = 0x40, ++}; ++ ++static struct s5h1409_config hauppauge_hvr1500q_config = { ++ .demod_address = 0x32 >> 1, ++ .output_mode = S5H1409_SERIAL_OUTPUT, ++ .gpio = S5H1409_GPIO_ON, ++ .qam_if = 44000, ++ .inversion = S5H1409_INVERSION_OFF, ++ .status_mode = S5H1409_DEMODLOCKING, ++ .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, ++}; ++ ++static struct s5h1409_config dvico_s5h1409_config = { ++ .demod_address = 0x32 >> 1, ++ .output_mode = S5H1409_SERIAL_OUTPUT, ++ .gpio = S5H1409_GPIO_ON, ++ .qam_if = 44000, ++ .inversion = S5H1409_INVERSION_OFF, ++ .status_mode = S5H1409_DEMODLOCKING, ++ .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, ++}; ++ ++static struct s5h1411_config dvico_s5h1411_config = { ++ .output_mode = S5H1411_SERIAL_OUTPUT, ++ .gpio = S5H1411_GPIO_ON, ++ .qam_if = S5H1411_IF_44000, ++ .vsb_if = S5H1411_IF_44000, ++ .inversion = S5H1411_INVERSION_OFF, ++ .status_mode = S5H1411_DEMODLOCKING, ++ .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, ++}; ++ ++static struct s5h1411_config hcw_s5h1411_config = { ++ .output_mode = S5H1411_SERIAL_OUTPUT, ++ .gpio = S5H1411_GPIO_OFF, ++ .vsb_if = S5H1411_IF_44000, ++ .qam_if = S5H1411_IF_4000, ++ .inversion = S5H1411_INVERSION_ON, ++ .status_mode = S5H1411_DEMODLOCKING, ++ .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, ++}; ++ ++static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { ++ .i2c_address = 0x61, ++ .if_khz = 5380, ++}; ++ ++static struct xc5000_config dvico_xc5000_tunerconfig = { ++ .i2c_address = 0x64, ++ .if_khz = 5380, ++}; ++ ++static struct tda829x_config tda829x_no_probe = { ++ .probe_tuner = TDA829X_DONT_PROBE, ++}; ++ ++static struct tda18271_std_map hauppauge_tda18271_std_map = { ++ .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, ++ .if_lvl = 6, .rfagc_top = 0x37 }, ++ .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, ++ .if_lvl = 6, .rfagc_top = 0x37 }, ++}; ++ ++static struct tda18271_std_map hauppauge_hvr1200_tda18271_std_map = { ++ .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4, ++ .if_lvl = 1, .rfagc_top = 0x37, }, ++ .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5, ++ .if_lvl = 1, .rfagc_top = 0x37, }, ++ .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6, ++ .if_lvl = 1, .rfagc_top = 0x37, }, ++}; ++ ++static struct tda18271_config hauppauge_tda18271_config = { ++ .std_map = &hauppauge_tda18271_std_map, ++ .gate = TDA18271_GATE_ANALOG, ++ .output_opt = TDA18271_OUTPUT_LT_OFF, ++}; ++ ++static struct tda18271_config hauppauge_hvr1200_tuner_config = { ++ .std_map = &hauppauge_hvr1200_tda18271_std_map, ++ .gate = TDA18271_GATE_ANALOG, ++ .output_opt = TDA18271_OUTPUT_LT_OFF, ++}; ++ ++static struct tda18271_config hauppauge_hvr1210_tuner_config = { ++ .gate = TDA18271_GATE_DIGITAL, ++ .output_opt = TDA18271_OUTPUT_LT_OFF, ++}; ++ ++static struct tda18271_std_map hauppauge_hvr127x_std_map = { ++ .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, ++ .if_lvl = 1, .rfagc_top = 0x58 }, ++ .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5, ++ .if_lvl = 1, .rfagc_top = 0x58 }, ++}; ++ ++static struct tda18271_config hauppauge_hvr127x_config = { ++ .std_map = &hauppauge_hvr127x_std_map, ++ .output_opt = TDA18271_OUTPUT_LT_OFF, ++}; ++ ++static struct lgdt3305_config hauppauge_lgdt3305_config = { ++ .i2c_addr = 0x0e, ++ .mpeg_mode = LGDT3305_MPEG_SERIAL, ++ .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE, ++ .tpvalid_polarity = LGDT3305_TP_VALID_HIGH, ++ .deny_i2c_rptr = 1, ++ .spectral_inversion = 1, ++ .qam_if_khz = 4000, ++ .vsb_if_khz = 3250, ++}; ++ ++static struct dibx000_agc_config xc3028_agc_config = { ++ BAND_VHF | BAND_UHF, /* band_caps */ ++ ++ /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0, ++ * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, ++ * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, ++ * P_agc_nb_est=2, P_agc_write=0 ++ */ ++ (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | ++ (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */ ++ ++ 712, /* inv_gain */ ++ 21, /* time_stabiliz */ ++ ++ 0, /* alpha_level */ ++ 118, /* thlock */ ++ ++ 0, /* wbd_inv */ ++ 2867, /* wbd_ref */ ++ 0, /* wbd_sel */ ++ 2, /* wbd_alpha */ ++ ++ 0, /* agc1_max */ ++ 0, /* agc1_min */ ++ 39718, /* agc2_max */ ++ 9930, /* agc2_min */ ++ 0, /* agc1_pt1 */ ++ 0, /* agc1_pt2 */ ++ 0, /* agc1_pt3 */ ++ 0, /* agc1_slope1 */ ++ 0, /* agc1_slope2 */ ++ 0, /* agc2_pt1 */ ++ 128, /* agc2_pt2 */ ++ 29, /* agc2_slope1 */ ++ 29, /* agc2_slope2 */ ++ ++ 17, /* alpha_mant */ ++ 27, /* alpha_exp */ ++ 23, /* beta_mant */ ++ 51, /* beta_exp */ ++ ++ 1, /* perform_agc_softsplit */ ++}; ++ ++/* PLL Configuration for COFDM BW_MHz = 8.000000 ++ * With external clock = 30.000000 */ ++static struct dibx000_bandwidth_config xc3028_bw_config = { ++ 60000, /* internal */ ++ 30000, /* sampling */ ++ 1, /* pll_cfg: prediv */ ++ 8, /* pll_cfg: ratio */ ++ 3, /* pll_cfg: range */ ++ 1, /* pll_cfg: reset */ ++ 0, /* pll_cfg: bypass */ ++ 0, /* misc: refdiv */ ++ 0, /* misc: bypclk_div */ ++ 1, /* misc: IO_CLK_en_core */ ++ 1, /* misc: ADClkSrc */ ++ 0, /* misc: modulo */ ++ (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */ ++ (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */ ++ 20452225, /* timf */ ++ 30000000 /* xtal_hz */ ++}; ++ ++static struct dib7000p_config hauppauge_hvr1400_dib7000_config = { ++ .output_mpeg2_in_188_bytes = 1, ++ .hostbus_diversity = 1, ++ .tuner_is_baseband = 0, ++ .update_lna = NULL, ++ ++ .agc_config_count = 1, ++ .agc = &xc3028_agc_config, ++ .bw = &xc3028_bw_config, ++ ++ .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, ++ .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, ++ .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, ++ ++ .pwm_freq_div = 0, ++ .agc_control = NULL, ++ .spur_protect = 0, ++ ++ .output_mode = OUTMODE_MPEG2_SERIAL, ++}; ++ ++static struct zl10353_config dvico_fusionhdtv_xc3028 = { ++ .demod_address = 0x0f, ++ .if2 = 45600, ++ .no_tuner = 1, ++ .disable_i2c_gate_ctrl = 1, ++}; ++ ++static struct stv0900_reg stv0900_ts_regs[] = { ++ { R0900_TSGENERAL, 0x00 }, ++ { R0900_P1_TSSPEED, 0x40 }, ++ { R0900_P2_TSSPEED, 0x40 }, ++ { R0900_P1_TSCFGM, 0xc0 }, ++ { R0900_P2_TSCFGM, 0xc0 }, ++ { R0900_P1_TSCFGH, 0xe0 }, ++ { R0900_P2_TSCFGH, 0xe0 }, ++ { R0900_P1_TSCFGL, 0x20 }, ++ { R0900_P2_TSCFGL, 0x20 }, ++ { 0xffff, 0xff }, /* terminate */ ++}; ++ ++static struct stv0900_config netup_stv0900_config = { ++ .demod_address = 0x68, ++ .demod_mode = 1, /* dual */ ++ .xtal = 8000000, ++ .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ ++ .diseqc_mode = 2,/* 2/3 PWM */ ++ .ts_config_regs = stv0900_ts_regs, ++ .tun1_maddress = 0,/* 0x60 */ ++ .tun2_maddress = 3,/* 0x63 */ ++ .tun1_adc = 1,/* 1 Vpp */ ++ .tun2_adc = 1,/* 1 Vpp */ ++}; ++ ++static struct stv6110_config netup_stv6110_tunerconfig_a = { ++ .i2c_address = 0x60, ++ .mclk = 16000000, ++ .clk_div = 1, ++ .gain = 8, /* +16 dB - maximum gain */ ++}; ++ ++static struct stv6110_config netup_stv6110_tunerconfig_b = { ++ .i2c_address = 0x63, ++ .mclk = 16000000, ++ .clk_div = 1, ++ .gain = 8, /* +16 dB - maximum gain */ ++}; ++ ++static struct cx24116_config tbs_cx24116_config = { ++ .demod_address = 0x55, ++}; ++ ++static struct ds3000_config tevii_ds3000_config = { ++ .demod_address = 0x68, ++}; ++ ++static struct cx24116_config dvbworld_cx24116_config = { ++ .demod_address = 0x05, ++}; ++ ++static struct lgs8gxx_config mygica_x8506_lgs8gl5_config = { ++ .prod = LGS8GXX_PROD_LGS8GL5, ++ .demod_address = 0x19, ++ .serial_ts = 0, ++ .ts_clk_pol = 1, ++ .ts_clk_gated = 1, ++ .if_clk_freq = 30400, /* 30.4 MHz */ ++ .if_freq = 5380, /* 5.38 MHz */ ++ .if_neg_center = 1, ++ .ext_adc = 0, ++ .adc_signed = 0, ++ .if_neg_edge = 0, ++}; ++ ++static struct xc5000_config mygica_x8506_xc5000_config = { ++ .i2c_address = 0x61, ++ .if_khz = 5380, ++}; ++ ++static int cx23885_dvb_set_frontend(struct dvb_frontend *fe, ++ struct dvb_frontend_parameters *param) ++{ ++ struct cx23885_tsport *port = fe->dvb->priv; ++ struct cx23885_dev *dev = port->dev; ++ ++ switch (dev->board) { ++ case CX23885_BOARD_HAUPPAUGE_HVR1275: ++ switch (param->u.vsb.modulation) { ++ case VSB_8: ++ cx23885_gpio_clear(dev, GPIO_5); ++ break; ++ case QAM_64: ++ case QAM_256: ++ default: ++ cx23885_gpio_set(dev, GPIO_5); ++ break; ++ } ++ break; ++ case CX23885_BOARD_MYGICA_X8506: ++ case CX23885_BOARD_MAGICPRO_PROHDTVE2: ++ /* Select Digital TV */ ++ cx23885_gpio_set(dev, GPIO_0); ++ break; ++ } ++ return 0; ++} ++ ++static int cx23885_dvb_fe_ioctl_override(struct dvb_frontend *fe, ++ unsigned int cmd, void *parg, ++ unsigned int stage) ++{ ++ int err = 0; ++ ++ switch (stage) { ++ case DVB_FE_IOCTL_PRE: ++ ++ switch (cmd) { ++ case FE_SET_FRONTEND: ++ err = cx23885_dvb_set_frontend(fe, ++ (struct dvb_frontend_parameters *) parg); ++ break; ++ } ++ break; ++ ++ case DVB_FE_IOCTL_POST: ++ /* no post-ioctl handling required */ ++ break; ++ } ++ return err; ++}; ++ ++ ++static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = { ++ .prod = LGS8GXX_PROD_LGS8G75, ++ .demod_address = 0x19, ++ .serial_ts = 0, ++ .ts_clk_pol = 1, ++ .ts_clk_gated = 1, ++ .if_clk_freq = 30400, /* 30.4 MHz */ ++ .if_freq = 6500, /* 6.50 MHz */ ++ .if_neg_center = 1, ++ .ext_adc = 0, ++ .adc_signed = 1, ++ .adc_vpp = 2, /* 1.6 Vpp */ ++ .if_neg_edge = 1, ++}; ++ ++static struct xc5000_config magicpro_prohdtve2_xc5000_config = { ++ .i2c_address = 0x61, ++ .if_khz = 6500, ++}; ++ ++static struct atbm8830_config mygica_x8558pro_atbm8830_cfg1 = { ++ .prod = ATBM8830_PROD_8830, ++ .demod_address = 0x44, ++ .serial_ts = 0, ++ .ts_sampling_edge = 1, ++ .ts_clk_gated = 0, ++ .osc_clk_freq = 30400, /* in kHz */ ++ .if_freq = 0, /* zero IF */ ++ .zif_swap_iq = 1, ++ .agc_min = 0x2E, ++ .agc_max = 0xFF, ++ .agc_hold_loop = 0, ++}; ++ ++static struct max2165_config mygic_x8558pro_max2165_cfg1 = { ++ .i2c_address = 0x60, ++ .osc_clk = 20 ++}; ++ ++static struct atbm8830_config mygica_x8558pro_atbm8830_cfg2 = { ++ .prod = ATBM8830_PROD_8830, ++ .demod_address = 0x44, ++ .serial_ts = 1, ++ .ts_sampling_edge = 1, ++ .ts_clk_gated = 0, ++ .osc_clk_freq = 30400, /* in kHz */ ++ .if_freq = 0, /* zero IF */ ++ .zif_swap_iq = 1, ++ .agc_min = 0x2E, ++ .agc_max = 0xFF, ++ .agc_hold_loop = 0, ++}; ++ ++static struct max2165_config mygic_x8558pro_max2165_cfg2 = { ++ .i2c_address = 0x60, ++ .osc_clk = 20 ++}; ++static struct stv0367_config netup_stv0367_config[] = { ++ { ++ .demod_address = 0x1c, ++ .xtal = 27000000, ++ .if_khz = 4500, ++ .if_iq_mode = 0, ++ .ts_mode = 1, ++ .clk_pol = 0, ++ }, { ++ .demod_address = 0x1d, ++ .xtal = 27000000, ++ .if_khz = 4500, ++ .if_iq_mode = 0, ++ .ts_mode = 1, ++ .clk_pol = 0, ++ }, ++}; ++ ++static struct xc5000_config netup_xc5000_config[] = { ++ { ++ .i2c_address = 0x61, ++ .if_khz = 4500, ++ }, { ++ .i2c_address = 0x64, ++ .if_khz = 4500, ++ }, ++}; ++ ++int netup_altera_fpga_rw(void *device, int flag, int data, int read) ++{ ++ struct cx23885_dev *dev = (struct cx23885_dev *)device; ++ unsigned long timeout = jiffies + msecs_to_jiffies(1); ++ uint32_t mem = 0; ++ ++ mem = cx_read(MC417_RWD); ++ if (read) ++ cx_set(MC417_OEN, ALT_DATA); ++ else { ++ cx_clear(MC417_OEN, ALT_DATA);/* D0-D7 out */ ++ mem &= ~ALT_DATA; ++ mem |= (data & ALT_DATA); ++ } ++ ++ if (flag) ++ mem |= ALT_AD_RG; ++ else ++ mem &= ~ALT_AD_RG; ++ ++ mem &= ~ALT_CS; ++ if (read) ++ mem = (mem & ~ALT_RD) | ALT_WR; ++ else ++ mem = (mem & ~ALT_WR) | ALT_RD; ++ ++ cx_write(MC417_RWD, mem); /* start RW cycle */ ++ ++ for (;;) { ++ mem = cx_read(MC417_RWD); ++ if ((mem & ALT_RDY) == 0) ++ break; ++ if (time_after(jiffies, timeout)) ++ break; ++ udelay(1); ++ } ++ ++ cx_set(MC417_RWD, ALT_RD | ALT_WR | ALT_CS); ++ if (read) ++ return mem & ALT_DATA; ++ ++ return 0; ++}; ++ ++static int dvb_register(struct cx23885_tsport *port) ++{ ++ struct cx23885_dev *dev = port->dev; ++ struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; ++ struct videobuf_dvb_frontend *fe0, *fe1 = NULL; ++ int mfe_shared = 0; /* bus not shared by default */ ++ int ret; ++ ++ /* Get the first frontend */ ++ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); ++ if (!fe0) ++ return -EINVAL; ++ ++ /* init struct videobuf_dvb */ ++ fe0->dvb.name = dev->name; ++ ++ /* multi-frontend gate control is undefined or defaults to fe0 */ ++ port->frontends.gate = 0; ++ ++ /* Sets the gate control callback to be used by i2c command calls */ ++ port->gate_ctrl = cx23885_dvb_gate_ctrl; ++ ++ /* init frontend */ ++ switch (dev->board) { ++ case CX23885_BOARD_HAUPPAUGE_HVR1250: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(s5h1409_attach, ++ &hauppauge_generic_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(mt2131_attach, fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ &hauppauge_generic_tunerconfig, 0); ++ } ++ break; ++ case CX23885_BOARD_HAUPPAUGE_HVR1270: ++ case CX23885_BOARD_HAUPPAUGE_HVR1275: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(lgdt3305_attach, ++ &hauppauge_lgdt3305_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(tda18271_attach, fe0->dvb.frontend, ++ 0x60, &dev->i2c_bus[1].i2c_adap, ++ &hauppauge_hvr127x_config); ++ } ++ break; ++ case CX23885_BOARD_HAUPPAUGE_HVR1255: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(s5h1411_attach, ++ &hcw_s5h1411_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(tda18271_attach, fe0->dvb.frontend, ++ 0x60, &dev->i2c_bus[1].i2c_adap, ++ &hauppauge_tda18271_config); ++ } ++ break; ++ case CX23885_BOARD_HAUPPAUGE_HVR1800: ++ i2c_bus = &dev->i2c_bus[0]; ++ switch (alt_tuner) { ++ case 1: ++ fe0->dvb.frontend = ++ dvb_attach(s5h1409_attach, ++ &hauppauge_ezqam_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(tda829x_attach, fe0->dvb.frontend, ++ &dev->i2c_bus[1].i2c_adap, 0x42, ++ &tda829x_no_probe); ++ dvb_attach(tda18271_attach, fe0->dvb.frontend, ++ 0x60, &dev->i2c_bus[1].i2c_adap, ++ &hauppauge_tda18271_config); ++ } ++ break; ++ case 0: ++ default: ++ fe0->dvb.frontend = ++ dvb_attach(s5h1409_attach, ++ &hauppauge_generic_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) ++ dvb_attach(mt2131_attach, fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ &hauppauge_generic_tunerconfig, 0); ++ break; ++ } ++ break; ++ case CX23885_BOARD_HAUPPAUGE_HVR1800lp: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(s5h1409_attach, ++ &hauppauge_hvr1800lp_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(mt2131_attach, fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ &hauppauge_generic_tunerconfig, 0); ++ } ++ break; ++ case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(lgdt330x_attach, ++ &fusionhdtv_5_express, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(simple_tuner_attach, fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, 0x61, ++ TUNER_LG_TDVS_H06XF); ++ } ++ break; ++ case CX23885_BOARD_HAUPPAUGE_HVR1500Q: ++ i2c_bus = &dev->i2c_bus[1]; ++ fe0->dvb.frontend = dvb_attach(s5h1409_attach, ++ &hauppauge_hvr1500q_config, ++ &dev->i2c_bus[0].i2c_adap); ++ if (fe0->dvb.frontend != NULL) ++ dvb_attach(xc5000_attach, fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ &hauppauge_hvr1500q_tunerconfig); ++ break; ++ case CX23885_BOARD_HAUPPAUGE_HVR1500: ++ i2c_bus = &dev->i2c_bus[1]; ++ fe0->dvb.frontend = dvb_attach(s5h1409_attach, ++ &hauppauge_hvr1500_config, ++ &dev->i2c_bus[0].i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ struct dvb_frontend *fe; ++ struct xc2028_config cfg = { ++ .i2c_adap = &i2c_bus->i2c_adap, ++ .i2c_addr = 0x61, ++ }; ++ static struct xc2028_ctrl ctl = { ++ .fname = XC2028_DEFAULT_FIRMWARE, ++ .max_len = 64, ++ .demod = XC3028_FE_OREN538, ++ }; ++ ++ fe = dvb_attach(xc2028_attach, ++ fe0->dvb.frontend, &cfg); ++ if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) ++ fe->ops.tuner_ops.set_config(fe, &ctl); ++ } ++ break; ++ case CX23885_BOARD_HAUPPAUGE_HVR1200: ++ case CX23885_BOARD_HAUPPAUGE_HVR1700: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(tda10048_attach, ++ &hauppauge_hvr1200_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(tda829x_attach, fe0->dvb.frontend, ++ &dev->i2c_bus[1].i2c_adap, 0x42, ++ &tda829x_no_probe); ++ dvb_attach(tda18271_attach, fe0->dvb.frontend, ++ 0x60, &dev->i2c_bus[1].i2c_adap, ++ &hauppauge_hvr1200_tuner_config); ++ } ++ break; ++ case CX23885_BOARD_HAUPPAUGE_HVR1210: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(tda10048_attach, ++ &hauppauge_hvr1210_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(tda18271_attach, fe0->dvb.frontend, ++ 0x60, &dev->i2c_bus[1].i2c_adap, ++ &hauppauge_hvr1210_tuner_config); ++ } ++ break; ++ case CX23885_BOARD_HAUPPAUGE_HVR1400: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(dib7000p_attach, ++ &i2c_bus->i2c_adap, ++ 0x12, &hauppauge_hvr1400_dib7000_config); ++ if (fe0->dvb.frontend != NULL) { ++ struct dvb_frontend *fe; ++ struct xc2028_config cfg = { ++ .i2c_adap = &dev->i2c_bus[1].i2c_adap, ++ .i2c_addr = 0x64, ++ }; ++ static struct xc2028_ctrl ctl = { ++ .fname = XC3028L_DEFAULT_FIRMWARE, ++ .max_len = 64, ++ .demod = XC3028_FE_DIBCOM52, ++ /* This is true for all demods with ++ v36 firmware? */ ++ .type = XC2028_D2633, ++ }; ++ ++ fe = dvb_attach(xc2028_attach, ++ fe0->dvb.frontend, &cfg); ++ if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) ++ fe->ops.tuner_ops.set_config(fe, &ctl); ++ } ++ break; ++ case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: ++ i2c_bus = &dev->i2c_bus[port->nr - 1]; ++ ++ fe0->dvb.frontend = dvb_attach(s5h1409_attach, ++ &dvico_s5h1409_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend == NULL) ++ fe0->dvb.frontend = dvb_attach(s5h1411_attach, ++ &dvico_s5h1411_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) ++ dvb_attach(xc5000_attach, fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ &dvico_xc5000_tunerconfig); ++ break; ++ case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { ++ i2c_bus = &dev->i2c_bus[port->nr - 1]; ++ ++ fe0->dvb.frontend = dvb_attach(zl10353_attach, ++ &dvico_fusionhdtv_xc3028, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ struct dvb_frontend *fe; ++ struct xc2028_config cfg = { ++ .i2c_adap = &i2c_bus->i2c_adap, ++ .i2c_addr = 0x61, ++ }; ++ static struct xc2028_ctrl ctl = { ++ .fname = XC2028_DEFAULT_FIRMWARE, ++ .max_len = 64, ++ .demod = XC3028_FE_ZARLINK456, ++ }; ++ ++ fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, ++ &cfg); ++ if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) ++ fe->ops.tuner_ops.set_config(fe, &ctl); ++ } ++ break; ++ } ++ case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: ++ case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: ++ case CX23885_BOARD_COMPRO_VIDEOMATE_E800: ++ i2c_bus = &dev->i2c_bus[0]; ++ ++ fe0->dvb.frontend = dvb_attach(zl10353_attach, ++ &dvico_fusionhdtv_xc3028, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ struct dvb_frontend *fe; ++ struct xc2028_config cfg = { ++ .i2c_adap = &dev->i2c_bus[1].i2c_adap, ++ .i2c_addr = 0x61, ++ }; ++ static struct xc2028_ctrl ctl = { ++ .fname = XC2028_DEFAULT_FIRMWARE, ++ .max_len = 64, ++ .demod = XC3028_FE_ZARLINK456, ++ }; ++ ++ fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, ++ &cfg); ++ if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) ++ fe->ops.tuner_ops.set_config(fe, &ctl); ++ } ++ break; ++ case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: ++ i2c_bus = &dev->i2c_bus[0]; ++ ++ fe0->dvb.frontend = dvb_attach(zl10353_attach, ++ &dvico_fusionhdtv_xc3028, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ struct dvb_frontend *fe; ++ struct xc4000_config cfg = { ++ .i2c_address = 0x61, ++ .default_pm = 0, ++ .dvb_amplitude = 134, ++ .set_smoothedcvbs = 1, ++ .if_khz = 4560 ++ }; ++ ++ fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, ++ &dev->i2c_bus[1].i2c_adap, &cfg); ++ if (!fe) { ++ printk(KERN_ERR "%s/2: xc4000 attach failed\n", ++ dev->name); ++ goto frontend_detach; ++ } ++ } ++ break; ++ case CX23885_BOARD_TBS_6920: ++ i2c_bus = &dev->i2c_bus[1]; ++ ++ fe0->dvb.frontend = dvb_attach(cx24116_attach, ++ &tbs_cx24116_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) ++ fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; ++ ++ break; ++ case CX23885_BOARD_TEVII_S470: ++ i2c_bus = &dev->i2c_bus[1]; ++ ++ fe0->dvb.frontend = dvb_attach(ds3000_attach, ++ &tevii_ds3000_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) ++ fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; ++ ++ break; ++ case CX23885_BOARD_DVBWORLD_2005: ++ i2c_bus = &dev->i2c_bus[1]; ++ ++ fe0->dvb.frontend = dvb_attach(cx24116_attach, ++ &dvbworld_cx24116_config, ++ &i2c_bus->i2c_adap); ++ break; ++ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: ++ i2c_bus = &dev->i2c_bus[0]; ++ switch (port->nr) { ++ /* port B */ ++ case 1: ++ fe0->dvb.frontend = dvb_attach(stv0900_attach, ++ &netup_stv0900_config, ++ &i2c_bus->i2c_adap, 0); ++ if (fe0->dvb.frontend != NULL) { ++ if (dvb_attach(stv6110_attach, ++ fe0->dvb.frontend, ++ &netup_stv6110_tunerconfig_a, ++ &i2c_bus->i2c_adap)) { ++ if (!dvb_attach(lnbh24_attach, ++ fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ LNBH24_PCL | LNBH24_TTX, ++ LNBH24_TEN, 0x09)) ++ printk(KERN_ERR ++ "No LNBH24 found!\n"); ++ ++ } ++ } ++ break; ++ /* port C */ ++ case 2: ++ fe0->dvb.frontend = dvb_attach(stv0900_attach, ++ &netup_stv0900_config, ++ &i2c_bus->i2c_adap, 1); ++ if (fe0->dvb.frontend != NULL) { ++ if (dvb_attach(stv6110_attach, ++ fe0->dvb.frontend, ++ &netup_stv6110_tunerconfig_b, ++ &i2c_bus->i2c_adap)) { ++ if (!dvb_attach(lnbh24_attach, ++ fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ LNBH24_PCL | LNBH24_TTX, ++ LNBH24_TEN, 0x0a)) ++ printk(KERN_ERR ++ "No LNBH24 found!\n"); ++ ++ } ++ } ++ break; ++ } ++ break; ++ case CX23885_BOARD_MYGICA_X8506: ++ i2c_bus = &dev->i2c_bus[0]; ++ i2c_bus2 = &dev->i2c_bus[1]; ++ fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, ++ &mygica_x8506_lgs8gl5_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(xc5000_attach, ++ fe0->dvb.frontend, ++ &i2c_bus2->i2c_adap, ++ &mygica_x8506_xc5000_config); ++ } ++ break; ++ case CX23885_BOARD_MAGICPRO_PROHDTVE2: ++ i2c_bus = &dev->i2c_bus[0]; ++ i2c_bus2 = &dev->i2c_bus[1]; ++ fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, ++ &magicpro_prohdtve2_lgs8g75_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(xc5000_attach, ++ fe0->dvb.frontend, ++ &i2c_bus2->i2c_adap, ++ &magicpro_prohdtve2_xc5000_config); ++ } ++ break; ++ case CX23885_BOARD_HAUPPAUGE_HVR1850: ++ case CX23885_BOARD_HAUPPAUGE_HVR1290: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(s5h1411_attach, ++ &hcw_s5h1411_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) ++ dvb_attach(tda18271_attach, fe0->dvb.frontend, ++ 0x60, &dev->i2c_bus[0].i2c_adap, ++ &hauppauge_tda18271_config); ++ break; ++ case CX23885_BOARD_MYGICA_X8558PRO: ++ switch (port->nr) { ++ /* port B */ ++ case 1: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(atbm8830_attach, ++ &mygica_x8558pro_atbm8830_cfg1, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(max2165_attach, ++ fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ &mygic_x8558pro_max2165_cfg1); ++ } ++ break; ++ /* port C */ ++ case 2: ++ i2c_bus = &dev->i2c_bus[1]; ++ fe0->dvb.frontend = dvb_attach(atbm8830_attach, ++ &mygica_x8558pro_atbm8830_cfg2, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(max2165_attach, ++ fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ &mygic_x8558pro_max2165_cfg2); ++ } ++ break; ++ } ++ break; ++ case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: ++ i2c_bus = &dev->i2c_bus[0]; ++ mfe_shared = 1;/* MFE */ ++ port->frontends.gate = 0;/* not clear for me yet */ ++ /* ports B, C */ ++ /* MFE frontend 1 DVB-T */ ++ fe0->dvb.frontend = dvb_attach(stv0367ter_attach, ++ &netup_stv0367_config[port->nr - 1], ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ if (NULL == dvb_attach(xc5000_attach, ++ fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ &netup_xc5000_config[port->nr - 1])) ++ goto frontend_detach; ++ /* load xc5000 firmware */ ++ fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend); ++ } ++ /* MFE frontend 2 */ ++ fe1 = videobuf_dvb_get_frontend(&port->frontends, 2); ++ if (fe1 == NULL) ++ goto frontend_detach; ++ /* DVB-C init */ ++ fe1->dvb.frontend = dvb_attach(stv0367cab_attach, ++ &netup_stv0367_config[port->nr - 1], ++ &i2c_bus->i2c_adap); ++ if (fe1->dvb.frontend != NULL) { ++ fe1->dvb.frontend->id = 1; ++ if (NULL == dvb_attach(xc5000_attach, ++ fe1->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ &netup_xc5000_config[port->nr - 1])) ++ goto frontend_detach; ++ } ++ break; ++ default: ++ printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " ++ " isn't supported yet\n", ++ dev->name); ++ break; ++ } ++ ++ if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) { ++ printk(KERN_ERR "%s: frontend initialization failed\n", ++ dev->name); ++ goto frontend_detach; ++ } ++ ++ /* define general-purpose callback pointer */ ++ fe0->dvb.frontend->callback = cx23885_tuner_callback; ++ if (fe1) ++ fe1->dvb.frontend->callback = cx23885_tuner_callback; ++#if 0 ++ /* Ensure all frontends negotiate bus access */ ++ fe0->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl; ++ if (fe1) ++ fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl; ++#endif ++ ++ /* Put the analog decoder in standby to keep it quiet */ ++ call_all(dev, core, s_power, 0); ++ ++ if (fe0->dvb.frontend->ops.analog_ops.standby) ++ fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); ++ ++ /* register everything */ ++ ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, ++ &dev->pci->dev, adapter_nr, mfe_shared, ++ cx23885_dvb_fe_ioctl_override); ++ if (ret) ++ goto frontend_detach; ++ ++ /* init CI & MAC */ ++ switch (dev->board) { ++ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: { ++ static struct netup_card_info cinfo; ++ ++ netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); ++ memcpy(port->frontends.adapter.proposed_mac, ++ cinfo.port[port->nr - 1].mac, 6); ++ printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=%pM\n", ++ port->nr, port->frontends.adapter.proposed_mac); ++ ++ netup_ci_init(port); ++ break; ++ } ++ case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: { ++ struct altera_ci_config netup_ci_cfg = { ++ .dev = dev,/* magic number to identify*/ ++ .adapter = &port->frontends.adapter,/* for CI */ ++ .demux = &fe0->dvb.demux,/* for hw pid filter */ ++ .fpga_rw = netup_altera_fpga_rw, ++ }; ++ ++ altera_ci_init(&netup_ci_cfg, port->nr); ++ break; ++ } ++ case CX23885_BOARD_TEVII_S470: { ++ u8 eeprom[256]; /* 24C02 i2c eeprom */ ++ ++ if (port->nr != 1) ++ break; ++ ++ /* Read entire EEPROM */ ++ dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; ++ tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); ++ printk(KERN_INFO "TeVii S470 MAC= %pM\n", eeprom + 0xa0); ++ memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6); ++ break; ++ } ++ } ++ ++ return ret; ++ ++frontend_detach: ++ port->gate_ctrl = NULL; ++ videobuf_dvb_dealloc_frontends(&port->frontends); ++ return -EINVAL; ++} ++ ++int cx23885_dvb_register(struct cx23885_tsport *port) ++{ ++ ++ struct videobuf_dvb_frontend *fe0; ++ struct cx23885_dev *dev = port->dev; ++ int err, i; ++ ++ /* Here we need to allocate the correct number of frontends, ++ * as reflected in the cards struct. The reality is that currently ++ * no cx23885 boards support this - yet. But, if we don't modify this ++ * code then the second frontend would never be allocated (later) ++ * and fail with error before the attach in dvb_register(). ++ * Without these changes we risk an OOPS later. The changes here ++ * are for safety, and should provide a good foundation for the ++ * future addition of any multi-frontend cx23885 based boards. ++ */ ++ printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, ++ port->num_frontends); ++ ++ for (i = 1; i <= port->num_frontends; i++) { ++ if (videobuf_dvb_alloc_frontend( ++ &port->frontends, i) == NULL) { ++ printk(KERN_ERR "%s() failed to alloc\n", __func__); ++ return -ENOMEM; ++ } ++ ++ fe0 = videobuf_dvb_get_frontend(&port->frontends, i); ++ if (!fe0) ++ err = -EINVAL; ++ ++ dprintk(1, "%s\n", __func__); ++ dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n", ++ dev->board, ++ dev->name, ++ dev->pci_bus, ++ dev->pci_slot); ++ ++ err = -ENODEV; ++ ++ /* dvb stuff */ ++ /* We have to init the queue for each frontend on a port. */ ++ printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); ++ videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, ++ &dev->pci->dev, &port->slock, ++ V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, ++ sizeof(struct cx23885_buffer), port, NULL); ++ } ++ err = dvb_register(port); ++ if (err != 0) ++ printk(KERN_ERR "%s() dvb_register failed err = %d\n", ++ __func__, err); ++ ++ return err; ++} ++ ++int cx23885_dvb_unregister(struct cx23885_tsport *port) ++{ ++ struct videobuf_dvb_frontend *fe0; ++ ++ /* FIXME: in an error condition where the we have ++ * an expected number of frontends (attach problem) ++ * then this might not clean up correctly, if 1 ++ * is invalid. ++ * This comment only applies to future boards IF they ++ * implement MFE support. ++ */ ++ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); ++ if (fe0 && fe0->dvb.frontend) ++ videobuf_dvb_unregister_bus(&port->frontends); ++ ++ switch (port->dev->board) { ++ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: ++ netup_ci_exit(port); ++ break; ++ case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: ++ altera_ci_release(port->dev, port->nr); ++ break; ++ } ++ ++ port->gate_ctrl = NULL; ++ ++ return 0; ++} ++ +diff -uprN linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-f300.c linux-3.2.10/drivers/media/video/cx23885/cx23885-f300.c +--- linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-f300.c 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx23885/cx23885-f300.c 2012-03-16 10:55:17.000000000 +0100 +@@ -175,3 +175,59 @@ int f300_set_voltage(struct dvb_frontend + + return f300_xfer(fe, buf); + } ++ ++/* bst control */ ++int bst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ struct cx23885_tsport *port = fe->dvb->priv; ++ struct cx23885_dev *dev = port->dev; ++ ++ cx23885_gpio_enable(dev, GPIO_1, 1); ++ cx23885_gpio_enable(dev, GPIO_0, 1); ++ ++ switch (voltage) { ++ case SEC_VOLTAGE_13: ++ cx23885_gpio_set(dev, GPIO_1); ++ cx23885_gpio_clear(dev, GPIO_0); ++ break; ++ case SEC_VOLTAGE_18: ++ cx23885_gpio_set(dev, GPIO_1); ++ cx23885_gpio_set(dev, GPIO_0); ++ break; ++ case SEC_VOLTAGE_OFF: ++ cx23885_gpio_clear(dev, GPIO_1); ++ cx23885_gpio_clear(dev, GPIO_0); ++ break; ++ } ++ ++ ++ return 0; ++} ++ ++int dvbsky_set_voltage_sec(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ struct cx23885_tsport *port = fe->dvb->priv; ++ struct cx23885_dev *dev = port->dev; ++ ++ cx23885_gpio_enable(dev, GPIO_12, 1); ++ cx23885_gpio_enable(dev, GPIO_13, 1); ++ ++ switch (voltage) { ++ case SEC_VOLTAGE_13: ++ cx23885_gpio_set(dev, GPIO_13); ++ cx23885_gpio_clear(dev, GPIO_12); ++ break; ++ case SEC_VOLTAGE_18: ++ cx23885_gpio_set(dev, GPIO_13); ++ cx23885_gpio_set(dev, GPIO_12); ++ break; ++ case SEC_VOLTAGE_OFF: ++ cx23885_gpio_clear(dev, GPIO_13); ++ cx23885_gpio_clear(dev, GPIO_12); ++ break; ++ } ++ ++ ++ return 0; ++} ++ +diff -uprN linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-f300.h linux-3.2.10/drivers/media/video/cx23885/cx23885-f300.h +--- linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-f300.h 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx23885/cx23885-f300.h 2012-03-16 10:55:17.000000000 +0100 +@@ -1,2 +1,8 @@ ++extern int dvbsky_set_voltage_sec(struct dvb_frontend *fe, ++ fe_sec_voltage_t voltage); ++ ++extern int bst_set_voltage(struct dvb_frontend *fe, ++ fe_sec_voltage_t voltage); ++ + extern int f300_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage); +diff -uprN linux-3.2.10.orig/drivers/media/video/cx23885/cx23885.h linux-3.2.10/drivers/media/video/cx23885/cx23885.h +--- linux-3.2.10.orig/drivers/media/video/cx23885/cx23885.h 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx23885/cx23885.h 2012-03-16 10:55:17.000000000 +0100 +@@ -87,6 +87,9 @@ + #define CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF 30 + #define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000 31 + #define CX23885_BOARD_MPX885 32 ++#define CX23885_BOARD_BST_PS8512 (CX23885_BOARD_MPX885+1) ++#define CX23885_BOARD_DVBSKY_S952 (CX23885_BOARD_BST_PS8512+1) ++#define CX23885_BOARD_DVBSKY_S950 (CX23885_BOARD_DVBSKY_S952+1) + + #define GPIO_0 0x00000001 + #define GPIO_1 0x00000002 +diff -uprN linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-input.c linux-3.2.10/drivers/media/video/cx23885/cx23885-input.c +--- linux-3.2.10.orig/drivers/media/video/cx23885/cx23885-input.c 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx23885/cx23885-input.c 2012-03-16 10:55:17.000000000 +0100 +@@ -87,6 +87,9 @@ void cx23885_input_rx_work_handler(struc + case CX23885_BOARD_HAUPPAUGE_HVR1290: + case CX23885_BOARD_TEVII_S470: + case CX23885_BOARD_HAUPPAUGE_HVR1250: ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: + /* + * The only boards we handle right now. However other boards + * using the CX2388x integrated IR controller should be similar +@@ -138,6 +141,9 @@ static int cx23885_input_ir_start(struct + case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: + case CX23885_BOARD_HAUPPAUGE_HVR1250: ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: + /* + * The IR controller on this board only returns pulse widths. + * Any other mode setting will fail to set up the device. +@@ -279,6 +285,15 @@ int cx23885_input_init(struct cx23885_de + /* A guess at the remote */ + rc_map = RC_MAP_TEVII_NEC; + break; ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: ++ /* Integrated CX2388[58] IR controller */ ++ driver_type = RC_DRIVER_IR_RAW; ++ allowed_protos = RC_TYPE_ALL; ++ /* A guess at the remote */ ++ rc_map = RC_MAP_DVBSKY; ++ break; + default: + return -ENODEV; + } +diff -uprN linux-3.2.10.orig/drivers/media/video/cx23885/Kconfig linux-3.2.10/drivers/media/video/cx23885/Kconfig +--- linux-3.2.10.orig/drivers/media/video/cx23885/Kconfig 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx23885/Kconfig 2012-03-16 10:55:17.000000000 +0100 +@@ -20,6 +20,7 @@ config VIDEO_CX23885 + select DVB_LNBP21 if !DVB_FE_CUSTOMISE + select DVB_STV6110 if !DVB_FE_CUSTOMISE + select DVB_CX24116 if !DVB_FE_CUSTOMISE ++ select DVB_M88DS3103 if !DVB_FE_CUSTOMISE + select DVB_STV0900 if !DVB_FE_CUSTOMISE + select DVB_DS3000 if !DVB_FE_CUSTOMISE + select DVB_STV0367 if !DVB_FE_CUSTOMISE +diff -uprN linux-3.2.10.orig/drivers/media/video/cx88/cx88-cards.c linux-3.2.10/drivers/media/video/cx88/cx88-cards.c +--- linux-3.2.10.orig/drivers/media/video/cx88/cx88-cards.c 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx88/cx88-cards.c 2012-03-16 10:55:35.000000000 +0100 +@@ -2237,6 +2237,18 @@ static const struct cx88_board cx88_boar + } }, + .mpeg = CX88_MPEG_DVB, + }, ++ [CX88_BOARD_BST_PS8312] = { ++ .name = "Bestunar PS8312 DVB-S/S2", ++ .tuner_type = UNSET, ++ .radio_type = UNSET, ++ .tuner_addr = ADDR_UNSET, ++ .radio_addr = ADDR_UNSET, ++ .input = {{ ++ .type = CX88_VMUX_DVB, ++ .vmux = 0, ++ } }, ++ .mpeg = CX88_MPEG_DVB, ++ }, + }; + + /* ------------------------------------------------------------------ */ +@@ -2726,6 +2738,10 @@ static const struct cx88_subid cx88_subi + .subvendor = 0x1822, + .subdevice = 0x0023, + .card = CX88_BOARD_TWINHAN_VP1027_DVBS, ++ }, { ++ .subvendor = 0x14f1, ++ .subdevice = 0x8312, ++ .card = CX88_BOARD_BST_PS8312, + }, + }; + +@@ -3454,7 +3470,13 @@ static void cx88_card_setup(struct cx88_ + msleep(100); + cx_write(MO_SRST_IO, 1); + msleep(100); +- break; ++ break; ++ case CX88_BOARD_BST_PS8312: ++ cx_write(MO_GP1_IO, 0x808000); ++ msleep(100); ++ cx_write(MO_GP1_IO, 0x808080); ++ msleep(100); ++ break; + } /*end switch() */ + + +diff -uprN linux-3.2.10.orig/drivers/media/video/cx88/cx88-dvb.c linux-3.2.10/drivers/media/video/cx88/cx88-dvb.c +--- linux-3.2.10.orig/drivers/media/video/cx88/cx88-dvb.c 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx88/cx88-dvb.c 2012-03-16 10:55:35.000000000 +0100 +@@ -54,6 +54,7 @@ + #include "stv0288.h" + #include "stb6000.h" + #include "cx24116.h" ++#include "m88ds3103.h" + #include "stv0900.h" + #include "stb6100.h" + #include "stb6100_proc.h" +@@ -458,6 +459,56 @@ static int tevii_dvbs_set_voltage(struct + return core->prev_set_voltage(fe, voltage); + return 0; + } ++/*CX88_BOARD_BST_PS8312*/ ++static int bst_dvbs_set_voltage(struct dvb_frontend *fe, ++ fe_sec_voltage_t voltage) ++{ ++ struct cx8802_dev *dev= fe->dvb->priv; ++ struct cx88_core *core = dev->core; ++ ++ cx_write(MO_GP1_IO, 0x111111); ++ switch (voltage) { ++ case SEC_VOLTAGE_13: ++ cx_write(MO_GP1_IO, 0x020200); ++ break; ++ case SEC_VOLTAGE_18: ++ cx_write(MO_GP1_IO, 0x020202); ++ break; ++ case SEC_VOLTAGE_OFF: ++ cx_write(MO_GP1_IO, 0x111100); ++ break; ++ } ++ ++ if (core->prev_set_voltage) ++ return core->prev_set_voltage(fe, voltage); ++ return 0; ++} ++ ++static int bst_dvbs_set_voltage_v2(struct dvb_frontend *fe, ++ fe_sec_voltage_t voltage) ++{ ++ struct cx8802_dev *dev= fe->dvb->priv; ++ struct cx88_core *core = dev->core; ++ ++ cx_write(MO_GP1_IO, 0x111101); ++ switch (voltage) { ++ case SEC_VOLTAGE_13: ++ cx_write(MO_GP1_IO, 0x020200); ++ break; ++ case SEC_VOLTAGE_18: ++ ++ cx_write(MO_GP1_IO, 0x020202); ++ break; ++ case SEC_VOLTAGE_OFF: ++ ++ cx_write(MO_GP1_IO, 0x111110); ++ break; ++ } ++ ++ if (core->prev_set_voltage) ++ return core->prev_set_voltage(fe, voltage); ++ return 0; ++} + + static int vp1027_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +@@ -700,6 +751,11 @@ static struct ds3000_config tevii_ds3000 + .set_ts_params = ds3000_set_ts_param, + }; + ++static struct m88ds3103_config dvbsky_ds3103_config = { ++ .demod_address = 0x68, ++ .set_ts_params = ds3000_set_ts_param, ++}; ++ + static const struct stv0900_config prof_7301_stv0900_config = { + .demod_address = 0x6a, + /* demod_mode = 0,*/ +@@ -1458,6 +1514,36 @@ static int dvb_register(struct cx8802_de + if (fe0->dvb.frontend != NULL) + fe0->dvb.frontend->ops.set_voltage = + tevii_dvbs_set_voltage; ++ break; ++ case CX88_BOARD_BST_PS8312: ++ fe0->dvb.frontend = dvb_attach(m88ds3103_attach, ++ &dvbsky_ds3103_config, ++ &core->i2c_adap); ++ if (fe0->dvb.frontend != NULL) ++ { ++ int ret; ++ u8 b0[] = { 0x60 }; ++ u8 b1[2] = { 0 }; ++ struct i2c_msg msg[] = { ++ { ++ .addr = 0x50, ++ .flags = 0, ++ .buf = b0, ++ .len = 1 ++ }, { ++ .addr = 0x50, ++ .flags = I2C_M_RD, ++ .buf = b1, ++ .len = 2 ++ } ++ }; ++ ret = i2c_transfer(&core->i2c_adap, msg, 2); ++ printk("PS8312: config = %02x, %02x", b1[0],b1[1]); ++ if(b1[0] == 0xaa) ++ fe0->dvb.frontend->ops.set_voltage = bst_dvbs_set_voltage_v2; ++ else ++ fe0->dvb.frontend->ops.set_voltage = bst_dvbs_set_voltage; ++ } + break; + case CX88_BOARD_OMICOM_SS4_PCI: + case CX88_BOARD_TBS_8920: +diff -uprN linux-3.2.10.orig/drivers/media/video/cx88/cx88.h linux-3.2.10/drivers/media/video/cx88/cx88.h +--- linux-3.2.10.orig/drivers/media/video/cx88/cx88.h 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx88/cx88.h 2012-03-16 10:55:35.000000000 +0100 +@@ -244,6 +244,7 @@ extern const struct sram_channel const c + #define CX88_BOARD_TEVII_S464 86 + #define CX88_BOARD_WINFAST_DTV2000H_PLUS 87 + #define CX88_BOARD_WINFAST_DTV1800H_XC4000 88 ++#define CX88_BOARD_BST_PS8312 (CX88_BOARD_WINFAST_DTV1800H_XC4000+1) + + enum cx88_itype { + CX88_VMUX_COMPOSITE1 = 1, +diff -uprN linux-3.2.10.orig/drivers/media/video/cx88/cx88-input.c linux-3.2.10/drivers/media/video/cx88/cx88-input.c +--- linux-3.2.10.orig/drivers/media/video/cx88/cx88-input.c 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx88/cx88-input.c 2012-03-16 10:55:35.000000000 +0100 +@@ -415,6 +415,10 @@ int cx88_ir_init(struct cx88_core *core, + rc_type = RC_TYPE_NEC; + ir->sampling = 0xff00; /* address */ + break; ++ case CX88_BOARD_BST_PS8312: ++ ir_codes = RC_MAP_DVBSKY; ++ ir->sampling = 0xff00; /* address */ ++ break; + } + + if (!ir_codes) { +diff -uprN linux-3.2.10.orig/drivers/media/video/cx88/Kconfig linux-3.2.10/drivers/media/video/cx88/Kconfig +--- linux-3.2.10.orig/drivers/media/video/cx88/Kconfig 2012-03-16 10:41:16.000000000 +0100 ++++ linux-3.2.10/drivers/media/video/cx88/Kconfig 2012-03-16 10:55:35.000000000 +0100 +@@ -57,6 +57,7 @@ config VIDEO_CX88_DVB + select DVB_ISL6421 if !DVB_FE_CUSTOMISE + select DVB_S5H1411 if !DVB_FE_CUSTOMISE + select DVB_CX24116 if !DVB_FE_CUSTOMISE ++ select DVB_M88DS3103 if !DVB_FE_CUSTOMISE + select DVB_STV0299 if !DVB_FE_CUSTOMISE + select DVB_STV0288 if !DVB_FE_CUSTOMISE + select DVB_STB6000 if !DVB_FE_CUSTOMISE +diff -uprN linux-3.2.10.orig/include/media/rc-map.h linux-3.2.10/include/media/rc-map.h +--- linux-3.2.10.orig/include/media/rc-map.h 2012-03-16 10:41:11.000000000 +0100 ++++ linux-3.2.10/include/media/rc-map.h 2012-03-16 10:56:20.000000000 +0100 +@@ -83,6 +83,7 @@ void rc_map_init(void); + #define RC_MAP_DM1105_NEC "rc-dm1105-nec" + #define RC_MAP_DNTV_LIVE_DVBT_PRO "rc-dntv-live-dvbt-pro" + #define RC_MAP_DNTV_LIVE_DVB_T "rc-dntv-live-dvb-t" ++#define RC_MAP_DVBSKY "rc-dvbsky" + #define RC_MAP_EMPTY "rc-empty" + #define RC_MAP_EM_TERRATEC "rc-em-terratec" + #define RC_MAP_ENCORE_ENLTV2 "rc-encore-enltv2" diff --git a/packages/linux/patches/linux-3.2.30-211-add_TeVii_s471_support.patch b/packages/linux/patches/linux-3.2.30-211-add_TeVii_s471_support.patch new file mode 100644 index 0000000000..264bc2fca4 --- /dev/null +++ b/packages/linux/patches/linux-3.2.30-211-add_TeVii_s471_support.patch @@ -0,0 +1,90 @@ +cx23885: add TeVii s471 card. + +From: Igor M. Liplianin + +New TeVii s471 card is like s470 model, +but there is different LNB power control. + +Signed-off-by: Igor M. Liplianin + +diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c +index 90bf573..6f4901a 100644 +--- a/drivers/media/dvb/frontends/ds3000.c ++++ b/drivers/media/dvb/frontends/ds3000.c +@@ -1129,7 +1129,10 @@ static int ds3000_set_frontend(struct dvb_frontend *fe, + ds3000_writereg(state, + ds3000_dvbs2_init_tab[i], + ds3000_dvbs2_init_tab[i + 1]); +- ds3000_writereg(state, 0xfe, 0x98); ++ if (c->symbol_rate >= 30000000) ++ ds3000_writereg(state, 0xfe, 0x54); ++ else ++ ds3000_writereg(state, 0xfe, 0x98); + break; + default: + return 1; +diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c +index ab8be9a..76e83e4 100644 +--- a/drivers/media/video/cx23885/cx23885-cards.c ++++ b/drivers/media/video/cx23885/cx23885-cards.c +@@ -452,6 +452,10 @@ struct cx23885_board cx23885_boards[] = { + .portc = CX23885_MPEG_DVB, + }, + ++ [CX23885_BOARD_TEVII_S471] = { ++ .name = "TeVii S471", ++ .portb = CX23885_MPEG_DVB, ++ }, + }; + const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); + +@@ -663,6 +667,10 @@ struct cx23885_subid cx23885_subids[] = { + .subvendor = 0x4254, + .subdevice = 0x0952, + .card = CX23885_BOARD_DVBSKY_S952, ++ }, { ++ .subvendor = 0xd471, ++ .subdevice = 0x9022, ++ .card = CX23885_BOARD_TEVII_S471, + }, + }; + const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); +@@ -1485,6 +1493,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) + case CX23885_BOARD_BST_PS8512: + case CX23885_BOARD_DVBSKY_S950: + case CX23885_BOARD_TEVII_S470: ++ case CX23885_BOARD_TEVII_S471: + case CX23885_BOARD_DVBWORLD_2005: + ts1->gen_ctrl_val = 0x5; /* Parallel */ + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ +diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c +index af9c459..9f68250 100644 +--- a/drivers/media/video/cx23885/cx23885-dvb.c ++++ b/drivers/media/video/cx23885/cx23885-dvb.c +@@ -1174,6 +1174,14 @@ static int dvb_register(struct cx23885_tsport *port) + break; + } + break; ++ case CX23885_BOARD_TEVII_S471: ++ i2c_bus = &dev->i2c_bus[1]; ++ ++ fe0->dvb.frontend = dvb_attach(ds3000_attach, ++ &tevii_ds3000_config, ++ &i2c_bus->i2c_adap); ++ break; ++ + default: + printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " + " isn't supported yet\n", +diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h +index 6f058f1..19cebdf 100644 +--- a/drivers/media/video/cx23885/cx23885.h ++++ b/drivers/media/video/cx23885/cx23885.h +@@ -90,6 +90,7 @@ + #define CX23885_BOARD_BST_PS8512 (CX23885_BOARD_MPX885+1) + #define CX23885_BOARD_DVBSKY_S952 (CX23885_BOARD_BST_PS8512+1) + #define CX23885_BOARD_DVBSKY_S950 (CX23885_BOARD_DVBSKY_S952+1) ++#define CX23885_BOARD_TEVII_S471 (CX23885_BOARD_DVBSKY_S950+1) + + #define GPIO_0 0x00000001 + #define GPIO_1 0x00000002 diff --git a/packages/linux/patches/linux-3.2.30-212-mantis_stb0899_faster_lock.patch b/packages/linux/patches/linux-3.2.30-212-mantis_stb0899_faster_lock.patch new file mode 100644 index 0000000000..23e28aea88 --- /dev/null +++ b/packages/linux/patches/linux-3.2.30-212-mantis_stb0899_faster_lock.patch @@ -0,0 +1,141 @@ +diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c +index 2da55ec..3efde1e 100644 +--- a/drivers/media/dvb/frontends/stb0899_algo.c ++++ b/drivers/media/dvb/frontends/stb0899_algo.c +@@ -206,7 +206,6 @@ static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state) + static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state) + { + struct stb0899_internal *internal = &state->internal; +- struct stb0899_params *params = &state->params; + + short int derot_step, derot_freq = 0, derot_limit, next_loop = 3; + int index = 0; +@@ -216,10 +215,9 @@ static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state) + + /* timing loop computation & symbol rate optimisation */ + derot_limit = (internal->sub_range / 2L) / internal->mclk; +- derot_step = (params->srate / 2L) / internal->mclk; ++ derot_step = internal->derot_step * 4; /* dertot_step = decreasing delta */ + + while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) { +- index++; + derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */ + + if (abs(derot_freq) > derot_limit) +@@ -230,6 +228,7 @@ static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state) + STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq)); + stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ + } ++ index++; + internal->direction = -internal->direction; /* Change zigzag direction */ + } + +@@ -278,14 +277,18 @@ static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state) + { + struct stb0899_internal *internal = &state->internal; + +- short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3; ++ short int derot_freq = 0, last_derot_freq = 0, derot_limit, derot_step, next_loop = 3; + int index = 0; ++ int base_freq; + u8 cfr[2]; + u8 reg; + + internal->status = NOCARRIER; + derot_limit = (internal->sub_range / 2L) / internal->mclk; + derot_freq = internal->derot_freq; ++ derot_step = internal->derot_step * 2; ++ last_derot_freq = internal->derot_freq; ++ base_freq = internal->derot_freq; + + reg = stb0899_read_reg(state, STB0899_CFD); + STB0899_SETFIELD_VAL(CFD_ON, reg, 1); +@@ -294,11 +297,10 @@ static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state) + do { + dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk); + if (stb0899_check_carrier(state) == NOCARRIER) { +- index++; + last_derot_freq = derot_freq; +- derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */ ++ derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */ + +- if(abs(derot_freq) > derot_limit) ++ if (derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit) + next_loop--; + + if (next_loop) { +@@ -310,9 +312,10 @@ static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state) + STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq)); + stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ + } ++ index++; ++ internal->direction = -internal->direction; /* Change zigzag direction */ + } + +- internal->direction = -internal->direction; /* Change zigzag direction */ + } while ((internal->status != CARRIEROK) && next_loop); + + if (internal->status == CARRIEROK) { +@@ -338,6 +341,7 @@ static enum stb0899_status stb0899_check_data(struct stb0899_state *state) + int lock = 0, index = 0, dataTime = 500, loop; + u8 reg; + ++ msleep(1); + internal->status = NODATA; + + /* RESET FEC */ +@@ -348,6 +352,7 @@ static enum stb0899_status stb0899_check_data(struct stb0899_state *state) + reg = stb0899_read_reg(state, STB0899_TSTRES); + STB0899_SETFIELD_VAL(FRESACS, reg, 0); + stb0899_write_reg(state, STB0899_TSTRES, reg); ++ msleep(1); + + if (params->srate <= 2000000) + dataTime = 2000; +@@ -360,6 +365,7 @@ static enum stb0899_status stb0899_check_data(struct stb0899_state *state) + + stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop */ + while (1) { ++ msleep(1); // Alex: added 1 mSec + /* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP */ + reg = stb0899_read_reg(state, STB0899_VSTATUS); + lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg); +@@ -387,20 +393,21 @@ static enum stb0899_status stb0899_search_data(struct stb0899_state *state) + short int derot_freq, derot_step, derot_limit, next_loop = 3; + u8 cfr[2]; + u8 reg; +- int index = 1; ++ int index = 0; ++ int base_freq; + + struct stb0899_internal *internal = &state->internal; +- struct stb0899_params *params = &state->params; + +- derot_step = (params->srate / 4L) / internal->mclk; ++ derot_step = internal->derot_step; + derot_limit = (internal->sub_range / 2L) / internal->mclk; + derot_freq = internal->derot_freq; ++ base_freq = internal->derot_freq; + + do { + if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) { + + derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */ +- if (abs(derot_freq) > derot_limit) ++ if (derot_freq > base_freq + derot_limit || derot_freq < base_freq - derot_limit) + next_loop--; + + if (next_loop) { +@@ -414,9 +421,9 @@ static enum stb0899_status stb0899_search_data(struct stb0899_state *state) + stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ + + stb0899_check_carrier(state); +- index++; + } + } ++ index++; + internal->direction = -internal->direction; /* change zig zag direction */ + } while ((internal->status != DATAOK) && next_loop); + +-- +1.7.1 diff --git a/packages/linux/patches/linux-3.2.30-213-cinergy_s2_usb_r2.patch b/packages/linux/patches/linux-3.2.30-213-cinergy_s2_usb_r2.patch new file mode 100644 index 0000000000..155e5311f7 --- /dev/null +++ b/packages/linux/patches/linux-3.2.30-213-cinergy_s2_usb_r2.patch @@ -0,0 +1,46 @@ +diff -Naur linux-3.2.21/drivers/media/dvb/dvb-usb/dw2102.c linux-3.2.21.patch/drivers/media/dvb/dvb-usb/dw2102.c +--- linux-3.2.21/drivers/media/dvb/dvb-usb/dw2102.c 2012-06-20 00:18:30.000000000 +0200 ++++ linux-3.2.21.patch/drivers/media/dvb/dvb-usb/dw2102.c 2012-06-28 14:08:50.721691934 +0200 +@@ -1181,6 +1181,14 @@ + { + u8 obuf[3] = { 0xe, 0x80, 0 }; + u8 ibuf[] = { 0 }; ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ //power on su3000 ++ obuf[0] = 0xe; ++ obuf[1] = 0x02; ++ obuf[2] = 1; + + if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) + err("command 0x0e transfer failed."); +@@ -1448,6 +1456,7 @@ + {USB_DEVICE(0x3034, 0x7500)}, + {USB_DEVICE(0x1f4d, 0x3000)}, + {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)}, ++ {USB_DEVICE(USB_VID_TERRATEC, 0x00b0)}, + {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, + {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, + {USB_DEVICE(0x1f4d, 0x3100)}, +@@ -1839,7 +1848,7 @@ + }}, + } + }, +- .num_device_descs = 3, ++ .num_device_descs = 4, + .devices = { + { "SU3000HD DVB-S USB2.0", + { &dw2102_table[10], NULL }, +@@ -1853,6 +1862,10 @@ + { &dw2102_table[14], NULL }, + { NULL }, + }, ++ { "Terratec Cinergy S2 USB HD Rev.2", ++ { &dw2102_table[17], NULL }, ++ { NULL }, ++ }, + } + }; + diff --git a/packages/linux/patches/linux-3.2.28-214-hdtv-hvr930c.patch b/packages/linux/patches/linux-3.2.30-214-hdtv-hvr930c.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-214-hdtv-hvr930c.patch rename to packages/linux/patches/linux-3.2.30-214-hdtv-hvr930c.patch diff --git a/packages/linux/patches/linux-3.2.30-251-acpi-5.0_support.patch b/packages/linux/patches/linux-3.2.30-251-acpi-5.0_support.patch new file mode 100644 index 0000000000..db121116e9 --- /dev/null +++ b/packages/linux/patches/linux-3.2.30-251-acpi-5.0_support.patch @@ -0,0 +1,5415 @@ +diff -Naur linux-3.2.16/drivers/acpi/acpica/acconfig.h linux-3.2.16.patch/drivers/acpi/acpica/acconfig.h +--- linux-3.2.16/drivers/acpi/acpica/acconfig.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/acconfig.h 2012-04-23 06:05:41.300122287 +0200 +@@ -202,9 +202,10 @@ + #define ACPI_RSDP_CHECKSUM_LENGTH 20 + #define ACPI_RSDP_XCHECKSUM_LENGTH 36 + +-/* SMBus and IPMI bidirectional buffer size */ ++/* SMBus, GSBus and IPMI bidirectional buffer size */ + + #define ACPI_SMBUS_BUFFER_SIZE 34 ++#define ACPI_GSBUS_BUFFER_SIZE 34 + #define ACPI_IPMI_BUFFER_SIZE 66 + + /* _sx_d and _sx_w control methods */ +diff -Naur linux-3.2.16/drivers/acpi/acpica/acevents.h linux-3.2.16.patch/drivers/acpi/acpica/acevents.h +--- linux-3.2.16/drivers/acpi/acpica/acevents.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/acevents.h 2012-04-23 06:05:41.300122287 +0200 +@@ -162,6 +162,7 @@ + + acpi_status + acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, ++ union acpi_operand_object *field_obj, + u32 function, + u32 region_offset, u32 bit_width, u64 *value); + +diff -Naur linux-3.2.16/drivers/acpi/acpica/acglobal.h linux-3.2.16.patch/drivers/acpi/acpica/acglobal.h +--- linux-3.2.16/drivers/acpi/acpica/acglobal.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/acglobal.h 2012-04-23 06:05:41.302122323 +0200 +@@ -140,8 +140,19 @@ + acpi_name acpi_gbl_trace_method_name; + u8 acpi_gbl_system_awake_and_running; + ++/* ++ * ACPI 5.0 introduces the concept of a "reduced hardware platform", meaning ++ * that the ACPI hardware is no longer required. A flag in the FADT indicates ++ * a reduced HW machine, and that flag is duplicated here for convenience. ++ */ ++u8 acpi_gbl_reduced_hardware; ++ + #endif + ++/* Do not disassemble buffers to resource descriptors */ ++ ++ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_no_resource_disassembly, FALSE); ++ + /***************************************************************************** + * + * Debug support +@@ -207,7 +218,7 @@ + + /***************************************************************************** + * +- * Mutual exlusion within ACPICA subsystem ++ * Mutual exclusion within ACPICA subsystem + * + ****************************************************************************/ + +diff -Naur linux-3.2.16/drivers/acpi/acpica/acinterp.h linux-3.2.16.patch/drivers/acpi/acpica/acinterp.h +--- linux-3.2.16/drivers/acpi/acpica/acinterp.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/acinterp.h 2012-04-23 06:05:41.370123694 +0200 +@@ -468,6 +468,8 @@ + + void acpi_ex_integer_to_string(char *dest, u64 value); + ++u8 acpi_is_valid_space_id(u8 space_id); ++ + /* + * exregion - default op_region handlers + */ +diff -Naur linux-3.2.16/drivers/acpi/acpica/aclocal.h linux-3.2.16.patch/drivers/acpi/acpica/aclocal.h +--- linux-3.2.16/drivers/acpi/acpica/aclocal.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/aclocal.h 2012-04-23 06:05:41.401124318 +0200 +@@ -53,7 +53,7 @@ + + /* Total number of aml opcodes defined */ + +-#define AML_NUM_OPCODES 0x7F ++#define AML_NUM_OPCODES 0x81 + + /* Forward declarations */ + +@@ -249,12 +249,16 @@ + struct acpi_namespace_node *field_node; + struct acpi_namespace_node *register_node; + struct acpi_namespace_node *data_register_node; ++ struct acpi_namespace_node *connection_node; ++ u8 *resource_buffer; + u32 bank_value; + u32 field_bit_position; + u32 field_bit_length; ++ u16 resource_length; + u8 field_flags; + u8 attribute; + u8 field_type; ++ u8 access_length; + }; + + typedef +@@ -315,7 +319,8 @@ + + /* + * Used for ACPI_PTYPE1_FIXED, ACPI_PTYPE1_VAR, ACPI_PTYPE2, +- * ACPI_PTYPE2_MIN, ACPI_PTYPE2_PKG_COUNT, ACPI_PTYPE2_COUNT ++ * ACPI_PTYPE2_MIN, ACPI_PTYPE2_PKG_COUNT, ACPI_PTYPE2_COUNT, ++ * ACPI_PTYPE2_FIX_VAR + */ + struct acpi_package_info { + u8 type; +@@ -951,7 +956,7 @@ + #define ACPI_RESOURCE_NAME_END_DEPENDENT 0x38 + #define ACPI_RESOURCE_NAME_IO 0x40 + #define ACPI_RESOURCE_NAME_FIXED_IO 0x48 +-#define ACPI_RESOURCE_NAME_RESERVED_S1 0x50 ++#define ACPI_RESOURCE_NAME_FIXED_DMA 0x50 + #define ACPI_RESOURCE_NAME_RESERVED_S2 0x58 + #define ACPI_RESOURCE_NAME_RESERVED_S3 0x60 + #define ACPI_RESOURCE_NAME_RESERVED_S4 0x68 +@@ -973,7 +978,9 @@ + #define ACPI_RESOURCE_NAME_EXTENDED_IRQ 0x89 + #define ACPI_RESOURCE_NAME_ADDRESS64 0x8A + #define ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 0x8B +-#define ACPI_RESOURCE_NAME_LARGE_MAX 0x8B ++#define ACPI_RESOURCE_NAME_GPIO 0x8C ++#define ACPI_RESOURCE_NAME_SERIAL_BUS 0x8E ++#define ACPI_RESOURCE_NAME_LARGE_MAX 0x8E + + /***************************************************************************** + * +diff -Naur linux-3.2.16/drivers/acpi/acpica/acobject.h linux-3.2.16.patch/drivers/acpi/acpica/acobject.h +--- linux-3.2.16/drivers/acpi/acpica/acobject.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/acobject.h 2012-04-23 06:05:41.402124338 +0200 +@@ -254,6 +254,7 @@ + u32 base_byte_offset; /* Byte offset within containing object */\ + u32 value; /* Value to store into the Bank or Index register */\ + u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\ ++ u8 access_length; /* For serial regions/fields */ + + + struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */ +@@ -261,7 +262,9 @@ + }; + + struct acpi_object_region_field { +- ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Containing op_region object */ ++ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO u16 resource_length; ++ union acpi_operand_object *region_obj; /* Containing op_region object */ ++ u8 *resource_buffer; /* resource_template for serial regions/fields */ + }; + + struct acpi_object_bank_field { +diff -Naur linux-3.2.16/drivers/acpi/acpica/acopcode.h linux-3.2.16.patch/drivers/acpi/acpica/acopcode.h +--- linux-3.2.16/drivers/acpi/acpica/acopcode.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/acopcode.h 2012-04-23 06:05:41.403124358 +0200 +@@ -93,6 +93,7 @@ + #define ARGP_CONCAT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) + #define ARGP_CONCAT_RES_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) + #define ARGP_COND_REF_OF_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_SUPERNAME) ++#define ARGP_CONNECTFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING) + #define ARGP_CONTINUE_OP ARG_NONE + #define ARGP_COPY_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_SIMPLENAME) + #define ARGP_CREATE_BIT_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME) +@@ -164,6 +165,7 @@ + #define ARGP_RETURN_OP ARGP_LIST1 (ARGP_TERMARG) + #define ARGP_REVISION_OP ARG_NONE + #define ARGP_SCOPE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_TERMLIST) ++#define ARGP_SERIALFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING) + #define ARGP_SHIFT_LEFT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) + #define ARGP_SHIFT_RIGHT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) + #define ARGP_SIGNAL_OP ARGP_LIST1 (ARGP_SUPERNAME) +@@ -223,6 +225,7 @@ + #define ARGI_CONCAT_OP ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA, ARGI_TARGETREF) + #define ARGI_CONCAT_RES_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_BUFFER, ARGI_TARGETREF) + #define ARGI_COND_REF_OF_OP ARGI_LIST2 (ARGI_OBJECT_REF, ARGI_TARGETREF) ++#define ARGI_CONNECTFIELD_OP ARGI_INVALID_OPCODE + #define ARGI_CONTINUE_OP ARGI_INVALID_OPCODE + #define ARGI_COPY_OP ARGI_LIST2 (ARGI_ANYTYPE, ARGI_SIMPLE_TARGET) + #define ARGI_CREATE_BIT_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE) +@@ -294,6 +297,7 @@ + #define ARGI_RETURN_OP ARGI_INVALID_OPCODE + #define ARGI_REVISION_OP ARG_NONE + #define ARGI_SCOPE_OP ARGI_INVALID_OPCODE ++#define ARGI_SERIALFIELD_OP ARGI_INVALID_OPCODE + #define ARGI_SHIFT_LEFT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) + #define ARGI_SHIFT_RIGHT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) + #define ARGI_SIGNAL_OP ARGI_LIST1 (ARGI_EVENT) +diff -Naur linux-3.2.16/drivers/acpi/acpica/acpredef.h linux-3.2.16.patch/drivers/acpi/acpica/acpredef.h +--- linux-3.2.16/drivers/acpi/acpica/acpredef.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/acpredef.h 2012-04-23 06:05:41.404124378 +0200 +@@ -94,6 +94,14 @@ + * ACPI_PTYPE2_REV_FIXED: Revision at start, each subpackage is Fixed-length + * (Used for _ART, _FPS) + * ++ * ACPI_PTYPE2_FIX_VAR: Each subpackage consists of some fixed-length elements ++ * followed by an optional element ++ * object type ++ * count ++ * object type ++ * count = 0 (optional) ++ * (Used for _DLM) ++ * + *****************************************************************************/ + + enum acpi_return_package_types { +@@ -105,7 +113,8 @@ + ACPI_PTYPE2_PKG_COUNT = 6, + ACPI_PTYPE2_FIXED = 7, + ACPI_PTYPE2_MIN = 8, +- ACPI_PTYPE2_REV_FIXED = 9 ++ ACPI_PTYPE2_REV_FIXED = 9, ++ ACPI_PTYPE2_FIX_VAR = 10 + }; + + #ifdef ACPI_CREATE_PREDEFINED_TABLE +@@ -154,6 +163,7 @@ + {{"_AC8", 0, ACPI_RTYPE_INTEGER}}, + {{"_AC9", 0, ACPI_RTYPE_INTEGER}}, + {{"_ADR", 0, ACPI_RTYPE_INTEGER}}, ++ {{"_AEI", 0, ACPI_RTYPE_BUFFER}}, + {{"_AL0", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + +@@ -229,6 +239,13 @@ + {{"_CID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints/Strs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0,0}, 0,0}}, + ++ {{"_CLS", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (3 Int) */ ++ {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3, 0}, 0, 0}}, ++ ++ {{"_CPC", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints/Bufs) */ ++ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER, 0, 0}, 0, ++ 0}}, ++ + {{"_CRS", 0, ACPI_RTYPE_BUFFER}}, + {{"_CRT", 0, ACPI_RTYPE_INTEGER}}, + {{"_CSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(n), n-1 Int) */ +@@ -237,12 +254,21 @@ + {{"_CST", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(n), n Pkg (1 Buf/3 Int) */ + {{{ACPI_PTYPE2_PKG_COUNT,ACPI_RTYPE_BUFFER, 1, ACPI_RTYPE_INTEGER}, 3,0}}, + ++ {{"_CWS", 1, ACPI_RTYPE_INTEGER}}, + {{"_DCK", 1, ACPI_RTYPE_INTEGER}}, + {{"_DCS", 0, ACPI_RTYPE_INTEGER}}, + {{"_DDC", 1, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER}}, + {{"_DDN", 0, ACPI_RTYPE_STRING}}, ++ {{"_DEP", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ ++ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, ++ + {{"_DGS", 0, ACPI_RTYPE_INTEGER}}, + {{"_DIS", 0, 0}}, ++ ++ {{"_DLM", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (1 Ref, 0/1 Optional Buf/Ref) */ ++ {{{ACPI_PTYPE2_FIX_VAR, ACPI_RTYPE_REFERENCE, 1, ++ ACPI_RTYPE_REFERENCE | ACPI_RTYPE_BUFFER}, 0, 0}}, ++ + {{"_DMA", 0, ACPI_RTYPE_BUFFER}}, + {{"_DOD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, +@@ -262,6 +288,7 @@ + {{"_EJ3", 1, 0}}, + {{"_EJ4", 1, 0}}, + {{"_EJD", 0, ACPI_RTYPE_STRING}}, ++ {{"_EVT", 1, 0}}, + {{"_FDE", 0, ACPI_RTYPE_BUFFER}}, + {{"_FDI", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16,0}, 0,0}}, +@@ -281,14 +308,17 @@ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3, 0}, 0, 0}}, + + {{"_GAI", 0, ACPI_RTYPE_INTEGER}}, ++ {{"_GCP", 0, ACPI_RTYPE_INTEGER}}, + {{"_GHL", 0, ACPI_RTYPE_INTEGER}}, + {{"_GLK", 0, ACPI_RTYPE_INTEGER}}, + {{"_GPD", 0, ACPI_RTYPE_INTEGER}}, + {{"_GPE", 0, ACPI_RTYPE_INTEGER}}, /* _GPE method, not _GPE scope */ ++ {{"_GRT", 0, ACPI_RTYPE_BUFFER}}, + {{"_GSB", 0, ACPI_RTYPE_INTEGER}}, + {{"_GTF", 0, ACPI_RTYPE_BUFFER}}, + {{"_GTM", 0, ACPI_RTYPE_BUFFER}}, + {{"_GTS", 1, 0}}, ++ {{"_GWS", 1, ACPI_RTYPE_INTEGER}}, + {{"_HID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, + {{"_HOT", 0, ACPI_RTYPE_INTEGER}}, + {{"_HPP", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ +@@ -303,6 +333,7 @@ + {{"_HPX", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (var Ints) */ + {{{ACPI_PTYPE2_MIN, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, + ++ {{"_HRV", 0, ACPI_RTYPE_INTEGER}}, + {{"_IFT", 0, ACPI_RTYPE_INTEGER}}, /* See IPMI spec */ + {{"_INI", 0, 0}}, + {{"_IRC", 0, 0}}, +@@ -361,6 +392,9 @@ + {{"_PR3", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, + ++ {{"_PRE", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ ++ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, ++ + {{"_PRL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, + +@@ -391,6 +425,7 @@ + {{"_PSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (5 Int) with count */ + {{{ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER,0,0}, 0,0}}, + ++ {{"_PSE", 1, 0}}, + {{"_PSL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + +@@ -457,6 +492,7 @@ + {{"_SLI", 0, ACPI_RTYPE_BUFFER}}, + {{"_SPD", 1, ACPI_RTYPE_INTEGER}}, + {{"_SRS", 1, 0}}, ++ {{"_SRT", 1, ACPI_RTYPE_INTEGER}}, + {{"_SRV", 0, ACPI_RTYPE_INTEGER}}, /* See IPMI spec */ + {{"_SST", 1, 0}}, + {{"_STA", 0, ACPI_RTYPE_INTEGER}}, +@@ -464,6 +500,7 @@ + {{"_STP", 2, ACPI_RTYPE_INTEGER}}, + {{"_STR", 0, ACPI_RTYPE_BUFFER}}, + {{"_STV", 2, ACPI_RTYPE_INTEGER}}, ++ {{"_SUB", 0, ACPI_RTYPE_STRING}}, + {{"_SUN", 0, ACPI_RTYPE_INTEGER}}, + {{"_SWS", 0, ACPI_RTYPE_INTEGER}}, + {{"_TC1", 0, ACPI_RTYPE_INTEGER}}, +diff -Naur linux-3.2.16/drivers/acpi/acpica/acresrc.h linux-3.2.16.patch/drivers/acpi/acpica/acresrc.h +--- linux-3.2.16/drivers/acpi/acpica/acresrc.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/acresrc.h 2012-04-23 06:05:41.405124398 +0200 +@@ -73,28 +73,40 @@ + + /* Resource conversion opcodes */ + +-#define ACPI_RSC_INITGET 0 +-#define ACPI_RSC_INITSET 1 +-#define ACPI_RSC_FLAGINIT 2 +-#define ACPI_RSC_1BITFLAG 3 +-#define ACPI_RSC_2BITFLAG 4 +-#define ACPI_RSC_COUNT 5 +-#define ACPI_RSC_COUNT16 6 +-#define ACPI_RSC_LENGTH 7 +-#define ACPI_RSC_MOVE8 8 +-#define ACPI_RSC_MOVE16 9 +-#define ACPI_RSC_MOVE32 10 +-#define ACPI_RSC_MOVE64 11 +-#define ACPI_RSC_SET8 12 +-#define ACPI_RSC_DATA8 13 +-#define ACPI_RSC_ADDRESS 14 +-#define ACPI_RSC_SOURCE 15 +-#define ACPI_RSC_SOURCEX 16 +-#define ACPI_RSC_BITMASK 17 +-#define ACPI_RSC_BITMASK16 18 +-#define ACPI_RSC_EXIT_NE 19 +-#define ACPI_RSC_EXIT_LE 20 +-#define ACPI_RSC_EXIT_EQ 21 ++typedef enum { ++ ACPI_RSC_INITGET = 0, ++ ACPI_RSC_INITSET, ++ ACPI_RSC_FLAGINIT, ++ ACPI_RSC_1BITFLAG, ++ ACPI_RSC_2BITFLAG, ++ ACPI_RSC_3BITFLAG, ++ ACPI_RSC_ADDRESS, ++ ACPI_RSC_BITMASK, ++ ACPI_RSC_BITMASK16, ++ ACPI_RSC_COUNT, ++ ACPI_RSC_COUNT16, ++ ACPI_RSC_COUNT_GPIO_PIN, ++ ACPI_RSC_COUNT_GPIO_RES, ++ ACPI_RSC_COUNT_GPIO_VEN, ++ ACPI_RSC_COUNT_SERIAL_RES, ++ ACPI_RSC_COUNT_SERIAL_VEN, ++ ACPI_RSC_DATA8, ++ ACPI_RSC_EXIT_EQ, ++ ACPI_RSC_EXIT_LE, ++ ACPI_RSC_EXIT_NE, ++ ACPI_RSC_LENGTH, ++ ACPI_RSC_MOVE_GPIO_PIN, ++ ACPI_RSC_MOVE_GPIO_RES, ++ ACPI_RSC_MOVE_SERIAL_RES, ++ ACPI_RSC_MOVE_SERIAL_VEN, ++ ACPI_RSC_MOVE8, ++ ACPI_RSC_MOVE16, ++ ACPI_RSC_MOVE32, ++ ACPI_RSC_MOVE64, ++ ACPI_RSC_SET8, ++ ACPI_RSC_SOURCE, ++ ACPI_RSC_SOURCEX ++} ACPI_RSCONVERT_OPCODES; + + /* Resource Conversion sub-opcodes */ + +@@ -106,6 +118,9 @@ + #define ACPI_RS_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_resource,f) + #define AML_OFFSET(f) (u8) ACPI_OFFSET (union aml_resource,f) + ++/* ++ * Individual entry for the resource dump tables ++ */ + typedef const struct acpi_rsdump_info { + u8 opcode; + u8 offset; +@@ -116,20 +131,25 @@ + + /* Values for the Opcode field above */ + +-#define ACPI_RSD_TITLE 0 +-#define ACPI_RSD_LITERAL 1 +-#define ACPI_RSD_STRING 2 +-#define ACPI_RSD_UINT8 3 +-#define ACPI_RSD_UINT16 4 +-#define ACPI_RSD_UINT32 5 +-#define ACPI_RSD_UINT64 6 +-#define ACPI_RSD_1BITFLAG 7 +-#define ACPI_RSD_2BITFLAG 8 +-#define ACPI_RSD_SHORTLIST 9 +-#define ACPI_RSD_LONGLIST 10 +-#define ACPI_RSD_DWORDLIST 11 +-#define ACPI_RSD_ADDRESS 12 +-#define ACPI_RSD_SOURCE 13 ++typedef enum { ++ ACPI_RSD_TITLE = 0, ++ ACPI_RSD_1BITFLAG, ++ ACPI_RSD_2BITFLAG, ++ ACPI_RSD_3BITFLAG, ++ ACPI_RSD_ADDRESS, ++ ACPI_RSD_DWORDLIST, ++ ACPI_RSD_LITERAL, ++ ACPI_RSD_LONGLIST, ++ ACPI_RSD_SHORTLIST, ++ ACPI_RSD_SHORTLISTX, ++ ACPI_RSD_SOURCE, ++ ACPI_RSD_STRING, ++ ACPI_RSD_UINT8, ++ ACPI_RSD_UINT16, ++ ACPI_RSD_UINT32, ++ ACPI_RSD_UINT64, ++ ACPI_RSD_WORDLIST ++} ACPI_RSDUMP_OPCODES; + + /* restore default alignment */ + +@@ -138,13 +158,18 @@ + /* Resource tables indexed by internal resource type */ + + extern const u8 acpi_gbl_aml_resource_sizes[]; ++extern const u8 acpi_gbl_aml_resource_serial_bus_sizes[]; + extern struct acpi_rsconvert_info *acpi_gbl_set_resource_dispatch[]; + + /* Resource tables indexed by raw AML resource descriptor type */ + + extern const u8 acpi_gbl_resource_struct_sizes[]; ++extern const u8 acpi_gbl_resource_struct_serial_bus_sizes[]; + extern struct acpi_rsconvert_info *acpi_gbl_get_resource_dispatch[]; + ++extern struct acpi_rsconvert_info ++ *acpi_gbl_convert_resource_serial_bus_dispatch[]; ++ + struct acpi_vendor_walk_info { + struct acpi_vendor_uuid *uuid; + struct acpi_buffer *buffer; +@@ -190,6 +215,10 @@ + acpi_rs_set_srs_method_data(struct acpi_namespace_node *node, + struct acpi_buffer *ret_buffer); + ++acpi_status ++acpi_rs_get_aei_method_data(struct acpi_namespace_node *node, ++ struct acpi_buffer *ret_buffer); ++ + /* + * rscalc + */ +@@ -293,6 +322,11 @@ + extern struct acpi_rsconvert_info acpi_rs_convert_ext_irq[]; + extern struct acpi_rsconvert_info acpi_rs_convert_address64[]; + extern struct acpi_rsconvert_info acpi_rs_convert_ext_address64[]; ++extern struct acpi_rsconvert_info acpi_rs_convert_gpio[]; ++extern struct acpi_rsconvert_info acpi_rs_convert_fixed_dma[]; ++extern struct acpi_rsconvert_info acpi_rs_convert_i2c_serial_bus[]; ++extern struct acpi_rsconvert_info acpi_rs_convert_spi_serial_bus[]; ++extern struct acpi_rsconvert_info acpi_rs_convert_uart_serial_bus[]; + + /* These resources require separate get/set tables */ + +@@ -310,6 +344,7 @@ + * rsinfo + */ + extern struct acpi_rsdump_info *acpi_gbl_dump_resource_dispatch[]; ++extern struct acpi_rsdump_info *acpi_gbl_dump_serial_bus_dispatch[]; + + /* + * rsdump +@@ -331,6 +366,12 @@ + extern struct acpi_rsdump_info acpi_rs_dump_ext_address64[]; + extern struct acpi_rsdump_info acpi_rs_dump_ext_irq[]; + extern struct acpi_rsdump_info acpi_rs_dump_generic_reg[]; ++extern struct acpi_rsdump_info acpi_rs_dump_gpio[]; ++extern struct acpi_rsdump_info acpi_rs_dump_fixed_dma[]; ++extern struct acpi_rsdump_info acpi_rs_dump_common_serial_bus[]; ++extern struct acpi_rsdump_info acpi_rs_dump_i2c_serial_bus[]; ++extern struct acpi_rsdump_info acpi_rs_dump_spi_serial_bus[]; ++extern struct acpi_rsdump_info acpi_rs_dump_uart_serial_bus[]; + #endif + + #endif /* __ACRESRC_H__ */ +diff -Naur linux-3.2.16/drivers/acpi/acpica/acutils.h linux-3.2.16.patch/drivers/acpi/acpica/acutils.h +--- linux-3.2.16/drivers/acpi/acpica/acutils.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/acutils.h 2012-04-23 06:05:41.406124418 +0200 +@@ -45,6 +45,7 @@ + #define _ACUTILS_H + + extern const u8 acpi_gbl_resource_aml_sizes[]; ++extern const u8 acpi_gbl_resource_aml_serial_bus_sizes[]; + + /* Strings used by the disassembler and debugger resource dump routines */ + +diff -Naur linux-3.2.16/drivers/acpi/acpica/amlcode.h linux-3.2.16.patch/drivers/acpi/acpica/amlcode.h +--- linux-3.2.16/drivers/acpi/acpica/amlcode.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/amlcode.h 2012-04-23 06:05:41.407124438 +0200 +@@ -189,6 +189,14 @@ + #define AML_LNOTEQUAL_OP (u16) 0x9293 + + /* ++ * Opcodes for "Field" operators ++ */ ++#define AML_FIELD_OFFSET_OP (u8) 0x00 ++#define AML_FIELD_ACCESS_OP (u8) 0x01 ++#define AML_FIELD_CONNECTION_OP (u8) 0x02 /* ACPI 5.0 */ ++#define AML_FIELD_EXT_ACCESS_OP (u8) 0x03 /* ACPI 5.0 */ ++ ++/* + * Internal opcodes + * Use only "Unknown" AML opcodes, don't attempt to use + * any valid ACPI ASCII values (A-Z, 0-9, '-') +@@ -202,6 +210,8 @@ + #define AML_INT_METHODCALL_OP (u16) 0x0035 + #define AML_INT_RETURN_VALUE_OP (u16) 0x0036 + #define AML_INT_EVAL_SUBTREE_OP (u16) 0x0037 ++#define AML_INT_CONNECTION_OP (u16) 0x0038 ++#define AML_INT_EXTACCESSFIELD_OP (u16) 0x0039 + + #define ARG_NONE 0x0 + +@@ -456,13 +466,16 @@ + * access_as keyword + */ + typedef enum { +- AML_FIELD_ATTRIB_SMB_QUICK = 0x02, +- AML_FIELD_ATTRIB_SMB_SEND_RCV = 0x04, +- AML_FIELD_ATTRIB_SMB_BYTE = 0x06, +- AML_FIELD_ATTRIB_SMB_WORD = 0x08, +- AML_FIELD_ATTRIB_SMB_BLOCK = 0x0A, +- AML_FIELD_ATTRIB_SMB_WORD_CALL = 0x0C, +- AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D ++ AML_FIELD_ATTRIB_QUICK = 0x02, ++ AML_FIELD_ATTRIB_SEND_RCV = 0x04, ++ AML_FIELD_ATTRIB_BYTE = 0x06, ++ AML_FIELD_ATTRIB_WORD = 0x08, ++ AML_FIELD_ATTRIB_BLOCK = 0x0A, ++ AML_FIELD_ATTRIB_MULTIBYTE = 0x0B, ++ AML_FIELD_ATTRIB_WORD_CALL = 0x0C, ++ AML_FIELD_ATTRIB_BLOCK_CALL = 0x0D, ++ AML_FIELD_ATTRIB_RAW_BYTES = 0x0E, ++ AML_FIELD_ATTRIB_RAW_PROCESS = 0x0F + } AML_ACCESS_ATTRIBUTE; + + /* Bit fields in the AML method_flags byte */ +diff -Naur linux-3.2.16/drivers/acpi/acpica/amlresrc.h linux-3.2.16.patch/drivers/acpi/acpica/amlresrc.h +--- linux-3.2.16/drivers/acpi/acpica/amlresrc.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/amlresrc.h 2012-04-23 06:05:41.407124438 +0200 +@@ -58,29 +58,48 @@ + #define ACPI_RESTAG_TYPESPECIFICATTRIBUTES "_ATT" + #define ACPI_RESTAG_BASEADDRESS "_BAS" + #define ACPI_RESTAG_BUSMASTER "_BM_" /* Master(1), Slave(0) */ ++#define ACPI_RESTAG_DEBOUNCETIME "_DBT" + #define ACPI_RESTAG_DECODE "_DEC" ++#define ACPI_RESTAG_DEVICEPOLARITY "_DPL" + #define ACPI_RESTAG_DMA "_DMA" + #define ACPI_RESTAG_DMATYPE "_TYP" /* Compatible(0), A(1), B(2), F(3) */ ++#define ACPI_RESTAG_DRIVESTRENGTH "_DRS" ++#define ACPI_RESTAG_ENDIANNESS "_END" ++#define ACPI_RESTAG_FLOWCONTROL "_FLC" + #define ACPI_RESTAG_GRANULARITY "_GRA" + #define ACPI_RESTAG_INTERRUPT "_INT" + #define ACPI_RESTAG_INTERRUPTLEVEL "_LL_" /* active_lo(1), active_hi(0) */ + #define ACPI_RESTAG_INTERRUPTSHARE "_SHR" /* Shareable(1), no_share(0) */ + #define ACPI_RESTAG_INTERRUPTTYPE "_HE_" /* Edge(1), Level(0) */ ++#define ACPI_RESTAG_IORESTRICTION "_IOR" + #define ACPI_RESTAG_LENGTH "_LEN" ++#define ACPI_RESTAG_LINE "_LIN" + #define ACPI_RESTAG_MEMATTRIBUTES "_MTP" /* Memory(0), Reserved(1), ACPI(2), NVS(3) */ + #define ACPI_RESTAG_MEMTYPE "_MEM" /* non_cache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */ + #define ACPI_RESTAG_MAXADDR "_MAX" + #define ACPI_RESTAG_MINADDR "_MIN" + #define ACPI_RESTAG_MAXTYPE "_MAF" + #define ACPI_RESTAG_MINTYPE "_MIF" ++#define ACPI_RESTAG_MODE "_MOD" ++#define ACPI_RESTAG_PARITY "_PAR" ++#define ACPI_RESTAG_PHASE "_PHA" ++#define ACPI_RESTAG_PIN "_PIN" ++#define ACPI_RESTAG_PINCONFIG "_PPI" ++#define ACPI_RESTAG_POLARITY "_POL" + #define ACPI_RESTAG_REGISTERBITOFFSET "_RBO" + #define ACPI_RESTAG_REGISTERBITWIDTH "_RBW" + #define ACPI_RESTAG_RANGETYPE "_RNG" + #define ACPI_RESTAG_READWRITETYPE "_RW_" /* read_only(0), Writeable (1) */ ++#define ACPI_RESTAG_LENGTH_RX "_RXL" ++#define ACPI_RESTAG_LENGTH_TX "_TXL" ++#define ACPI_RESTAG_SLAVEMODE "_SLV" ++#define ACPI_RESTAG_SPEED "_SPE" ++#define ACPI_RESTAG_STOPBITS "_STB" + #define ACPI_RESTAG_TRANSLATION "_TRA" + #define ACPI_RESTAG_TRANSTYPE "_TRS" /* Sparse(1), Dense(0) */ + #define ACPI_RESTAG_TYPE "_TTP" /* Translation(1), Static (0) */ + #define ACPI_RESTAG_XFERTYPE "_SIZ" /* 8(0), 8_and16(1), 16(2) */ ++#define ACPI_RESTAG_VENDORDATA "_VEN" + + /* Default sizes for "small" resource descriptors */ + +@@ -90,6 +109,7 @@ + #define ASL_RDESC_END_DEPEND_SIZE 0x00 + #define ASL_RDESC_IO_SIZE 0x07 + #define ASL_RDESC_FIXED_IO_SIZE 0x03 ++#define ASL_RDESC_FIXED_DMA_SIZE 0x05 + #define ASL_RDESC_END_TAG_SIZE 0x01 + + struct asl_resource_node { +@@ -164,6 +184,12 @@ + AML_RESOURCE_SMALL_HEADER_COMMON u8 checksum; + }; + ++struct aml_resource_fixed_dma { ++ AML_RESOURCE_SMALL_HEADER_COMMON u16 request_lines; ++ u16 channels; ++ u8 width; ++}; ++ + /* + * LARGE descriptors + */ +@@ -263,6 +289,110 @@ + u64 address; + }; + ++/* Common descriptor for gpio_int and gpio_io (ACPI 5.0) */ ++ ++struct aml_resource_gpio { ++ AML_RESOURCE_LARGE_HEADER_COMMON u8 revision_id; ++ u8 connection_type; ++ u16 flags; ++ u16 int_flags; ++ u8 pin_config; ++ u16 drive_strength; ++ u16 debounce_timeout; ++ u16 pin_table_offset; ++ u8 res_source_index; ++ u16 res_source_offset; ++ u16 vendor_offset; ++ u16 vendor_length; ++ /* ++ * Optional fields follow immediately: ++ * 1) PIN list (Words) ++ * 2) Resource Source String ++ * 3) Vendor Data bytes ++ */ ++}; ++ ++#define AML_RESOURCE_GPIO_REVISION 1 /* ACPI 5.0 */ ++ ++/* Values for connection_type above */ ++ ++#define AML_RESOURCE_GPIO_TYPE_INT 0 ++#define AML_RESOURCE_GPIO_TYPE_IO 1 ++#define AML_RESOURCE_MAX_GPIOTYPE 1 ++ ++/* Common preamble for all serial descriptors (ACPI 5.0) */ ++ ++#define AML_RESOURCE_SERIAL_COMMON \ ++ u8 revision_id; \ ++ u8 res_source_index; \ ++ u8 type; \ ++ u8 flags; \ ++ u16 type_specific_flags; \ ++ u8 type_revision_id; \ ++ u16 type_data_length; \ ++ ++/* Values for the type field above */ ++ ++#define AML_RESOURCE_I2C_SERIALBUSTYPE 1 ++#define AML_RESOURCE_SPI_SERIALBUSTYPE 2 ++#define AML_RESOURCE_UART_SERIALBUSTYPE 3 ++#define AML_RESOURCE_MAX_SERIALBUSTYPE 3 ++#define AML_RESOURCE_VENDOR_SERIALBUSTYPE 192 /* Vendor defined is 0xC0-0xFF (NOT SUPPORTED) */ ++ ++struct aml_resource_common_serialbus { ++AML_RESOURCE_LARGE_HEADER_COMMON AML_RESOURCE_SERIAL_COMMON}; ++ ++struct aml_resource_i2c_serialbus { ++ AML_RESOURCE_LARGE_HEADER_COMMON ++ AML_RESOURCE_SERIAL_COMMON u32 connection_speed; ++ u16 slave_address; ++ /* ++ * Optional fields follow immediately: ++ * 1) Vendor Data bytes ++ * 2) Resource Source String ++ */ ++}; ++ ++#define AML_RESOURCE_I2C_REVISION 1 /* ACPI 5.0 */ ++#define AML_RESOURCE_I2C_TYPE_REVISION 1 /* ACPI 5.0 */ ++#define AML_RESOURCE_I2C_MIN_DATA_LEN 6 ++ ++struct aml_resource_spi_serialbus { ++ AML_RESOURCE_LARGE_HEADER_COMMON ++ AML_RESOURCE_SERIAL_COMMON u32 connection_speed; ++ u8 data_bit_length; ++ u8 clock_phase; ++ u8 clock_polarity; ++ u16 device_selection; ++ /* ++ * Optional fields follow immediately: ++ * 1) Vendor Data bytes ++ * 2) Resource Source String ++ */ ++}; ++ ++#define AML_RESOURCE_SPI_REVISION 1 /* ACPI 5.0 */ ++#define AML_RESOURCE_SPI_TYPE_REVISION 1 /* ACPI 5.0 */ ++#define AML_RESOURCE_SPI_MIN_DATA_LEN 9 ++ ++struct aml_resource_uart_serialbus { ++ AML_RESOURCE_LARGE_HEADER_COMMON ++ AML_RESOURCE_SERIAL_COMMON u32 default_baud_rate; ++ u16 rx_fifo_size; ++ u16 tx_fifo_size; ++ u8 parity; ++ u8 lines_enabled; ++ /* ++ * Optional fields follow immediately: ++ * 1) Vendor Data bytes ++ * 2) Resource Source String ++ */ ++}; ++ ++#define AML_RESOURCE_UART_REVISION 1 /* ACPI 5.0 */ ++#define AML_RESOURCE_UART_TYPE_REVISION 1 /* ACPI 5.0 */ ++#define AML_RESOURCE_UART_MIN_DATA_LEN 10 ++ + /* restore default alignment */ + + #pragma pack() +@@ -284,6 +414,7 @@ + struct aml_resource_end_dependent end_dpf; + struct aml_resource_io io; + struct aml_resource_fixed_io fixed_io; ++ struct aml_resource_fixed_dma fixed_dma; + struct aml_resource_vendor_small vendor_small; + struct aml_resource_end_tag end_tag; + +@@ -299,6 +430,11 @@ + struct aml_resource_address64 address64; + struct aml_resource_extended_address64 ext_address64; + struct aml_resource_extended_irq extended_irq; ++ struct aml_resource_gpio gpio; ++ struct aml_resource_i2c_serialbus i2c_serial_bus; ++ struct aml_resource_spi_serialbus spi_serial_bus; ++ struct aml_resource_uart_serialbus uart_serial_bus; ++ struct aml_resource_common_serialbus common_serial_bus; + + /* Utility overlays */ + +diff -Naur linux-3.2.16/drivers/acpi/acpica/dsfield.c linux-3.2.16.patch/drivers/acpi/acpica/dsfield.c +--- linux-3.2.16/drivers/acpi/acpica/dsfield.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/dsfield.c 2012-04-23 06:05:41.409124478 +0200 +@@ -221,6 +221,7 @@ + { + acpi_status status; + u64 position; ++ union acpi_parse_object *child; + + ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info); + +@@ -232,10 +233,11 @@ + + while (arg) { + /* +- * Three types of field elements are handled: +- * 1) Offset - specifies a bit offset +- * 2) access_as - changes the access mode +- * 3) Name - Enters a new named field into the namespace ++ * Four types of field elements are handled: ++ * 1) Name - Enters a new named field into the namespace ++ * 2) Offset - specifies a bit offset ++ * 3) access_as - changes the access mode/attributes ++ * 4) Connection - Associate a resource template with the field + */ + switch (arg->common.aml_opcode) { + case AML_INT_RESERVEDFIELD_OP: +@@ -253,21 +255,70 @@ + break; + + case AML_INT_ACCESSFIELD_OP: +- ++ case AML_INT_EXTACCESSFIELD_OP: + /* +- * Get a new access_type and access_attribute -- to be used for all +- * field units that follow, until field end or another access_as +- * keyword. ++ * Get new access_type, access_attribute, and access_length fields ++ * -- to be used for all field units that follow, until the ++ * end-of-field or another access_as keyword is encountered. ++ * NOTE. These three bytes are encoded in the integer value ++ * of the parseop for convenience. + * + * In field_flags, preserve the flag bits other than the +- * ACCESS_TYPE bits ++ * ACCESS_TYPE bits. + */ ++ ++ /* access_type (byte_acc, word_acc, etc.) */ ++ + info->field_flags = (u8) + ((info-> + field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | +- ((u8) ((u32) arg->common.value.integer >> 8))); ++ ((u8)((u32)(arg->common.value.integer & 0x07)))); ++ ++ /* access_attribute (attrib_quick, attrib_byte, etc.) */ ++ ++ info->attribute = ++ (u8)((arg->common.value.integer >> 8) & 0xFF); ++ ++ /* access_length (for serial/buffer protocols) */ + +- info->attribute = (u8) (arg->common.value.integer); ++ info->access_length = ++ (u8)((arg->common.value.integer >> 16) & 0xFF); ++ break; ++ ++ case AML_INT_CONNECTION_OP: ++ /* ++ * Clear any previous connection. New connection is used for all ++ * fields that follow, similar to access_as ++ */ ++ info->resource_buffer = NULL; ++ info->connection_node = NULL; ++ ++ /* ++ * A Connection() is either an actual resource descriptor (buffer) ++ * or a named reference to a resource template ++ */ ++ child = arg->common.value.arg; ++ if (child->common.aml_opcode == AML_INT_BYTELIST_OP) { ++ info->resource_buffer = child->named.data; ++ info->resource_length = ++ (u16)child->named.value.integer; ++ } else { ++ /* Lookup the Connection() namepath, it should already exist */ ++ ++ status = acpi_ns_lookup(walk_state->scope_info, ++ child->common.value. ++ name, ACPI_TYPE_ANY, ++ ACPI_IMODE_EXECUTE, ++ ACPI_NS_DONT_OPEN_SCOPE, ++ walk_state, ++ &info->connection_node); ++ if (ACPI_FAILURE(status)) { ++ ACPI_ERROR_NAMESPACE(child->common. ++ value.name, ++ status); ++ return_ACPI_STATUS(status); ++ } ++ } + break; + + case AML_INT_NAMEDFIELD_OP: +@@ -374,6 +425,8 @@ + } + } + ++ ACPI_MEMSET(&info, 0, sizeof(struct acpi_create_field_info)); ++ + /* Second arg is the field flags */ + + arg = arg->common.next; +@@ -386,7 +439,6 @@ + info.region_node = region_node; + + status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); +- + return_ACPI_STATUS(status); + } + +@@ -474,8 +526,8 @@ + */ + while (arg) { + /* +- * Ignore OFFSET and ACCESSAS terms here; we are only interested in the +- * field names in order to enter them into the namespace. ++ * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested ++ * in the field names in order to enter them into the namespace. + */ + if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { + status = acpi_ns_lookup(walk_state->scope_info, +@@ -651,6 +703,5 @@ + info.region_node = region_node; + + status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); +- + return_ACPI_STATUS(status); + } +diff -Naur linux-3.2.16/drivers/acpi/acpica/evevent.c linux-3.2.16.patch/drivers/acpi/acpica/evevent.c +--- linux-3.2.16/drivers/acpi/acpica/evevent.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/evevent.c 2012-04-23 06:05:41.409124478 +0200 +@@ -71,6 +71,12 @@ + + ACPI_FUNCTION_TRACE(ev_initialize_events); + ++ /* If Hardware Reduced flag is set, there are no fixed events */ ++ ++ if (acpi_gbl_reduced_hardware) { ++ return_ACPI_STATUS(AE_OK); ++ } ++ + /* + * Initialize the Fixed and General Purpose Events. This is done prior to + * enabling SCIs to prevent interrupts from occurring before the handlers +@@ -111,6 +117,12 @@ + + ACPI_FUNCTION_TRACE(ev_install_xrupt_handlers); + ++ /* If Hardware Reduced flag is set, there is no ACPI h/w */ ++ ++ if (acpi_gbl_reduced_hardware) { ++ return_ACPI_STATUS(AE_OK); ++ } ++ + /* Install the SCI handler */ + + status = acpi_ev_install_sci_handler(); +diff -Naur linux-3.2.16/drivers/acpi/acpica/evglock.c linux-3.2.16.patch/drivers/acpi/acpica/evglock.c +--- linux-3.2.16/drivers/acpi/acpica/evglock.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/evglock.c 2012-04-23 06:05:41.410124498 +0200 +@@ -70,6 +70,12 @@ + + ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); + ++ /* If Hardware Reduced flag is set, there is no global lock */ ++ ++ if (acpi_gbl_reduced_hardware) { ++ return_ACPI_STATUS(AE_OK); ++ } ++ + /* Attempt installation of the global lock handler */ + + status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, +diff -Naur linux-3.2.16/drivers/acpi/acpica/evregion.c linux-3.2.16.patch/drivers/acpi/acpica/evregion.c +--- linux-3.2.16/drivers/acpi/acpica/evregion.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/evregion.c 2012-04-23 06:05:41.411124518 +0200 +@@ -329,6 +329,7 @@ + * FUNCTION: acpi_ev_address_space_dispatch + * + * PARAMETERS: region_obj - Internal region object ++ * field_obj - Corresponding field. Can be NULL. + * Function - Read or Write operation + * region_offset - Where in the region to read or write + * bit_width - Field width in bits (8, 16, 32, or 64) +@@ -344,6 +345,7 @@ + + acpi_status + acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, ++ union acpi_operand_object *field_obj, + u32 function, + u32 region_offset, u32 bit_width, u64 *value) + { +@@ -353,6 +355,7 @@ + union acpi_operand_object *handler_desc; + union acpi_operand_object *region_obj2; + void *region_context = NULL; ++ struct acpi_connection_info *context; + + ACPI_FUNCTION_TRACE(ev_address_space_dispatch); + +@@ -375,6 +378,8 @@ + return_ACPI_STATUS(AE_NOT_EXIST); + } + ++ context = handler_desc->address_space.context; ++ + /* + * It may be the case that the region has never been initialized. + * Some types of regions require special init code +@@ -404,8 +409,7 @@ + acpi_ex_exit_interpreter(); + + status = region_setup(region_obj, ACPI_REGION_ACTIVATE, +- handler_desc->address_space.context, +- ®ion_context); ++ context, ®ion_context); + + /* Re-enter the interpreter */ + +@@ -455,6 +459,25 @@ + acpi_ut_get_region_name(region_obj->region. + space_id))); + ++ /* ++ * Special handling for generic_serial_bus and general_purpose_io: ++ * There are three extra parameters that must be passed to the ++ * handler via the context: ++ * 1) Connection buffer, a resource template from Connection() op. ++ * 2) Length of the above buffer. ++ * 3) Actual access length from the access_as() op. ++ */ ++ if (((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) || ++ (region_obj->region.space_id == ACPI_ADR_SPACE_GPIO)) && ++ context && field_obj) { ++ ++ /* Get the Connection (resource_template) buffer */ ++ ++ context->connection = field_obj->field.resource_buffer; ++ context->length = field_obj->field.resource_length; ++ context->access_length = field_obj->field.access_length; ++ } ++ + if (!(handler_desc->address_space.handler_flags & + ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { + /* +@@ -469,7 +492,7 @@ + + status = handler(function, + (region_obj->region.address + region_offset), +- bit_width, value, handler_desc->address_space.context, ++ bit_width, value, context, + region_obj2->extra.region_context); + + if (ACPI_FAILURE(status)) { +diff -Naur linux-3.2.16/drivers/acpi/acpica/exconfig.c linux-3.2.16.patch/drivers/acpi/acpica/exconfig.c +--- linux-3.2.16/drivers/acpi/acpica/exconfig.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/exconfig.c 2012-04-23 06:05:41.412124538 +0200 +@@ -297,9 +297,9 @@ + /* Bytewise reads */ + + for (i = 0; i < length; i++) { +- status = acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, +- region_offset, 8, +- &value); ++ status = ++ acpi_ev_address_space_dispatch(obj_desc, NULL, ACPI_READ, ++ region_offset, 8, &value); + if (ACPI_FAILURE(status)) { + return status; + } +diff -Naur linux-3.2.16/drivers/acpi/acpica/excreate.c linux-3.2.16.patch/drivers/acpi/acpica/excreate.c +--- linux-3.2.16/drivers/acpi/acpica/excreate.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/excreate.c 2012-04-23 06:10:20.640734230 +0200 +@@ -267,7 +267,7 @@ + * + * PARAMETERS: aml_start - Pointer to the region declaration AML + * aml_length - Max length of the declaration AML +- * region_space - space_iD for the region ++ * space_id - Address space ID for the region + * walk_state - Current state + * + * RETURN: Status +@@ -279,7 +279,7 @@ + acpi_status + acpi_ex_create_region(u8 * aml_start, + u32 aml_length, +- u8 region_space, struct acpi_walk_state *walk_state) ++ u8 space_id, struct acpi_walk_state *walk_state) + { + acpi_status status; + union acpi_operand_object *obj_desc; +@@ -304,16 +304,19 @@ + * Space ID must be one of the predefined IDs, or in the user-defined + * range + */ +- if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) && +- (region_space < ACPI_USER_REGION_BEGIN) && +- (region_space != ACPI_ADR_SPACE_DATA_TABLE)) { +- ACPI_ERROR((AE_INFO, "Invalid AddressSpace type 0x%X", +- region_space)); +- return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); ++ if (!acpi_is_valid_space_id(space_id)) { ++ /* ++ * Print an error message, but continue. We don't want to abort ++ * a table load for this exception. Instead, if the region is ++ * actually used at runtime, abort the executing method. ++ */ ++ ACPI_ERROR((AE_INFO, ++ "Invalid/unknown Address Space ID: 0x%2.2X", ++ space_id)); + } + + ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "Region Type - %s (0x%X)\n", +- acpi_ut_get_region_name(region_space), region_space)); ++ acpi_ut_get_region_name(space_id), space_id)); + + /* Create the region descriptor */ + +@@ -339,7 +342,7 @@ + + /* Init the region from the operands */ + +- obj_desc->region.space_id = region_space; ++ obj_desc->region.space_id = space_id; + obj_desc->region.address = 0; + obj_desc->region.length = 0; + obj_desc->region.node = node; +diff -Naur linux-3.2.16/drivers/acpi/acpica/exdump.c linux-3.2.16.patch/drivers/acpi/acpica/exdump.c +--- linux-3.2.16/drivers/acpi/acpica/exdump.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/exdump.c 2012-04-23 06:05:41.414124579 +0200 +@@ -192,10 +192,13 @@ + "Buffer Object"} + }; + +-static struct acpi_exdump_info acpi_ex_dump_region_field[3] = { ++static struct acpi_exdump_info acpi_ex_dump_region_field[5] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region_field), NULL}, + {ACPI_EXD_FIELD, 0, NULL}, +- {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.region_obj), "Region Object"} ++ {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(field.access_length), "AccessLength"}, ++ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.region_obj), "Region Object"}, ++ {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.resource_buffer), ++ "ResourceBuffer"} + }; + + static struct acpi_exdump_info acpi_ex_dump_bank_field[5] = { +diff -Naur linux-3.2.16/drivers/acpi/acpica/exfield.c linux-3.2.16.patch/drivers/acpi/acpica/exfield.c +--- linux-3.2.16/drivers/acpi/acpica/exfield.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/exfield.c 2012-04-23 06:05:41.414124579 +0200 +@@ -100,18 +100,25 @@ + (obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_SMBUS + || obj_desc->field.region_obj->region.space_id == ++ ACPI_ADR_SPACE_GSBUS ++ || obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_IPMI)) { + /* +- * This is an SMBus or IPMI read. We must create a buffer to hold ++ * This is an SMBus, GSBus or IPMI read. We must create a buffer to hold + * the data and then directly access the region handler. + * +- * Note: Smbus protocol value is passed in upper 16-bits of Function ++ * Note: SMBus and GSBus protocol value is passed in upper 16-bits of Function + */ + if (obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_SMBUS) { + length = ACPI_SMBUS_BUFFER_SIZE; + function = + ACPI_READ | (obj_desc->field.attribute << 16); ++ } else if (obj_desc->field.region_obj->region.space_id == ++ ACPI_ADR_SPACE_GSBUS) { ++ length = ACPI_GSBUS_BUFFER_SIZE; ++ function = ++ ACPI_READ | (obj_desc->field.attribute << 16); + } else { /* IPMI */ + + length = ACPI_IPMI_BUFFER_SIZE; +@@ -248,21 +255,23 @@ + (obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_SMBUS + || obj_desc->field.region_obj->region.space_id == ++ ACPI_ADR_SPACE_GSBUS ++ || obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_IPMI)) { + /* +- * This is an SMBus or IPMI write. We will bypass the entire field ++ * This is an SMBus, GSBus or IPMI write. We will bypass the entire field + * mechanism and handoff the buffer directly to the handler. For + * these address spaces, the buffer is bi-directional; on a write, + * return data is returned in the same buffer. + * + * Source must be a buffer of sufficient size: +- * ACPI_SMBUS_BUFFER_SIZE or ACPI_IPMI_BUFFER_SIZE. ++ * ACPI_SMBUS_BUFFER_SIZE, ACPI_GSBUS_BUFFER_SIZE, or ACPI_IPMI_BUFFER_SIZE. + * +- * Note: SMBus protocol type is passed in upper 16-bits of Function ++ * Note: SMBus and GSBus protocol type is passed in upper 16-bits of Function + */ + if (source_desc->common.type != ACPI_TYPE_BUFFER) { + ACPI_ERROR((AE_INFO, +- "SMBus or IPMI write requires Buffer, found type %s", ++ "SMBus/IPMI/GenericSerialBus write requires Buffer, found type %s", + acpi_ut_get_object_type_name(source_desc))); + + return_ACPI_STATUS(AE_AML_OPERAND_TYPE); +@@ -273,6 +282,11 @@ + length = ACPI_SMBUS_BUFFER_SIZE; + function = + ACPI_WRITE | (obj_desc->field.attribute << 16); ++ } else if (obj_desc->field.region_obj->region.space_id == ++ ACPI_ADR_SPACE_GSBUS) { ++ length = ACPI_GSBUS_BUFFER_SIZE; ++ function = ++ ACPI_WRITE | (obj_desc->field.attribute << 16); + } else { /* IPMI */ + + length = ACPI_IPMI_BUFFER_SIZE; +@@ -281,7 +295,7 @@ + + if (source_desc->buffer.length < length) { + ACPI_ERROR((AE_INFO, +- "SMBus or IPMI write requires Buffer of length %u, found length %u", ++ "SMBus/IPMI/GenericSerialBus write requires Buffer of length %u, found length %u", + length, source_desc->buffer.length)); + + return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); +diff -Naur linux-3.2.16/drivers/acpi/acpica/exfldio.c linux-3.2.16.patch/drivers/acpi/acpica/exfldio.c +--- linux-3.2.16/drivers/acpi/acpica/exfldio.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/exfldio.c 2012-04-23 06:05:41.415124599 +0200 +@@ -86,6 +86,7 @@ + { + acpi_status status = AE_OK; + union acpi_operand_object *rgn_desc; ++ u8 space_id; + + ACPI_FUNCTION_TRACE_U32(ex_setup_region, field_datum_byte_offset); + +@@ -101,6 +102,17 @@ + return_ACPI_STATUS(AE_AML_OPERAND_TYPE); + } + ++ space_id = rgn_desc->region.space_id; ++ ++ /* Validate the Space ID */ ++ ++ if (!acpi_is_valid_space_id(space_id)) { ++ ACPI_ERROR((AE_INFO, ++ "Invalid/unknown Address Space ID: 0x%2.2X", ++ space_id)); ++ return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); ++ } ++ + /* + * If the Region Address and Length have not been previously evaluated, + * evaluate them now and save the results. +@@ -119,11 +131,12 @@ + } + + /* +- * Exit now for SMBus or IPMI address space, it has a non-linear ++ * Exit now for SMBus, GSBus or IPMI address space, it has a non-linear + * address space and the request cannot be directly validated + */ +- if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || +- rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { ++ if (space_id == ACPI_ADR_SPACE_SMBUS || ++ space_id == ACPI_ADR_SPACE_GSBUS || ++ space_id == ACPI_ADR_SPACE_IPMI) { + + /* SMBus or IPMI has a non-linear address space */ + +@@ -271,11 +284,12 @@ + + /* Invoke the appropriate address_space/op_region handler */ + +- status = +- acpi_ev_address_space_dispatch(rgn_desc, function, region_offset, +- ACPI_MUL_8(obj_desc->common_field. +- access_byte_width), +- value); ++ status = acpi_ev_address_space_dispatch(rgn_desc, obj_desc, ++ function, region_offset, ++ ACPI_MUL_8(obj_desc-> ++ common_field. ++ access_byte_width), ++ value); + + if (ACPI_FAILURE(status)) { + if (status == AE_NOT_IMPLEMENTED) { +@@ -316,6 +330,7 @@ + static u8 + acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value) + { ++ ACPI_FUNCTION_NAME(ex_register_overflow); + + if (obj_desc->common_field.bit_length >= ACPI_INTEGER_BIT_SIZE) { + /* +@@ -330,6 +345,11 @@ + * The Value is larger than the maximum value that can fit into + * the register. + */ ++ ACPI_ERROR((AE_INFO, ++ "Index value 0x%8.8X%8.8X overflows field width 0x%X", ++ ACPI_FORMAT_UINT64(value), ++ obj_desc->common_field.bit_length)); ++ + return (TRUE); + } + +diff -Naur linux-3.2.16/drivers/acpi/acpica/exprep.c linux-3.2.16.patch/drivers/acpi/acpica/exprep.c +--- linux-3.2.16/drivers/acpi/acpica/exprep.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/exprep.c 2012-04-23 06:05:41.416124619 +0200 +@@ -47,6 +47,7 @@ + #include "acinterp.h" + #include "amlcode.h" + #include "acnamesp.h" ++#include "acdispat.h" + + #define _COMPONENT ACPI_EXECUTER + ACPI_MODULE_NAME("exprep") +@@ -455,6 +456,30 @@ + obj_desc->field.region_obj = + acpi_ns_get_attached_object(info->region_node); + ++ /* Fields specific to generic_serial_bus fields */ ++ ++ obj_desc->field.access_length = info->access_length; ++ ++ if (info->connection_node) { ++ second_desc = info->connection_node->object; ++ if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) { ++ status = ++ acpi_ds_get_buffer_arguments(second_desc); ++ if (ACPI_FAILURE(status)) { ++ acpi_ut_delete_object_desc(obj_desc); ++ return_ACPI_STATUS(status); ++ } ++ } ++ ++ obj_desc->field.resource_buffer = ++ second_desc->buffer.pointer; ++ obj_desc->field.resource_length = ++ (u16)second_desc->buffer.length; ++ } else if (info->resource_buffer) { ++ obj_desc->field.resource_buffer = info->resource_buffer; ++ obj_desc->field.resource_length = info->resource_length; ++ } ++ + /* Allow full data read from EC address space */ + + if ((obj_desc->field.region_obj->region.space_id == +diff -Naur linux-3.2.16/drivers/acpi/acpica/exutils.c linux-3.2.16.patch/drivers/acpi/acpica/exutils.c +--- linux-3.2.16/drivers/acpi/acpica/exutils.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/exutils.c 2012-04-23 06:05:41.417124639 +0200 +@@ -435,4 +435,29 @@ + } + } + ++/******************************************************************************* ++ * ++ * FUNCTION: acpi_is_valid_space_id ++ * ++ * PARAMETERS: space_id - ID to be validated ++ * ++ * RETURN: TRUE if valid/supported ID. ++ * ++ * DESCRIPTION: Validate an operation region space_iD. ++ * ++ ******************************************************************************/ ++ ++u8 acpi_is_valid_space_id(u8 space_id) ++{ ++ ++ if ((space_id >= ACPI_NUM_PREDEFINED_REGIONS) && ++ (space_id < ACPI_USER_REGION_BEGIN) && ++ (space_id != ACPI_ADR_SPACE_DATA_TABLE) && ++ (space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { ++ return (FALSE); ++ } ++ ++ return (TRUE); ++} ++ + #endif +diff -Naur linux-3.2.16/drivers/acpi/acpica/hwvalid.c linux-3.2.16.patch/drivers/acpi/acpica/hwvalid.c +--- linux-3.2.16/drivers/acpi/acpica/hwvalid.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/hwvalid.c 2012-04-23 06:05:41.417124639 +0200 +@@ -134,6 +134,8 @@ + /* Supported widths are 8/16/32 */ + + if ((bit_width != 8) && (bit_width != 16) && (bit_width != 32)) { ++ ACPI_ERROR((AE_INFO, ++ "Bad BitWidth parameter: %8.8X", bit_width)); + return AE_BAD_PARAMETER; + } + +diff -Naur linux-3.2.16/drivers/acpi/acpica/Makefile linux-3.2.16.patch/drivers/acpi/acpica/Makefile +--- linux-3.2.16/drivers/acpi/acpica/Makefile 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/Makefile 2012-04-23 06:05:41.418124659 +0200 +@@ -8,41 +8,150 @@ + # use acpi.o to put all files here into acpi.o modparam namespace + obj-y += acpi.o + +-acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ +- dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ +- dsinit.o dsargs.o dscontrol.o dswload2.o +- +-acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ +- evmisc.o evrgnini.o evxface.o evxfregn.o \ +- evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o evxfgpe.o evglock.o +- +-acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ +- exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ +- excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ +- exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o exdebug.o +- +-acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o hwpci.o ++acpi-y := \ ++ dsargs.o \ ++ dscontrol.o \ ++ dsfield.o \ ++ dsinit.o \ ++ dsmethod.o \ ++ dsmthdat.o \ ++ dsobject.o \ ++ dsopcode.o \ ++ dsutils.o \ ++ dswexec.o \ ++ dswload.o \ ++ dswload2.o \ ++ dswscope.o \ ++ dswstate.o ++ ++acpi-y += \ ++ evevent.o \ ++ evgpe.o \ ++ evgpeblk.o \ ++ evgpeinit.o \ ++ evgpeutil.o \ ++ evglock.o \ ++ evmisc.o \ ++ evregion.o \ ++ evrgnini.o \ ++ evsci.o \ ++ evxface.o \ ++ evxfevnt.o \ ++ evxfgpe.o \ ++ evxfregn.o ++ ++acpi-y += \ ++ exconfig.o \ ++ exconvrt.o \ ++ excreate.o \ ++ exdebug.o \ ++ exdump.o \ ++ exfield.o \ ++ exfldio.o \ ++ exmutex.o \ ++ exnames.o \ ++ exoparg1.o \ ++ exoparg2.o \ ++ exoparg3.o \ ++ exoparg6.o \ ++ exprep.o \ ++ exmisc.o \ ++ exregion.o \ ++ exresnte.o \ ++ exresolv.o \ ++ exresop.o \ ++ exstore.o \ ++ exstoren.o \ ++ exstorob.o \ ++ exsystem.o \ ++ exutils.o ++ ++acpi-y += \ ++ hwacpi.o \ ++ hwgpe.o \ ++ hwpci.o \ ++ hwregs.o \ ++ hwsleep.o \ ++ hwvalid.o \ ++ hwxface.o + + acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o + +-acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ +- nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ +- nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ +- nsparse.o nspredef.o nsrepair.o nsrepair2.o ++acpi-y += \ ++ nsaccess.o \ ++ nsalloc.o \ ++ nsdump.o \ ++ nseval.o \ ++ nsinit.o \ ++ nsload.o \ ++ nsnames.o \ ++ nsobject.o \ ++ nsparse.o \ ++ nspredef.o \ ++ nsrepair.o \ ++ nsrepair2.o \ ++ nssearch.o \ ++ nsutils.o \ ++ nswalk.o \ ++ nsxfeval.o \ ++ nsxfname.o \ ++ nsxfobj.o + + acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o + +-acpi-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \ +- psopcode.o psscope.o psutils.o psxface.o +- +-acpi-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ +- rscalc.o rsirq.o rsmemory.o rsutils.o ++acpi-y += \ ++ psargs.o \ ++ psloop.o \ ++ psopcode.o \ ++ psparse.o \ ++ psscope.o \ ++ pstree.o \ ++ psutils.o \ ++ pswalk.o \ ++ psxface.o ++ ++acpi-y += \ ++ rsaddr.o \ ++ rscalc.o \ ++ rscreate.o \ ++ rsinfo.o \ ++ rsio.o \ ++ rsirq.o \ ++ rslist.o \ ++ rsmemory.o \ ++ rsmisc.o \ ++ rsserial.o \ ++ rsutils.o \ ++ rsxface.o + + acpi-$(ACPI_FUTURE_USAGE) += rsdump.o + +-acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o +- +-acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ +- utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ +- utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o \ +- utosi.o utxferror.o utdecode.o ++acpi-y += \ ++ tbfadt.o \ ++ tbfind.o \ ++ tbinstal.o \ ++ tbutils.o \ ++ tbxface.o \ ++ tbxfroot.o ++ ++acpi-y += \ ++ utalloc.o \ ++ utcopy.o \ ++ utdebug.o \ ++ utdecode.o \ ++ utdelete.o \ ++ uteval.o \ ++ utglobal.o \ ++ utids.o \ ++ utinit.o \ ++ utlock.o \ ++ utmath.o \ ++ utmisc.o \ ++ utmutex.o \ ++ utobject.o \ ++ utosi.o \ ++ utresrc.o \ ++ utstate.o \ ++ utxface.o \ ++ utxferror.o \ ++ utxfmutex.o +diff -Naur linux-3.2.16/drivers/acpi/acpica/nspredef.c linux-3.2.16.patch/drivers/acpi/acpica/nspredef.c +--- linux-3.2.16/drivers/acpi/acpica/nspredef.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/nspredef.c 2012-04-23 06:05:41.419124679 +0200 +@@ -620,6 +620,7 @@ + case ACPI_PTYPE2_FIXED: + case ACPI_PTYPE2_MIN: + case ACPI_PTYPE2_COUNT: ++ case ACPI_PTYPE2_FIX_VAR: + + /* + * These types all return a single Package that consists of a +@@ -757,6 +758,34 @@ + if (ACPI_FAILURE(status)) { + return (status); + } ++ break; ++ ++ case ACPI_PTYPE2_FIX_VAR: ++ /* ++ * Each subpackage has a fixed number of elements and an ++ * optional element ++ */ ++ expected_count = ++ package->ret_info.count1 + package->ret_info.count2; ++ if (sub_package->package.count < expected_count) { ++ goto package_too_small; ++ } ++ ++ status = ++ acpi_ns_check_package_elements(data, sub_elements, ++ package->ret_info. ++ object_type1, ++ package->ret_info. ++ count1, ++ package->ret_info. ++ object_type2, ++ sub_package->package. ++ count - ++ package->ret_info. ++ count1, 0); ++ if (ACPI_FAILURE(status)) { ++ return (status); ++ } + break; + + case ACPI_PTYPE2_FIXED: +diff -Naur linux-3.2.16/drivers/acpi/acpica/nsrepair2.c linux-3.2.16.patch/drivers/acpi/acpica/nsrepair2.c +--- linux-3.2.16/drivers/acpi/acpica/nsrepair2.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/nsrepair2.c 2012-04-23 06:05:41.420124699 +0200 +@@ -467,11 +467,12 @@ + } + + /* +- * Copy and uppercase the string. From the ACPI specification: ++ * Copy and uppercase the string. From the ACPI 5.0 specification: + * + * A valid PNP ID must be of the form "AAA####" where A is an uppercase + * letter and # is a hex digit. A valid ACPI ID must be of the form +- * "ACPI####" where # is a hex digit. ++ * "NNNN####" where N is an uppercase letter or decimal digit, and ++ * # is a hex digit. + */ + for (dest = new_string->string.pointer; *source; dest++, source++) { + *dest = (char)ACPI_TOUPPER(*source); +diff -Naur linux-3.2.16/drivers/acpi/acpica/nsrepair.c linux-3.2.16.patch/drivers/acpi/acpica/nsrepair.c +--- linux-3.2.16/drivers/acpi/acpica/nsrepair.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/nsrepair.c 2012-04-23 06:05:41.421124719 +0200 +@@ -634,6 +634,7 @@ + case ACPI_PTYPE2_FIXED: + case ACPI_PTYPE2_MIN: + case ACPI_PTYPE2_REV_FIXED: ++ case ACPI_PTYPE2_FIX_VAR: + break; + + default: +diff -Naur linux-3.2.16/drivers/acpi/acpica/psargs.c linux-3.2.16.patch/drivers/acpi/acpica/psargs.c +--- linux-3.2.16/drivers/acpi/acpica/psargs.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/psargs.c 2012-04-23 06:05:41.421124719 +0200 +@@ -484,34 +484,54 @@ + static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state + *parser_state) + { +- u32 aml_offset = (u32) +- ACPI_PTR_DIFF(parser_state->aml, +- parser_state->aml_start); ++ u32 aml_offset; + union acpi_parse_object *field; ++ union acpi_parse_object *arg = NULL; + u16 opcode; + u32 name; ++ u8 access_type; ++ u8 access_attribute; ++ u8 access_length; ++ u32 pkg_length; ++ u8 *pkg_end; ++ u32 buffer_length; + + ACPI_FUNCTION_TRACE(ps_get_next_field); + ++ aml_offset = ++ (u32)ACPI_PTR_DIFF(parser_state->aml, parser_state->aml_start); ++ + /* Determine field type */ + + switch (ACPI_GET8(parser_state->aml)) { +- default: ++ case AML_FIELD_OFFSET_OP: + +- opcode = AML_INT_NAMEDFIELD_OP; ++ opcode = AML_INT_RESERVEDFIELD_OP; ++ parser_state->aml++; + break; + +- case 0x00: ++ case AML_FIELD_ACCESS_OP: + +- opcode = AML_INT_RESERVEDFIELD_OP; ++ opcode = AML_INT_ACCESSFIELD_OP; + parser_state->aml++; + break; + +- case 0x01: ++ case AML_FIELD_CONNECTION_OP: + +- opcode = AML_INT_ACCESSFIELD_OP; ++ opcode = AML_INT_CONNECTION_OP; ++ parser_state->aml++; ++ break; ++ ++ case AML_FIELD_EXT_ACCESS_OP: ++ ++ opcode = AML_INT_EXTACCESSFIELD_OP; + parser_state->aml++; + break; ++ ++ default: ++ ++ opcode = AML_INT_NAMEDFIELD_OP; ++ break; + } + + /* Allocate a new field op */ +@@ -549,16 +569,111 @@ + break; + + case AML_INT_ACCESSFIELD_OP: ++ case AML_INT_EXTACCESSFIELD_OP: + + /* + * Get access_type and access_attrib and merge into the field Op +- * access_type is first operand, access_attribute is second ++ * access_type is first operand, access_attribute is second. stuff ++ * these bytes into the node integer value for convenience. + */ +- field->common.value.integer = +- (((u32) ACPI_GET8(parser_state->aml) << 8)); ++ ++ /* Get the two bytes (Type/Attribute) */ ++ ++ access_type = ACPI_GET8(parser_state->aml); + parser_state->aml++; +- field->common.value.integer |= ACPI_GET8(parser_state->aml); ++ access_attribute = ACPI_GET8(parser_state->aml); + parser_state->aml++; ++ ++ field->common.value.integer = (u8)access_type; ++ field->common.value.integer |= (u16)(access_attribute << 8); ++ ++ /* This opcode has a third byte, access_length */ ++ ++ if (opcode == AML_INT_EXTACCESSFIELD_OP) { ++ access_length = ACPI_GET8(parser_state->aml); ++ parser_state->aml++; ++ ++ field->common.value.integer |= ++ (u32)(access_length << 16); ++ } ++ break; ++ ++ case AML_INT_CONNECTION_OP: ++ ++ /* ++ * Argument for Connection operator can be either a Buffer ++ * (resource descriptor), or a name_string. ++ */ ++ if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) { ++ parser_state->aml++; ++ ++ pkg_end = parser_state->aml; ++ pkg_length = ++ acpi_ps_get_next_package_length(parser_state); ++ pkg_end += pkg_length; ++ ++ if (parser_state->aml < pkg_end) { ++ ++ /* Non-empty list */ ++ ++ arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP); ++ if (!arg) { ++ return_PTR(NULL); ++ } ++ ++ /* Get the actual buffer length argument */ ++ ++ opcode = ACPI_GET8(parser_state->aml); ++ parser_state->aml++; ++ ++ switch (opcode) { ++ case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ ++ buffer_length = ++ ACPI_GET8(parser_state->aml); ++ parser_state->aml += 1; ++ break; ++ ++ case AML_WORD_OP: /* AML_WORDDATA_ARG */ ++ buffer_length = ++ ACPI_GET16(parser_state->aml); ++ parser_state->aml += 2; ++ break; ++ ++ case AML_DWORD_OP: /* AML_DWORDATA_ARG */ ++ buffer_length = ++ ACPI_GET32(parser_state->aml); ++ parser_state->aml += 4; ++ break; ++ ++ default: ++ buffer_length = 0; ++ break; ++ } ++ ++ /* Fill in bytelist data */ ++ ++ arg->named.value.size = buffer_length; ++ arg->named.data = parser_state->aml; ++ } ++ ++ /* Skip to End of byte data */ ++ ++ parser_state->aml = pkg_end; ++ } else { ++ arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP); ++ if (!arg) { ++ return_PTR(NULL); ++ } ++ ++ /* Get the Namestring argument */ ++ ++ arg->common.value.name = ++ acpi_ps_get_next_namestring(parser_state); ++ } ++ ++ /* Link the buffer/namestring to parent (CONNECTION_OP) */ ++ ++ acpi_ps_append_arg(field, arg); + break; + + default: +diff -Naur linux-3.2.16/drivers/acpi/acpica/psopcode.c linux-3.2.16.patch/drivers/acpi/acpica/psopcode.c +--- linux-3.2.16/drivers/acpi/acpica/psopcode.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/psopcode.c 2012-04-23 06:05:41.422124739 +0200 +@@ -638,7 +638,16 @@ + + /* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY, + AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R, +- AML_FLAGS_EXEC_0A_0T_1R) ++ AML_FLAGS_EXEC_0A_0T_1R), ++ ++/* ACPI 5.0 opcodes */ ++ ++/* 7F */ ACPI_OP("-ConnectField-", ARGP_CONNECTFIELD_OP, ++ ARGI_CONNECTFIELD_OP, ACPI_TYPE_ANY, ++ AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS), ++/* 80 */ ACPI_OP("-ExtAccessField-", ARGP_CONNECTFIELD_OP, ++ ARGI_CONNECTFIELD_OP, ACPI_TYPE_ANY, ++ AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0) + + /*! [End] no source code translation !*/ + }; +@@ -657,7 +666,7 @@ + /* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, + /* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX, + /* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D, +-/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, ++/* 0x38 */ 0x7F, 0x80, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, + /* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, + /* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, + /* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, +diff -Naur linux-3.2.16/drivers/acpi/acpica/pstree.c linux-3.2.16.patch/drivers/acpi/acpica/pstree.c +--- linux-3.2.16/drivers/acpi/acpica/pstree.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/pstree.c 2012-04-23 06:05:41.423124759 +0200 +@@ -74,6 +74,12 @@ + + ACPI_FUNCTION_ENTRY(); + ++/* ++ if (Op->Common.aml_opcode == AML_INT_CONNECTION_OP) ++ { ++ return (Op->Common.Value.Arg); ++ } ++*/ + /* Get the info structure for this opcode */ + + op_info = acpi_ps_get_opcode_info(op->common.aml_opcode); +diff -Naur linux-3.2.16/drivers/acpi/acpica/rscalc.c linux-3.2.16.patch/drivers/acpi/acpica/rscalc.c +--- linux-3.2.16/drivers/acpi/acpica/rscalc.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/rscalc.c 2012-04-23 06:05:41.424124779 +0200 +@@ -313,6 +313,38 @@ + resource_source)); + break; + ++ case ACPI_RESOURCE_TYPE_GPIO: ++ ++ total_size = ++ (acpi_rs_length) (total_size + ++ (resource->data.gpio. ++ pin_table_length * 2) + ++ resource->data.gpio. ++ resource_source.string_length + ++ resource->data.gpio. ++ vendor_length); ++ ++ break; ++ ++ case ACPI_RESOURCE_TYPE_SERIAL_BUS: ++ ++ total_size = ++ acpi_gbl_aml_resource_serial_bus_sizes[resource-> ++ data. ++ common_serial_bus. ++ type]; ++ ++ total_size = (acpi_rs_length) (total_size + ++ resource->data. ++ i2c_serial_bus. ++ resource_source. ++ string_length + ++ resource->data. ++ i2c_serial_bus. ++ vendor_length); ++ ++ break; ++ + default: + break; + } +@@ -362,10 +394,11 @@ + u32 extra_struct_bytes; + u8 resource_index; + u8 minimum_aml_resource_length; ++ union aml_resource *aml_resource; + + ACPI_FUNCTION_TRACE(rs_get_list_length); + +- *size_needed = 0; ++ *size_needed = ACPI_RS_SIZE_MIN; /* Minimum size is one end_tag */ + end_aml = aml_buffer + aml_buffer_length; + + /* Walk the list of AML resource descriptors */ +@@ -376,9 +409,15 @@ + + status = acpi_ut_validate_resource(aml_buffer, &resource_index); + if (ACPI_FAILURE(status)) { ++ /* ++ * Exit on failure. Cannot continue because the descriptor length ++ * may be bogus also. ++ */ + return_ACPI_STATUS(status); + } + ++ aml_resource = (void *)aml_buffer; ++ + /* Get the resource length and base (minimum) AML size */ + + resource_length = acpi_ut_get_resource_length(aml_buffer); +@@ -422,10 +461,8 @@ + + case ACPI_RESOURCE_NAME_END_TAG: + /* +- * End Tag: +- * This is the normal exit, add size of end_tag ++ * End Tag: This is the normal exit + */ +- *size_needed += ACPI_RS_SIZE_MIN; + return_ACPI_STATUS(AE_OK); + + case ACPI_RESOURCE_NAME_ADDRESS32: +@@ -457,6 +494,33 @@ + minimum_aml_resource_length); + break; + ++ case ACPI_RESOURCE_NAME_GPIO: ++ ++ /* Vendor data is optional */ ++ ++ if (aml_resource->gpio.vendor_length) { ++ extra_struct_bytes += ++ aml_resource->gpio.vendor_offset - ++ aml_resource->gpio.pin_table_offset + ++ aml_resource->gpio.vendor_length; ++ } else { ++ extra_struct_bytes += ++ aml_resource->large_header.resource_length + ++ sizeof(struct aml_resource_large_header) - ++ aml_resource->gpio.pin_table_offset; ++ } ++ break; ++ ++ case ACPI_RESOURCE_NAME_SERIAL_BUS: ++ ++ minimum_aml_resource_length = ++ acpi_gbl_resource_aml_serial_bus_sizes ++ [aml_resource->common_serial_bus.type]; ++ extra_struct_bytes += ++ aml_resource->common_serial_bus.resource_length - ++ minimum_aml_resource_length; ++ break; ++ + default: + break; + } +@@ -467,9 +531,18 @@ + * Important: Round the size up for the appropriate alignment. This + * is a requirement on IA64. + */ +- buffer_size = acpi_gbl_resource_struct_sizes[resource_index] + +- extra_struct_bytes; +- buffer_size = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size); ++ if (acpi_ut_get_resource_type(aml_buffer) == ++ ACPI_RESOURCE_NAME_SERIAL_BUS) { ++ buffer_size = ++ acpi_gbl_resource_struct_serial_bus_sizes ++ [aml_resource->common_serial_bus.type] + ++ extra_struct_bytes; ++ } else { ++ buffer_size = ++ acpi_gbl_resource_struct_sizes[resource_index] + ++ extra_struct_bytes; ++ } ++ buffer_size = (u32)ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size); + + *size_needed += buffer_size; + +diff -Naur linux-3.2.16/drivers/acpi/acpica/rscreate.c linux-3.2.16.patch/drivers/acpi/acpica/rscreate.c +--- linux-3.2.16/drivers/acpi/acpica/rscreate.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/rscreate.c 2012-04-23 06:05:41.424124779 +0200 +@@ -51,6 +51,70 @@ + + /******************************************************************************* + * ++ * FUNCTION: acpi_buffer_to_resource ++ * ++ * PARAMETERS: aml_buffer - Pointer to the resource byte stream ++ * aml_buffer_length - Length of the aml_buffer ++ * resource_ptr - Where the converted resource is returned ++ * ++ * RETURN: Status ++ * ++ * DESCRIPTION: Convert a raw AML buffer to a resource list ++ * ++ ******************************************************************************/ ++acpi_status ++acpi_buffer_to_resource(u8 *aml_buffer, ++ u16 aml_buffer_length, ++ struct acpi_resource **resource_ptr) ++{ ++ acpi_status status; ++ acpi_size list_size_needed; ++ void *resource; ++ void *current_resource_ptr; ++ ++ /* ++ * Note: we allow AE_AML_NO_RESOURCE_END_TAG, since an end tag ++ * is not required here. ++ */ ++ ++ /* Get the required length for the converted resource */ ++ ++ status = acpi_rs_get_list_length(aml_buffer, aml_buffer_length, ++ &list_size_needed); ++ if (status == AE_AML_NO_RESOURCE_END_TAG) { ++ status = AE_OK; ++ } ++ if (ACPI_FAILURE(status)) { ++ return (status); ++ } ++ ++ /* Allocate a buffer for the converted resource */ ++ ++ resource = ACPI_ALLOCATE_ZEROED(list_size_needed); ++ current_resource_ptr = resource; ++ if (!resource) { ++ return (AE_NO_MEMORY); ++ } ++ ++ /* Perform the AML-to-Resource conversion */ ++ ++ status = acpi_ut_walk_aml_resources(aml_buffer, aml_buffer_length, ++ acpi_rs_convert_aml_to_resources, ++ ¤t_resource_ptr); ++ if (status == AE_AML_NO_RESOURCE_END_TAG) { ++ status = AE_OK; ++ } ++ if (ACPI_FAILURE(status)) { ++ ACPI_FREE(resource); ++ } else { ++ *resource_ptr = resource; ++ } ++ ++ return (status); ++} ++ ++/******************************************************************************* ++ * + * FUNCTION: acpi_rs_create_resource_list + * + * PARAMETERS: aml_buffer - Pointer to the resource byte stream +@@ -66,9 +130,10 @@ + * of device resources. + * + ******************************************************************************/ ++ + acpi_status + acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, +- struct acpi_buffer *output_buffer) ++ struct acpi_buffer * output_buffer) + { + + acpi_status status; +diff -Naur linux-3.2.16/drivers/acpi/acpica/rsdump.c linux-3.2.16.patch/drivers/acpi/acpica/rsdump.c +--- linux-3.2.16/drivers/acpi/acpica/rsdump.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/rsdump.c 2012-04-23 06:05:41.425124800 +0200 +@@ -61,11 +61,13 @@ + + static void acpi_rs_out_title(char *title); + +-static void acpi_rs_dump_byte_list(u16 length, u8 * data); ++static void acpi_rs_dump_byte_list(u16 length, u8 *data); + +-static void acpi_rs_dump_dword_list(u8 length, u32 * data); ++static void acpi_rs_dump_word_list(u16 length, u16 *data); + +-static void acpi_rs_dump_short_byte_list(u8 length, u8 * data); ++static void acpi_rs_dump_dword_list(u8 length, u32 *data); ++ ++static void acpi_rs_dump_short_byte_list(u8 length, u8 *data); + + static void + acpi_rs_dump_resource_source(struct acpi_resource_source *resource_source); +@@ -309,6 +311,125 @@ + {ACPI_RSD_UINT64, ACPI_RSD_OFFSET(generic_reg.address), "Address", NULL} + }; + ++struct acpi_rsdump_info acpi_rs_dump_gpio[16] = { ++ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_gpio), "GPIO", NULL}, ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.revision_id), "RevisionId", NULL}, ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.connection_type), ++ "ConnectionType", acpi_gbl_ct_decode}, ++ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(gpio.producer_consumer), ++ "ProducerConsumer", acpi_gbl_consume_decode}, ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(gpio.pin_config), "PinConfig", ++ acpi_gbl_ppc_decode}, ++ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.sharable), "Sharable", ++ acpi_gbl_shr_decode}, ++ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.io_restriction), ++ "IoRestriction", acpi_gbl_ior_decode}, ++ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(gpio.triggering), "Triggering", ++ acpi_gbl_he_decode}, ++ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(gpio.polarity), "Polarity", ++ acpi_gbl_ll_decode}, ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.drive_strength), "DriveStrength", ++ NULL}, ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.debounce_timeout), ++ "DebounceTimeout", NULL}, ++ {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET(gpio.resource_source), ++ "ResourceSource", NULL}, ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.pin_table_length), ++ "PinTableLength", NULL}, ++ {ACPI_RSD_WORDLIST, ACPI_RSD_OFFSET(gpio.pin_table), "PinTable", NULL}, ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(gpio.vendor_length), "VendorLength", ++ NULL}, ++ {ACPI_RSD_SHORTLISTX, ACPI_RSD_OFFSET(gpio.vendor_data), "VendorData", ++ NULL}, ++}; ++ ++struct acpi_rsdump_info acpi_rs_dump_fixed_dma[4] = { ++ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_fixed_dma), ++ "FixedDma", NULL}, ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_dma.request_lines), ++ "RequestLines", NULL}, ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(fixed_dma.channels), "Channels", ++ NULL}, ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(fixed_dma.width), "TransferWidth", ++ acpi_gbl_dts_decode}, ++}; ++ ++#define ACPI_RS_DUMP_COMMON_SERIAL_BUS \ ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (common_serial_bus.revision_id), "RevisionId", NULL}, \ ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (common_serial_bus.type), "Type", acpi_gbl_sbt_decode}, \ ++ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (common_serial_bus.producer_consumer), "ProducerConsumer", acpi_gbl_consume_decode}, \ ++ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET (common_serial_bus.slave_mode), "SlaveMode", acpi_gbl_sm_decode}, \ ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET (common_serial_bus.type_revision_id), "TypeRevisionId", NULL}, \ ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (common_serial_bus.type_data_length), "TypeDataLength", NULL}, \ ++ {ACPI_RSD_SOURCE, ACPI_RSD_OFFSET (common_serial_bus.resource_source), "ResourceSource", NULL}, \ ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET (common_serial_bus.vendor_length), "VendorLength", NULL}, \ ++ {ACPI_RSD_SHORTLISTX,ACPI_RSD_OFFSET (common_serial_bus.vendor_data), "VendorData", NULL}, ++ ++struct acpi_rsdump_info acpi_rs_dump_common_serial_bus[10] = { ++ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_common_serial_bus), ++ "Common Serial Bus", NULL}, ++ ACPI_RS_DUMP_COMMON_SERIAL_BUS ++}; ++ ++struct acpi_rsdump_info acpi_rs_dump_i2c_serial_bus[13] = { ++ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_i2c_serial_bus), ++ "I2C Serial Bus", NULL}, ++ ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_1BITFLAG, ++ ACPI_RSD_OFFSET(i2c_serial_bus. ++ access_mode), ++ "AccessMode", acpi_gbl_am_decode}, ++ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(i2c_serial_bus.connection_speed), ++ "ConnectionSpeed", NULL}, ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(i2c_serial_bus.slave_address), ++ "SlaveAddress", NULL}, ++}; ++ ++struct acpi_rsdump_info acpi_rs_dump_spi_serial_bus[17] = { ++ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_spi_serial_bus), ++ "Spi Serial Bus", NULL}, ++ ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_1BITFLAG, ++ ACPI_RSD_OFFSET(spi_serial_bus. ++ wire_mode), "WireMode", ++ acpi_gbl_wm_decode}, ++ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(spi_serial_bus.device_polarity), ++ "DevicePolarity", acpi_gbl_dp_decode}, ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.data_bit_length), ++ "DataBitLength", NULL}, ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.clock_phase), ++ "ClockPhase", acpi_gbl_cph_decode}, ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(spi_serial_bus.clock_polarity), ++ "ClockPolarity", acpi_gbl_cpo_decode}, ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(spi_serial_bus.device_selection), ++ "DeviceSelection", NULL}, ++ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(spi_serial_bus.connection_speed), ++ "ConnectionSpeed", NULL}, ++}; ++ ++struct acpi_rsdump_info acpi_rs_dump_uart_serial_bus[19] = { ++ {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_uart_serial_bus), ++ "Uart Serial Bus", NULL}, ++ ACPI_RS_DUMP_COMMON_SERIAL_BUS {ACPI_RSD_2BITFLAG, ++ ACPI_RSD_OFFSET(uart_serial_bus. ++ flow_control), ++ "FlowControl", acpi_gbl_fc_decode}, ++ {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.stop_bits), ++ "StopBits", acpi_gbl_sb_decode}, ++ {ACPI_RSD_3BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.data_bits), ++ "DataBits", acpi_gbl_bpb_decode}, ++ {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(uart_serial_bus.endian), "Endian", ++ acpi_gbl_ed_decode}, ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(uart_serial_bus.parity), "Parity", ++ acpi_gbl_pt_decode}, ++ {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(uart_serial_bus.lines_enabled), ++ "LinesEnabled", NULL}, ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(uart_serial_bus.rx_fifo_size), ++ "RxFifoSize", NULL}, ++ {ACPI_RSD_UINT16, ACPI_RSD_OFFSET(uart_serial_bus.tx_fifo_size), ++ "TxFifoSize", NULL}, ++ {ACPI_RSD_UINT32, ACPI_RSD_OFFSET(uart_serial_bus.default_baud_rate), ++ "ConnectionSpeed", NULL}, ++}; ++ + /* + * Tables used for common address descriptor flag fields + */ +@@ -413,7 +534,14 @@ + /* Data items, 8/16/32/64 bit */ + + case ACPI_RSD_UINT8: +- acpi_rs_out_integer8(name, ACPI_GET8(target)); ++ if (table->pointer) { ++ acpi_rs_out_string(name, ACPI_CAST_PTR(char, ++ table-> ++ pointer ++ [*target])); ++ } else { ++ acpi_rs_out_integer8(name, ACPI_GET8(target)); ++ } + break; + + case ACPI_RSD_UINT16: +@@ -444,6 +572,13 @@ + 0x03])); + break; + ++ case ACPI_RSD_3BITFLAG: ++ acpi_rs_out_string(name, ACPI_CAST_PTR(char, ++ table-> ++ pointer[*target & ++ 0x07])); ++ break; ++ + case ACPI_RSD_SHORTLIST: + /* + * Short byte list (single line output) for DMA and IRQ resources +@@ -456,6 +591,20 @@ + } + break; + ++ case ACPI_RSD_SHORTLISTX: ++ /* ++ * Short byte list (single line output) for GPIO vendor data ++ * Note: The list length is obtained from the previous table entry ++ */ ++ if (previous_target) { ++ acpi_rs_out_title(name); ++ acpi_rs_dump_short_byte_list(*previous_target, ++ * ++ (ACPI_CAST_INDIRECT_PTR ++ (u8, target))); ++ } ++ break; ++ + case ACPI_RSD_LONGLIST: + /* + * Long byte list for Vendor resource data +@@ -480,6 +629,18 @@ + } + break; + ++ case ACPI_RSD_WORDLIST: ++ /* ++ * Word list for GPIO Pin Table ++ * Note: The list length is obtained from the previous table entry ++ */ ++ if (previous_target) { ++ acpi_rs_dump_word_list(*previous_target, ++ *(ACPI_CAST_INDIRECT_PTR ++ (u16, target))); ++ } ++ break; ++ + case ACPI_RSD_ADDRESS: + /* + * Common flags for all Address resources +@@ -627,14 +788,20 @@ + + /* Dump the resource descriptor */ + +- acpi_rs_dump_descriptor(&resource_list->data, +- acpi_gbl_dump_resource_dispatch[type]); ++ if (type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { ++ acpi_rs_dump_descriptor(&resource_list->data, ++ acpi_gbl_dump_serial_bus_dispatch ++ [resource_list->data. ++ common_serial_bus.type]); ++ } else { ++ acpi_rs_dump_descriptor(&resource_list->data, ++ acpi_gbl_dump_resource_dispatch ++ [type]); ++ } + + /* Point to the next resource structure */ + +- resource_list = +- ACPI_ADD_PTR(struct acpi_resource, resource_list, +- resource_list->length); ++ resource_list = ACPI_NEXT_RESOURCE(resource_list); + + /* Exit when END_TAG descriptor is reached */ + +@@ -768,4 +935,13 @@ + } + } + ++static void acpi_rs_dump_word_list(u16 length, u16 *data) ++{ ++ u16 i; ++ ++ for (i = 0; i < length; i++) { ++ acpi_os_printf("%25s%2.2X : %4.4X\n", "Word", i, data[i]); ++ } ++} ++ + #endif +diff -Naur linux-3.2.16/drivers/acpi/acpica/rsinfo.c linux-3.2.16.patch/drivers/acpi/acpica/rsinfo.c +--- linux-3.2.16/drivers/acpi/acpica/rsinfo.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/rsinfo.c 2012-04-23 06:05:41.426124820 +0200 +@@ -76,7 +76,10 @@ + acpi_rs_convert_address64, /* 0x0D, ACPI_RESOURCE_TYPE_ADDRESS64 */ + acpi_rs_convert_ext_address64, /* 0x0E, ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ + acpi_rs_convert_ext_irq, /* 0x0F, ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ +- acpi_rs_convert_generic_reg /* 0x10, ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ ++ acpi_rs_convert_generic_reg, /* 0x10, ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ ++ acpi_rs_convert_gpio, /* 0x11, ACPI_RESOURCE_TYPE_GPIO */ ++ acpi_rs_convert_fixed_dma, /* 0x12, ACPI_RESOURCE_TYPE_FIXED_DMA */ ++ NULL, /* 0x13, ACPI_RESOURCE_TYPE_SERIAL_BUS - Use subtype table below */ + }; + + /* Dispatch tables for AML-to-resource (Get Resource) conversion functions */ +@@ -94,7 +97,7 @@ + acpi_rs_convert_end_dpf, /* 0x07, ACPI_RESOURCE_NAME_END_DEPENDENT */ + acpi_rs_convert_io, /* 0x08, ACPI_RESOURCE_NAME_IO */ + acpi_rs_convert_fixed_io, /* 0x09, ACPI_RESOURCE_NAME_FIXED_IO */ +- NULL, /* 0x0A, Reserved */ ++ acpi_rs_convert_fixed_dma, /* 0x0A, ACPI_RESOURCE_NAME_FIXED_DMA */ + NULL, /* 0x0B, Reserved */ + NULL, /* 0x0C, Reserved */ + NULL, /* 0x0D, Reserved */ +@@ -114,7 +117,19 @@ + acpi_rs_convert_address16, /* 0x08, ACPI_RESOURCE_NAME_ADDRESS16 */ + acpi_rs_convert_ext_irq, /* 0x09, ACPI_RESOURCE_NAME_EXTENDED_IRQ */ + acpi_rs_convert_address64, /* 0x0A, ACPI_RESOURCE_NAME_ADDRESS64 */ +- acpi_rs_convert_ext_address64 /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 */ ++ acpi_rs_convert_ext_address64, /* 0x0B, ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64 */ ++ acpi_rs_convert_gpio, /* 0x0C, ACPI_RESOURCE_NAME_GPIO */ ++ NULL, /* 0x0D, Reserved */ ++ NULL, /* 0x0E, ACPI_RESOURCE_NAME_SERIAL_BUS - Use subtype table below */ ++}; ++ ++/* Subtype table for serial_bus -- I2C, SPI, and UART */ ++ ++struct acpi_rsconvert_info *acpi_gbl_convert_resource_serial_bus_dispatch[] = { ++ NULL, ++ acpi_rs_convert_i2c_serial_bus, ++ acpi_rs_convert_spi_serial_bus, ++ acpi_rs_convert_uart_serial_bus, + }; + + #ifdef ACPI_FUTURE_USAGE +@@ -140,6 +155,16 @@ + acpi_rs_dump_ext_address64, /* ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ + acpi_rs_dump_ext_irq, /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ + acpi_rs_dump_generic_reg, /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ ++ acpi_rs_dump_gpio, /* ACPI_RESOURCE_TYPE_GPIO */ ++ acpi_rs_dump_fixed_dma, /* ACPI_RESOURCE_TYPE_FIXED_DMA */ ++ NULL, /* ACPI_RESOURCE_TYPE_SERIAL_BUS */ ++}; ++ ++struct acpi_rsdump_info *acpi_gbl_dump_serial_bus_dispatch[] = { ++ NULL, ++ acpi_rs_dump_i2c_serial_bus, /* AML_RESOURCE_I2C_BUS_TYPE */ ++ acpi_rs_dump_spi_serial_bus, /* AML_RESOURCE_SPI_BUS_TYPE */ ++ acpi_rs_dump_uart_serial_bus, /* AML_RESOURCE_UART_BUS_TYPE */ + }; + #endif + +@@ -166,7 +191,10 @@ + sizeof(struct aml_resource_address64), /* ACPI_RESOURCE_TYPE_ADDRESS64 */ + sizeof(struct aml_resource_extended_address64), /*ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 */ + sizeof(struct aml_resource_extended_irq), /* ACPI_RESOURCE_TYPE_EXTENDED_IRQ */ +- sizeof(struct aml_resource_generic_register) /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ ++ sizeof(struct aml_resource_generic_register), /* ACPI_RESOURCE_TYPE_GENERIC_REGISTER */ ++ sizeof(struct aml_resource_gpio), /* ACPI_RESOURCE_TYPE_GPIO */ ++ sizeof(struct aml_resource_fixed_dma), /* ACPI_RESOURCE_TYPE_FIXED_DMA */ ++ sizeof(struct aml_resource_common_serialbus), /* ACPI_RESOURCE_TYPE_SERIAL_BUS */ + }; + + const u8 acpi_gbl_resource_struct_sizes[] = { +@@ -182,7 +210,7 @@ + ACPI_RS_SIZE_MIN, + ACPI_RS_SIZE(struct acpi_resource_io), + ACPI_RS_SIZE(struct acpi_resource_fixed_io), +- 0, ++ ACPI_RS_SIZE(struct acpi_resource_fixed_dma), + 0, + 0, + 0, +@@ -202,5 +230,21 @@ + ACPI_RS_SIZE(struct acpi_resource_address16), + ACPI_RS_SIZE(struct acpi_resource_extended_irq), + ACPI_RS_SIZE(struct acpi_resource_address64), +- ACPI_RS_SIZE(struct acpi_resource_extended_address64) ++ ACPI_RS_SIZE(struct acpi_resource_extended_address64), ++ ACPI_RS_SIZE(struct acpi_resource_gpio), ++ ACPI_RS_SIZE(struct acpi_resource_common_serialbus) ++}; ++ ++const u8 acpi_gbl_aml_resource_serial_bus_sizes[] = { ++ 0, ++ sizeof(struct aml_resource_i2c_serialbus), ++ sizeof(struct aml_resource_spi_serialbus), ++ sizeof(struct aml_resource_uart_serialbus), ++}; ++ ++const u8 acpi_gbl_resource_struct_serial_bus_sizes[] = { ++ 0, ++ ACPI_RS_SIZE(struct acpi_resource_i2c_serialbus), ++ ACPI_RS_SIZE(struct acpi_resource_spi_serialbus), ++ ACPI_RS_SIZE(struct acpi_resource_uart_serialbus), + }; +diff -Naur linux-3.2.16/drivers/acpi/acpica/rsirq.c linux-3.2.16.patch/drivers/acpi/acpica/rsirq.c +--- linux-3.2.16/drivers/acpi/acpica/rsirq.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/rsirq.c 2012-04-23 06:05:41.427124840 +0200 +@@ -264,3 +264,34 @@ + AML_OFFSET(dma.dma_channel_mask), + ACPI_RS_OFFSET(data.dma.channel_count)} + }; ++ ++/******************************************************************************* ++ * ++ * acpi_rs_convert_fixed_dma ++ * ++ ******************************************************************************/ ++ ++struct acpi_rsconvert_info acpi_rs_convert_fixed_dma[4] = { ++ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_FIXED_DMA, ++ ACPI_RS_SIZE(struct acpi_resource_fixed_dma), ++ ACPI_RSC_TABLE_SIZE(acpi_rs_convert_fixed_dma)}, ++ ++ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_FIXED_DMA, ++ sizeof(struct aml_resource_fixed_dma), ++ 0}, ++ ++ /* ++ * These fields are contiguous in both the source and destination: ++ * request_lines ++ * Channels ++ */ ++ ++ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.fixed_dma.request_lines), ++ AML_OFFSET(fixed_dma.request_lines), ++ 2}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.fixed_dma.width), ++ AML_OFFSET(fixed_dma.width), ++ 1}, ++ ++}; +diff -Naur linux-3.2.16/drivers/acpi/acpica/rslist.c linux-3.2.16.patch/drivers/acpi/acpica/rslist.c +--- linux-3.2.16/drivers/acpi/acpica/rslist.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/rslist.c 2012-04-23 06:05:41.427124840 +0200 +@@ -70,6 +70,8 @@ + struct acpi_resource **resource_ptr = + ACPI_CAST_INDIRECT_PTR(struct acpi_resource, context); + struct acpi_resource *resource; ++ union aml_resource *aml_resource; ++ struct acpi_rsconvert_info *conversion_table; + acpi_status status; + + ACPI_FUNCTION_TRACE(rs_convert_aml_to_resources); +@@ -84,14 +86,37 @@ + "Misaligned resource pointer %p", resource)); + } + ++ /* Get the appropriate conversion info table */ ++ ++ aml_resource = ACPI_CAST_PTR(union aml_resource, aml); ++ if (acpi_ut_get_resource_type(aml) == ACPI_RESOURCE_NAME_SERIAL_BUS) { ++ if (aml_resource->common_serial_bus.type > ++ AML_RESOURCE_MAX_SERIALBUSTYPE) { ++ conversion_table = NULL; ++ } else { ++ /* This is an I2C, SPI, or UART serial_bus descriptor */ ++ ++ conversion_table = ++ acpi_gbl_convert_resource_serial_bus_dispatch ++ [aml_resource->common_serial_bus.type]; ++ } ++ } else { ++ conversion_table = ++ acpi_gbl_get_resource_dispatch[resource_index]; ++ } ++ ++ if (!conversion_table) { ++ ACPI_ERROR((AE_INFO, ++ "Invalid/unsupported resource descriptor: Type 0x%2.2X", ++ resource_index)); ++ return (AE_AML_INVALID_RESOURCE_TYPE); ++ } ++ + /* Convert the AML byte stream resource to a local resource struct */ + + status = +- acpi_rs_convert_aml_to_resource(resource, +- ACPI_CAST_PTR(union aml_resource, +- aml), +- acpi_gbl_get_resource_dispatch +- [resource_index]); ++ acpi_rs_convert_aml_to_resource(resource, aml_resource, ++ conversion_table); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not convert AML resource (Type 0x%X)", +@@ -106,7 +131,7 @@ + + /* Point to the next structure in the output buffer */ + +- *resource_ptr = ACPI_ADD_PTR(void, resource, resource->length); ++ *resource_ptr = ACPI_NEXT_RESOURCE(resource); + return_ACPI_STATUS(AE_OK); + } + +@@ -135,6 +160,7 @@ + { + u8 *aml = output_buffer; + u8 *end_aml = output_buffer + aml_size_needed; ++ struct acpi_rsconvert_info *conversion_table; + acpi_status status; + + ACPI_FUNCTION_TRACE(rs_convert_resources_to_aml); +@@ -154,11 +180,34 @@ + + /* Perform the conversion */ + +- status = acpi_rs_convert_resource_to_aml(resource, ACPI_CAST_PTR(union +- aml_resource, +- aml), +- acpi_gbl_set_resource_dispatch +- [resource->type]); ++ if (resource->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { ++ if (resource->data.common_serial_bus.type > ++ AML_RESOURCE_MAX_SERIALBUSTYPE) { ++ conversion_table = NULL; ++ } else { ++ /* This is an I2C, SPI, or UART serial_bus descriptor */ ++ ++ conversion_table = ++ acpi_gbl_convert_resource_serial_bus_dispatch ++ [resource->data.common_serial_bus.type]; ++ } ++ } else { ++ conversion_table = ++ acpi_gbl_set_resource_dispatch[resource->type]; ++ } ++ ++ if (!conversion_table) { ++ ACPI_ERROR((AE_INFO, ++ "Invalid/unsupported resource descriptor: Type 0x%2.2X", ++ resource->type)); ++ return (AE_AML_INVALID_RESOURCE_TYPE); ++ } ++ ++ status = acpi_rs_convert_resource_to_aml(resource, ++ ACPI_CAST_PTR(union ++ aml_resource, ++ aml), ++ conversion_table); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not convert resource (type 0x%X) to AML", +@@ -192,9 +241,7 @@ + + /* Point to the next input resource descriptor */ + +- resource = +- ACPI_ADD_PTR(struct acpi_resource, resource, +- resource->length); ++ resource = ACPI_NEXT_RESOURCE(resource); + } + + /* Completed buffer, but did not find an end_tag resource descriptor */ +diff -Naur linux-3.2.16/drivers/acpi/acpica/rsmisc.c linux-3.2.16.patch/drivers/acpi/acpica/rsmisc.c +--- linux-3.2.16/drivers/acpi/acpica/rsmisc.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/rsmisc.c 2012-04-23 06:05:41.428124860 +0200 +@@ -83,6 +83,10 @@ + + ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource); + ++ if (!info) { ++ return_ACPI_STATUS(AE_BAD_PARAMETER); ++ } ++ + if (((acpi_size) resource) & 0x3) { + + /* Each internal resource struct is expected to be 32-bit aligned */ +@@ -101,7 +105,6 @@ + * table length (# of table entries) + */ + count = INIT_TABLE_LENGTH(info); +- + while (count) { + /* + * Source is the external AML byte stream buffer, +@@ -145,6 +148,14 @@ + ((ACPI_GET8(source) >> info->value) & 0x03); + break; + ++ case ACPI_RSC_3BITFLAG: ++ /* ++ * Mask and shift the flag bits ++ */ ++ ACPI_SET8(destination) = (u8) ++ ((ACPI_GET8(source) >> info->value) & 0x07); ++ break; ++ + case ACPI_RSC_COUNT: + + item_count = ACPI_GET8(source); +@@ -163,6 +174,69 @@ + (info->value * (item_count - 1)); + break; + ++ case ACPI_RSC_COUNT_GPIO_PIN: ++ ++ target = ACPI_ADD_PTR(void, aml, info->value); ++ item_count = ACPI_GET16(target) - ACPI_GET16(source); ++ ++ resource->length = resource->length + item_count; ++ item_count = item_count / 2; ++ ACPI_SET16(destination) = item_count; ++ break; ++ ++ case ACPI_RSC_COUNT_GPIO_VEN: ++ ++ item_count = ACPI_GET8(source); ++ ACPI_SET8(destination) = (u8)item_count; ++ ++ resource->length = resource->length + ++ (info->value * item_count); ++ break; ++ ++ case ACPI_RSC_COUNT_GPIO_RES: ++ ++ /* ++ * Vendor data is optional (length/offset may both be zero) ++ * Examine vendor data length field first ++ */ ++ target = ACPI_ADD_PTR(void, aml, (info->value + 2)); ++ if (ACPI_GET16(target)) { ++ ++ /* Use vendor offset to get resource source length */ ++ ++ target = ACPI_ADD_PTR(void, aml, info->value); ++ item_count = ++ ACPI_GET16(target) - ACPI_GET16(source); ++ } else { ++ /* No vendor data to worry about */ ++ ++ item_count = aml->large_header.resource_length + ++ sizeof(struct aml_resource_large_header) - ++ ACPI_GET16(source); ++ } ++ ++ resource->length = resource->length + item_count; ++ ACPI_SET16(destination) = item_count; ++ break; ++ ++ case ACPI_RSC_COUNT_SERIAL_VEN: ++ ++ item_count = ACPI_GET16(source) - info->value; ++ ++ resource->length = resource->length + item_count; ++ ACPI_SET16(destination) = item_count; ++ break; ++ ++ case ACPI_RSC_COUNT_SERIAL_RES: ++ ++ item_count = (aml_resource_length + ++ sizeof(struct aml_resource_large_header)) ++ - ACPI_GET16(source) - info->value; ++ ++ resource->length = resource->length + item_count; ++ ACPI_SET16(destination) = item_count; ++ break; ++ + case ACPI_RSC_LENGTH: + + resource->length = resource->length + info->value; +@@ -183,6 +257,72 @@ + info->opcode); + break; + ++ case ACPI_RSC_MOVE_GPIO_PIN: ++ ++ /* Generate and set the PIN data pointer */ ++ ++ target = (char *)ACPI_ADD_PTR(void, resource, ++ (resource->length - ++ item_count * 2)); ++ *(u16 **)destination = ACPI_CAST_PTR(u16, target); ++ ++ /* Copy the PIN data */ ++ ++ source = ACPI_ADD_PTR(void, aml, ACPI_GET16(source)); ++ acpi_rs_move_data(target, source, item_count, ++ info->opcode); ++ break; ++ ++ case ACPI_RSC_MOVE_GPIO_RES: ++ ++ /* Generate and set the resource_source string pointer */ ++ ++ target = (char *)ACPI_ADD_PTR(void, resource, ++ (resource->length - ++ item_count)); ++ *(u8 **)destination = ACPI_CAST_PTR(u8, target); ++ ++ /* Copy the resource_source string */ ++ ++ source = ACPI_ADD_PTR(void, aml, ACPI_GET16(source)); ++ acpi_rs_move_data(target, source, item_count, ++ info->opcode); ++ break; ++ ++ case ACPI_RSC_MOVE_SERIAL_VEN: ++ ++ /* Generate and set the Vendor Data pointer */ ++ ++ target = (char *)ACPI_ADD_PTR(void, resource, ++ (resource->length - ++ item_count)); ++ *(u8 **)destination = ACPI_CAST_PTR(u8, target); ++ ++ /* Copy the Vendor Data */ ++ ++ source = ACPI_ADD_PTR(void, aml, info->value); ++ acpi_rs_move_data(target, source, item_count, ++ info->opcode); ++ break; ++ ++ case ACPI_RSC_MOVE_SERIAL_RES: ++ ++ /* Generate and set the resource_source string pointer */ ++ ++ target = (char *)ACPI_ADD_PTR(void, resource, ++ (resource->length - ++ item_count)); ++ *(u8 **)destination = ACPI_CAST_PTR(u8, target); ++ ++ /* Copy the resource_source string */ ++ ++ source = ++ ACPI_ADD_PTR(void, aml, ++ (ACPI_GET16(source) + info->value)); ++ acpi_rs_move_data(target, source, item_count, ++ info->opcode); ++ break; ++ + case ACPI_RSC_SET8: + + ACPI_MEMSET(destination, info->aml_offset, info->value); +@@ -219,13 +359,18 @@ + * Optional resource_source (Index and String). This is the more + * complicated case used by the Interrupt() macro + */ +- target = +- ACPI_ADD_PTR(char, resource, +- info->aml_offset + (item_count * 4)); ++ target = ACPI_ADD_PTR(char, resource, ++ info->aml_offset + ++ (item_count * 4)); + + resource->length += + acpi_rs_get_resource_source(aml_resource_length, +- (acpi_rs_length) (((item_count - 1) * sizeof(u32)) + info->value), destination, aml, target); ++ (acpi_rs_length) ++ (((item_count - ++ 1) * sizeof(u32)) + ++ info->value), ++ destination, aml, ++ target); + break; + + case ACPI_RSC_BITMASK: +@@ -327,6 +472,7 @@ + { + void *source = NULL; + void *destination; ++ char *target; + acpi_rsdesc_size aml_length = 0; + u8 count; + u16 temp16 = 0; +@@ -334,6 +480,10 @@ + + ACPI_FUNCTION_TRACE(rs_convert_resource_to_aml); + ++ if (!info) { ++ return_ACPI_STATUS(AE_BAD_PARAMETER); ++ } ++ + /* + * First table entry must be ACPI_RSC_INITxxx and must contain the + * table length (# of table entries) +@@ -383,6 +533,14 @@ + ((ACPI_GET8(source) & 0x03) << info->value); + break; + ++ case ACPI_RSC_3BITFLAG: ++ /* ++ * Mask and shift the flag bits ++ */ ++ ACPI_SET8(destination) |= (u8) ++ ((ACPI_GET8(source) & 0x07) << info->value); ++ break; ++ + case ACPI_RSC_COUNT: + + item_count = ACPI_GET8(source); +@@ -400,6 +558,63 @@ + acpi_rs_set_resource_length(aml_length, aml); + break; + ++ case ACPI_RSC_COUNT_GPIO_PIN: ++ ++ item_count = ACPI_GET16(source); ++ ACPI_SET16(destination) = (u16)aml_length; ++ ++ aml_length = (u16)(aml_length + item_count * 2); ++ target = ACPI_ADD_PTR(void, aml, info->value); ++ ACPI_SET16(target) = (u16)aml_length; ++ acpi_rs_set_resource_length(aml_length, aml); ++ break; ++ ++ case ACPI_RSC_COUNT_GPIO_VEN: ++ ++ item_count = ACPI_GET16(source); ++ ACPI_SET16(destination) = (u16)item_count; ++ ++ aml_length = ++ (u16)(aml_length + (info->value * item_count)); ++ acpi_rs_set_resource_length(aml_length, aml); ++ break; ++ ++ case ACPI_RSC_COUNT_GPIO_RES: ++ ++ /* Set resource source string length */ ++ ++ item_count = ACPI_GET16(source); ++ ACPI_SET16(destination) = (u16)aml_length; ++ ++ /* Compute offset for the Vendor Data */ ++ ++ aml_length = (u16)(aml_length + item_count); ++ target = ACPI_ADD_PTR(void, aml, info->value); ++ ++ /* Set vendor offset only if there is vendor data */ ++ ++ if (resource->data.gpio.vendor_length) { ++ ACPI_SET16(target) = (u16)aml_length; ++ } ++ ++ acpi_rs_set_resource_length(aml_length, aml); ++ break; ++ ++ case ACPI_RSC_COUNT_SERIAL_VEN: ++ ++ item_count = ACPI_GET16(source); ++ ACPI_SET16(destination) = item_count + info->value; ++ aml_length = (u16)(aml_length + item_count); ++ acpi_rs_set_resource_length(aml_length, aml); ++ break; ++ ++ case ACPI_RSC_COUNT_SERIAL_RES: ++ ++ item_count = ACPI_GET16(source); ++ aml_length = (u16)(aml_length + item_count); ++ acpi_rs_set_resource_length(aml_length, aml); ++ break; ++ + case ACPI_RSC_LENGTH: + + acpi_rs_set_resource_length(info->value, aml); +@@ -416,6 +631,48 @@ + acpi_rs_move_data(destination, source, item_count, + info->opcode); + break; ++ ++ case ACPI_RSC_MOVE_GPIO_PIN: ++ ++ destination = (char *)ACPI_ADD_PTR(void, aml, ++ ACPI_GET16 ++ (destination)); ++ source = *(u16 **)source; ++ acpi_rs_move_data(destination, source, item_count, ++ info->opcode); ++ break; ++ ++ case ACPI_RSC_MOVE_GPIO_RES: ++ ++ /* Used for both resource_source string and vendor_data */ ++ ++ destination = (char *)ACPI_ADD_PTR(void, aml, ++ ACPI_GET16 ++ (destination)); ++ source = *(u8 **)source; ++ acpi_rs_move_data(destination, source, item_count, ++ info->opcode); ++ break; ++ ++ case ACPI_RSC_MOVE_SERIAL_VEN: ++ ++ destination = (char *)ACPI_ADD_PTR(void, aml, ++ (aml_length - ++ item_count)); ++ source = *(u8 **)source; ++ acpi_rs_move_data(destination, source, item_count, ++ info->opcode); ++ break; ++ ++ case ACPI_RSC_MOVE_SERIAL_RES: ++ ++ destination = (char *)ACPI_ADD_PTR(void, aml, ++ (aml_length - ++ item_count)); ++ source = *(u8 **)source; ++ acpi_rs_move_data(destination, source, item_count, ++ info->opcode); ++ break; + + case ACPI_RSC_ADDRESS: + +diff -Naur linux-3.2.16/drivers/acpi/acpica/rsserial.c linux-3.2.16.patch/drivers/acpi/acpica/rsserial.c +--- linux-3.2.16/drivers/acpi/acpica/rsserial.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.2.16.patch/drivers/acpi/acpica/rsserial.c 2012-04-23 06:05:41.429124880 +0200 +@@ -0,0 +1,441 @@ ++/******************************************************************************* ++ * ++ * Module Name: rsserial - GPIO/serial_bus resource descriptors ++ * ++ ******************************************************************************/ ++ ++/* ++ * Copyright (C) 2000 - 2011, Intel Corp. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce at minimum a disclaimer ++ * substantially similar to the "NO WARRANTY" disclaimer below ++ * ("Disclaimer") and any redistribution must be conditioned upon ++ * including a substantially similar Disclaimer requirement for further ++ * binary redistribution. ++ * 3. Neither the names of the above-listed copyright holders nor the names ++ * of any contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * Alternatively, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2 as published by the Free ++ * Software Foundation. ++ * ++ * NO WARRANTY ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGES. ++ */ ++ ++#include ++#include "accommon.h" ++#include "acresrc.h" ++ ++#define _COMPONENT ACPI_RESOURCES ++ACPI_MODULE_NAME("rsserial") ++ ++/******************************************************************************* ++ * ++ * acpi_rs_convert_gpio ++ * ++ ******************************************************************************/ ++struct acpi_rsconvert_info acpi_rs_convert_gpio[17] = { ++ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_GPIO, ++ ACPI_RS_SIZE(struct acpi_resource_gpio), ++ ACPI_RSC_TABLE_SIZE(acpi_rs_convert_gpio)}, ++ ++ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_GPIO, ++ sizeof(struct aml_resource_gpio), ++ 0}, ++ ++ /* ++ * These fields are contiguous in both the source and destination: ++ * revision_id ++ * connection_type ++ */ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.gpio.revision_id), ++ AML_OFFSET(gpio.revision_id), ++ 2}, ++ ++ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.gpio.producer_consumer), ++ AML_OFFSET(gpio.flags), ++ 0}, ++ ++ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.gpio.sharable), ++ AML_OFFSET(gpio.int_flags), ++ 3}, ++ ++ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.gpio.io_restriction), ++ AML_OFFSET(gpio.int_flags), ++ 0}, ++ ++ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.gpio.triggering), ++ AML_OFFSET(gpio.int_flags), ++ 0}, ++ ++ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.gpio.polarity), ++ AML_OFFSET(gpio.int_flags), ++ 1}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.gpio.pin_config), ++ AML_OFFSET(gpio.pin_config), ++ 1}, ++ ++ /* ++ * These fields are contiguous in both the source and destination: ++ * drive_strength ++ * debounce_timeout ++ */ ++ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.gpio.drive_strength), ++ AML_OFFSET(gpio.drive_strength), ++ 2}, ++ ++ /* Pin Table */ ++ ++ {ACPI_RSC_COUNT_GPIO_PIN, ACPI_RS_OFFSET(data.gpio.pin_table_length), ++ AML_OFFSET(gpio.pin_table_offset), ++ AML_OFFSET(gpio.res_source_offset)}, ++ ++ {ACPI_RSC_MOVE_GPIO_PIN, ACPI_RS_OFFSET(data.gpio.pin_table), ++ AML_OFFSET(gpio.pin_table_offset), ++ 0}, ++ ++ /* Resource Source */ ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.gpio.resource_source.index), ++ AML_OFFSET(gpio.res_source_index), ++ 1}, ++ ++ {ACPI_RSC_COUNT_GPIO_RES, ++ ACPI_RS_OFFSET(data.gpio.resource_source.string_length), ++ AML_OFFSET(gpio.res_source_offset), ++ AML_OFFSET(gpio.vendor_offset)}, ++ ++ {ACPI_RSC_MOVE_GPIO_RES, ++ ACPI_RS_OFFSET(data.gpio.resource_source.string_ptr), ++ AML_OFFSET(gpio.res_source_offset), ++ 0}, ++ ++ /* Vendor Data */ ++ ++ {ACPI_RSC_COUNT_GPIO_VEN, ACPI_RS_OFFSET(data.gpio.vendor_length), ++ AML_OFFSET(gpio.vendor_length), ++ 1}, ++ ++ {ACPI_RSC_MOVE_GPIO_RES, ACPI_RS_OFFSET(data.gpio.vendor_data), ++ AML_OFFSET(gpio.vendor_offset), ++ 0}, ++}; ++ ++/******************************************************************************* ++ * ++ * acpi_rs_convert_i2c_serial_bus ++ * ++ ******************************************************************************/ ++ ++struct acpi_rsconvert_info acpi_rs_convert_i2c_serial_bus[16] = { ++ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_SERIAL_BUS, ++ ACPI_RS_SIZE(struct acpi_resource_i2c_serialbus), ++ ACPI_RSC_TABLE_SIZE(acpi_rs_convert_i2c_serial_bus)}, ++ ++ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_SERIAL_BUS, ++ sizeof(struct aml_resource_i2c_serialbus), ++ 0}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.common_serial_bus.revision_id), ++ AML_OFFSET(common_serial_bus.revision_id), ++ 1}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.common_serial_bus.type), ++ AML_OFFSET(common_serial_bus.type), ++ 1}, ++ ++ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.common_serial_bus.slave_mode), ++ AML_OFFSET(common_serial_bus.flags), ++ 0}, ++ ++ {ACPI_RSC_1BITFLAG, ++ ACPI_RS_OFFSET(data.common_serial_bus.producer_consumer), ++ AML_OFFSET(common_serial_bus.flags), ++ 1}, ++ ++ {ACPI_RSC_MOVE8, ++ ACPI_RS_OFFSET(data.common_serial_bus.type_revision_id), ++ AML_OFFSET(common_serial_bus.type_revision_id), ++ 1}, ++ ++ {ACPI_RSC_MOVE16, ++ ACPI_RS_OFFSET(data.common_serial_bus.type_data_length), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ 1}, ++ ++ /* Vendor data */ ++ ++ {ACPI_RSC_COUNT_SERIAL_VEN, ++ ACPI_RS_OFFSET(data.common_serial_bus.vendor_length), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ AML_RESOURCE_I2C_MIN_DATA_LEN}, ++ ++ {ACPI_RSC_MOVE_SERIAL_VEN, ++ ACPI_RS_OFFSET(data.common_serial_bus.vendor_data), ++ 0, ++ sizeof(struct aml_resource_i2c_serialbus)}, ++ ++ /* Resource Source */ ++ ++ {ACPI_RSC_MOVE8, ++ ACPI_RS_OFFSET(data.common_serial_bus.resource_source.index), ++ AML_OFFSET(common_serial_bus.res_source_index), ++ 1}, ++ ++ {ACPI_RSC_COUNT_SERIAL_RES, ++ ACPI_RS_OFFSET(data.common_serial_bus.resource_source.string_length), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ sizeof(struct aml_resource_common_serialbus)}, ++ ++ {ACPI_RSC_MOVE_SERIAL_RES, ++ ACPI_RS_OFFSET(data.common_serial_bus.resource_source.string_ptr), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ sizeof(struct aml_resource_common_serialbus)}, ++ ++ /* I2C bus type specific */ ++ ++ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.i2c_serial_bus.access_mode), ++ AML_OFFSET(i2c_serial_bus.type_specific_flags), ++ 0}, ++ ++ {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.i2c_serial_bus.connection_speed), ++ AML_OFFSET(i2c_serial_bus.connection_speed), ++ 1}, ++ ++ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.i2c_serial_bus.slave_address), ++ AML_OFFSET(i2c_serial_bus.slave_address), ++ 1}, ++}; ++ ++/******************************************************************************* ++ * ++ * acpi_rs_convert_spi_serial_bus ++ * ++ ******************************************************************************/ ++ ++struct acpi_rsconvert_info acpi_rs_convert_spi_serial_bus[20] = { ++ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_SERIAL_BUS, ++ ACPI_RS_SIZE(struct acpi_resource_spi_serialbus), ++ ACPI_RSC_TABLE_SIZE(acpi_rs_convert_spi_serial_bus)}, ++ ++ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_SERIAL_BUS, ++ sizeof(struct aml_resource_spi_serialbus), ++ 0}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.common_serial_bus.revision_id), ++ AML_OFFSET(common_serial_bus.revision_id), ++ 1}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.common_serial_bus.type), ++ AML_OFFSET(common_serial_bus.type), ++ 1}, ++ ++ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.common_serial_bus.slave_mode), ++ AML_OFFSET(common_serial_bus.flags), ++ 0}, ++ ++ {ACPI_RSC_1BITFLAG, ++ ACPI_RS_OFFSET(data.common_serial_bus.producer_consumer), ++ AML_OFFSET(common_serial_bus.flags), ++ 1}, ++ ++ {ACPI_RSC_MOVE8, ++ ACPI_RS_OFFSET(data.common_serial_bus.type_revision_id), ++ AML_OFFSET(common_serial_bus.type_revision_id), ++ 1}, ++ ++ {ACPI_RSC_MOVE16, ++ ACPI_RS_OFFSET(data.common_serial_bus.type_data_length), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ 1}, ++ ++ /* Vendor data */ ++ ++ {ACPI_RSC_COUNT_SERIAL_VEN, ++ ACPI_RS_OFFSET(data.common_serial_bus.vendor_length), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ AML_RESOURCE_SPI_MIN_DATA_LEN}, ++ ++ {ACPI_RSC_MOVE_SERIAL_VEN, ++ ACPI_RS_OFFSET(data.common_serial_bus.vendor_data), ++ 0, ++ sizeof(struct aml_resource_spi_serialbus)}, ++ ++ /* Resource Source */ ++ ++ {ACPI_RSC_MOVE8, ++ ACPI_RS_OFFSET(data.common_serial_bus.resource_source.index), ++ AML_OFFSET(common_serial_bus.res_source_index), ++ 1}, ++ ++ {ACPI_RSC_COUNT_SERIAL_RES, ++ ACPI_RS_OFFSET(data.common_serial_bus.resource_source.string_length), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ sizeof(struct aml_resource_common_serialbus)}, ++ ++ {ACPI_RSC_MOVE_SERIAL_RES, ++ ACPI_RS_OFFSET(data.common_serial_bus.resource_source.string_ptr), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ sizeof(struct aml_resource_common_serialbus)}, ++ ++ /* Spi bus type specific */ ++ ++ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.spi_serial_bus.wire_mode), ++ AML_OFFSET(spi_serial_bus.type_specific_flags), ++ 0}, ++ ++ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.spi_serial_bus.device_polarity), ++ AML_OFFSET(spi_serial_bus.type_specific_flags), ++ 1}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.spi_serial_bus.data_bit_length), ++ AML_OFFSET(spi_serial_bus.data_bit_length), ++ 1}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.spi_serial_bus.clock_phase), ++ AML_OFFSET(spi_serial_bus.clock_phase), ++ 1}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.spi_serial_bus.clock_polarity), ++ AML_OFFSET(spi_serial_bus.clock_polarity), ++ 1}, ++ ++ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.spi_serial_bus.device_selection), ++ AML_OFFSET(spi_serial_bus.device_selection), ++ 1}, ++ ++ {ACPI_RSC_MOVE32, ACPI_RS_OFFSET(data.spi_serial_bus.connection_speed), ++ AML_OFFSET(spi_serial_bus.connection_speed), ++ 1}, ++}; ++ ++/******************************************************************************* ++ * ++ * acpi_rs_convert_uart_serial_bus ++ * ++ ******************************************************************************/ ++ ++struct acpi_rsconvert_info acpi_rs_convert_uart_serial_bus[22] = { ++ {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_SERIAL_BUS, ++ ACPI_RS_SIZE(struct acpi_resource_uart_serialbus), ++ ACPI_RSC_TABLE_SIZE(acpi_rs_convert_uart_serial_bus)}, ++ ++ {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_SERIAL_BUS, ++ sizeof(struct aml_resource_uart_serialbus), ++ 0}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.common_serial_bus.revision_id), ++ AML_OFFSET(common_serial_bus.revision_id), ++ 1}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.common_serial_bus.type), ++ AML_OFFSET(common_serial_bus.type), ++ 1}, ++ ++ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.common_serial_bus.slave_mode), ++ AML_OFFSET(common_serial_bus.flags), ++ 0}, ++ ++ {ACPI_RSC_1BITFLAG, ++ ACPI_RS_OFFSET(data.common_serial_bus.producer_consumer), ++ AML_OFFSET(common_serial_bus.flags), ++ 1}, ++ ++ {ACPI_RSC_MOVE8, ++ ACPI_RS_OFFSET(data.common_serial_bus.type_revision_id), ++ AML_OFFSET(common_serial_bus.type_revision_id), ++ 1}, ++ ++ {ACPI_RSC_MOVE16, ++ ACPI_RS_OFFSET(data.common_serial_bus.type_data_length), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ 1}, ++ ++ /* Vendor data */ ++ ++ {ACPI_RSC_COUNT_SERIAL_VEN, ++ ACPI_RS_OFFSET(data.common_serial_bus.vendor_length), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ AML_RESOURCE_UART_MIN_DATA_LEN}, ++ ++ {ACPI_RSC_MOVE_SERIAL_VEN, ++ ACPI_RS_OFFSET(data.common_serial_bus.vendor_data), ++ 0, ++ sizeof(struct aml_resource_uart_serialbus)}, ++ ++ /* Resource Source */ ++ ++ {ACPI_RSC_MOVE8, ++ ACPI_RS_OFFSET(data.common_serial_bus.resource_source.index), ++ AML_OFFSET(common_serial_bus.res_source_index), ++ 1}, ++ ++ {ACPI_RSC_COUNT_SERIAL_RES, ++ ACPI_RS_OFFSET(data.common_serial_bus.resource_source.string_length), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ sizeof(struct aml_resource_common_serialbus)}, ++ ++ {ACPI_RSC_MOVE_SERIAL_RES, ++ ACPI_RS_OFFSET(data.common_serial_bus.resource_source.string_ptr), ++ AML_OFFSET(common_serial_bus.type_data_length), ++ sizeof(struct aml_resource_common_serialbus)}, ++ ++ /* Uart bus type specific */ ++ ++ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.uart_serial_bus.flow_control), ++ AML_OFFSET(uart_serial_bus.type_specific_flags), ++ 0}, ++ ++ {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.uart_serial_bus.stop_bits), ++ AML_OFFSET(uart_serial_bus.type_specific_flags), ++ 2}, ++ ++ {ACPI_RSC_3BITFLAG, ACPI_RS_OFFSET(data.uart_serial_bus.data_bits), ++ AML_OFFSET(uart_serial_bus.type_specific_flags), ++ 4}, ++ ++ {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.uart_serial_bus.endian), ++ AML_OFFSET(uart_serial_bus.type_specific_flags), ++ 7}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.uart_serial_bus.parity), ++ AML_OFFSET(uart_serial_bus.parity), ++ 1}, ++ ++ {ACPI_RSC_MOVE8, ACPI_RS_OFFSET(data.uart_serial_bus.lines_enabled), ++ AML_OFFSET(uart_serial_bus.lines_enabled), ++ 1}, ++ ++ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.uart_serial_bus.rx_fifo_size), ++ AML_OFFSET(uart_serial_bus.rx_fifo_size), ++ 1}, ++ ++ {ACPI_RSC_MOVE16, ACPI_RS_OFFSET(data.uart_serial_bus.tx_fifo_size), ++ AML_OFFSET(uart_serial_bus.tx_fifo_size), ++ 1}, ++ ++ {ACPI_RSC_MOVE32, ++ ACPI_RS_OFFSET(data.uart_serial_bus.default_baud_rate), ++ AML_OFFSET(uart_serial_bus.default_baud_rate), ++ 1}, ++}; +diff -Naur linux-3.2.16/drivers/acpi/acpica/rsutils.c linux-3.2.16.patch/drivers/acpi/acpica/rsutils.c +--- linux-3.2.16/drivers/acpi/acpica/rsutils.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/rsutils.c 2012-04-23 06:05:41.430124900 +0200 +@@ -144,6 +144,9 @@ + * since there are no alignment or endian issues + */ + case ACPI_RSC_MOVE8: ++ case ACPI_RSC_MOVE_GPIO_RES: ++ case ACPI_RSC_MOVE_SERIAL_VEN: ++ case ACPI_RSC_MOVE_SERIAL_RES: + ACPI_MEMCPY(destination, source, item_count); + return; + +@@ -153,6 +156,7 @@ + * misaligned memory transfers + */ + case ACPI_RSC_MOVE16: ++ case ACPI_RSC_MOVE_GPIO_PIN: + ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i], + &ACPI_CAST_PTR(u16, source)[i]); + break; +@@ -590,6 +594,56 @@ + + /******************************************************************************* + * ++ * FUNCTION: acpi_rs_get_aei_method_data ++ * ++ * PARAMETERS: Node - Device node ++ * ret_buffer - Pointer to a buffer structure for the ++ * results ++ * ++ * RETURN: Status ++ * ++ * DESCRIPTION: This function is called to get the _AEI value of an object ++ * contained in an object specified by the handle passed in ++ * ++ * If the function fails an appropriate status will be returned ++ * and the contents of the callers buffer is undefined. ++ * ++ ******************************************************************************/ ++ ++acpi_status ++acpi_rs_get_aei_method_data(struct acpi_namespace_node *node, ++ struct acpi_buffer *ret_buffer) ++{ ++ union acpi_operand_object *obj_desc; ++ acpi_status status; ++ ++ ACPI_FUNCTION_TRACE(rs_get_aei_method_data); ++ ++ /* Parameters guaranteed valid by caller */ ++ ++ /* Execute the method, no parameters */ ++ ++ status = acpi_ut_evaluate_object(node, METHOD_NAME__AEI, ++ ACPI_BTYPE_BUFFER, &obj_desc); ++ if (ACPI_FAILURE(status)) { ++ return_ACPI_STATUS(status); ++ } ++ ++ /* ++ * Make the call to create a resource linked list from the ++ * byte stream buffer that comes back from the _CRS method ++ * execution. ++ */ ++ status = acpi_rs_create_resource_list(obj_desc, ret_buffer); ++ ++ /* On exit, we must delete the object returned by evaluate_object */ ++ ++ acpi_ut_remove_reference(obj_desc); ++ return_ACPI_STATUS(status); ++} ++ ++/******************************************************************************* ++ * + * FUNCTION: acpi_rs_get_method_data + * + * PARAMETERS: Handle - Handle to the containing object +diff -Naur linux-3.2.16/drivers/acpi/acpica/rsxface.c linux-3.2.16.patch/drivers/acpi/acpica/rsxface.c +--- linux-3.2.16/drivers/acpi/acpica/rsxface.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/rsxface.c 2012-04-23 06:05:41.431124920 +0200 +@@ -307,6 +307,46 @@ + + ACPI_EXPORT_SYMBOL(acpi_set_current_resources) + ++/******************************************************************************* ++ * ++ * FUNCTION: acpi_get_event_resources ++ * ++ * PARAMETERS: device_handle - Handle to the device object for the ++ * device we are getting resources ++ * in_buffer - Pointer to a buffer containing the ++ * resources to be set for the device ++ * ++ * RETURN: Status ++ * ++ * DESCRIPTION: This function is called to get the event resources for a ++ * specific device. The caller must first acquire a handle for ++ * the desired device. The resource data is passed to the routine ++ * the buffer pointed to by the in_buffer variable. Uses the ++ * _AEI method. ++ * ++ ******************************************************************************/ ++acpi_status ++acpi_get_event_resources(acpi_handle device_handle, ++ struct acpi_buffer *ret_buffer) ++{ ++ acpi_status status; ++ struct acpi_namespace_node *node; ++ ++ ACPI_FUNCTION_TRACE(acpi_get_event_resources); ++ ++ /* Validate parameters then dispatch to internal routine */ ++ ++ status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); ++ if (ACPI_FAILURE(status)) { ++ return_ACPI_STATUS(status); ++ } ++ ++ status = acpi_rs_get_aei_method_data(node, ret_buffer); ++ return_ACPI_STATUS(status); ++} ++ ++ACPI_EXPORT_SYMBOL(acpi_get_event_resources) ++ + /****************************************************************************** + * + * FUNCTION: acpi_resource_to_address64 +@@ -486,8 +526,9 @@ + * + * PARAMETERS: device_handle - Handle to the device object for the + * device we are querying +- * Name - Method name of the resources we want +- * (METHOD_NAME__CRS or METHOD_NAME__PRS) ++ * Name - Method name of the resources we want. ++ * (METHOD_NAME__CRS, METHOD_NAME__PRS, or ++ * METHOD_NAME__AEI) + * user_function - Called for each resource + * Context - Passed to user_function + * +@@ -514,11 +555,12 @@ + + if (!device_handle || !user_function || !name || + (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) && +- !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS))) { ++ !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS) && ++ !ACPI_COMPARE_NAME(name, METHOD_NAME__AEI))) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + +- /* Get the _CRS or _PRS resource list */ ++ /* Get the _CRS/_PRS/_AEI resource list */ + + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_rs_get_method_data(device_handle, name, &buffer); +diff -Naur linux-3.2.16/drivers/acpi/acpica/tbfadt.c linux-3.2.16.patch/drivers/acpi/acpica/tbfadt.c +--- linux-3.2.16/drivers/acpi/acpica/tbfadt.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/tbfadt.c 2012-04-23 06:05:41.432124940 +0200 +@@ -253,8 +253,13 @@ + acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, + ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); + +- acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, +- ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); ++ /* If Hardware Reduced flag is set, there is no FACS */ ++ ++ if (!acpi_gbl_reduced_hardware) { ++ acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT. ++ Xfacs, ACPI_SIG_FACS, ++ ACPI_TABLE_INDEX_FACS); ++ } + } + + /******************************************************************************* +@@ -277,12 +282,12 @@ + { + /* + * Check if the FADT is larger than the largest table that we expect +- * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue ++ * (the ACPI 5.0 version). If so, truncate the table, and issue + * a warning. + */ + if (length > sizeof(struct acpi_table_fadt)) { + ACPI_WARNING((AE_INFO, +- "FADT (revision %u) is longer than ACPI 2.0 version, " ++ "FADT (revision %u) is longer than ACPI 5.0 version, " + "truncating length %u to %u", + table->revision, length, + (u32)sizeof(struct acpi_table_fadt))); +@@ -297,6 +302,13 @@ + ACPI_MEMCPY(&acpi_gbl_FADT, table, + ACPI_MIN(length, sizeof(struct acpi_table_fadt))); + ++ /* Take a copy of the Hardware Reduced flag */ ++ ++ acpi_gbl_reduced_hardware = FALSE; ++ if (acpi_gbl_FADT.flags & ACPI_FADT_HW_REDUCED) { ++ acpi_gbl_reduced_hardware = TRUE; ++ } ++ + /* Convert the local copy of the FADT to the common internal format */ + + acpi_tb_convert_fadt(); +@@ -502,6 +514,12 @@ + acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; + } + ++ /* If Hardware Reduced flag is set, we are all done */ ++ ++ if (acpi_gbl_reduced_hardware) { ++ return; ++ } ++ + /* Examine all of the 64-bit extended address fields (X fields) */ + + for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { +diff -Naur linux-3.2.16/drivers/acpi/acpica/tbutils.c linux-3.2.16.patch/drivers/acpi/acpica/tbutils.c +--- linux-3.2.16/drivers/acpi/acpica/tbutils.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/tbutils.c 2012-04-23 06:05:41.433124960 +0200 +@@ -135,6 +135,13 @@ + { + acpi_status status; + ++ /* If Hardware Reduced flag is set, there is no FACS */ ++ ++ if (acpi_gbl_reduced_hardware) { ++ acpi_gbl_FACS = NULL; ++ return (AE_OK); ++ } ++ + status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, + ACPI_CAST_INDIRECT_PTR(struct + acpi_table_header, +diff -Naur linux-3.2.16/drivers/acpi/acpica/utdecode.c linux-3.2.16.patch/drivers/acpi/acpica/utdecode.c +--- linux-3.2.16/drivers/acpi/acpica/utdecode.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/utdecode.c 2012-04-23 06:05:41.433124960 +0200 +@@ -171,7 +171,9 @@ + "SMBus", + "SystemCMOS", + "PCIBARTarget", +- "IPMI" ++ "IPMI", ++ "GeneralPurposeIo", ++ "GenericSerialBus" + }; + + char *acpi_ut_get_region_name(u8 space_id) +diff -Naur linux-3.2.16/drivers/acpi/acpica/utmutex.c linux-3.2.16.patch/drivers/acpi/acpica/utmutex.c +--- linux-3.2.16/drivers/acpi/acpica/utmutex.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/utmutex.c 2012-04-23 06:05:41.434124980 +0200 +@@ -293,14 +293,10 @@ + + acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) + { +- acpi_thread_id this_thread_id; +- + ACPI_FUNCTION_NAME(ut_release_mutex); + +- this_thread_id = acpi_os_get_thread_id(); +- + ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n", +- (u32)this_thread_id, ++ (u32)acpi_os_get_thread_id(), + acpi_ut_get_mutex_name(mutex_id))); + + if (mutex_id > ACPI_MAX_MUTEX) { +@@ -329,7 +325,8 @@ + * the ACPI subsystem code. + */ + for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) { +- if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { ++ if (acpi_gbl_mutex_info[i].thread_id == ++ acpi_os_get_thread_id()) { + if (i == mutex_id) { + continue; + } +diff -Naur linux-3.2.16/drivers/acpi/acpica/utresrc.c linux-3.2.16.patch/drivers/acpi/acpica/utresrc.c +--- linux-3.2.16/drivers/acpi/acpica/utresrc.c 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/drivers/acpi/acpica/utresrc.c 2012-04-23 06:05:41.435125000 +0200 +@@ -43,7 +43,7 @@ + + #include + #include "accommon.h" +-#include "amlresrc.h" ++#include "acresrc.h" + + #define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME("utresrc") +@@ -154,6 +154,138 @@ + "TypeF" + }; + ++const char *acpi_gbl_ppc_decode[] = { ++ "PullDefault", ++ "PullUp", ++ "PullDown", ++ "PullNone" ++}; ++ ++const char *acpi_gbl_ior_decode[] = { ++ "IoRestrictionNone", ++ "IoRestrictionInputOnly", ++ "IoRestrictionOutputOnly", ++ "IoRestrictionNoneAndPreserve" ++}; ++ ++const char *acpi_gbl_dts_decode[] = { ++ "Width8bit", ++ "Width16bit", ++ "Width32bit", ++ "Width64bit", ++ "Width128bit", ++ "Width256bit", ++}; ++ ++/* GPIO connection type */ ++ ++const char *acpi_gbl_ct_decode[] = { ++ "Interrupt", ++ "I/O" ++}; ++ ++/* Serial bus type */ ++ ++const char *acpi_gbl_sbt_decode[] = { ++ "/* UNKNOWN serial bus type */", ++ "I2C", ++ "SPI", ++ "UART" ++}; ++ ++/* I2C serial bus access mode */ ++ ++const char *acpi_gbl_am_decode[] = { ++ "AddressingMode7Bit", ++ "AddressingMode10Bit" ++}; ++ ++/* I2C serial bus slave mode */ ++ ++const char *acpi_gbl_sm_decode[] = { ++ "ControllerInitiated", ++ "DeviceInitiated" ++}; ++ ++/* SPI serial bus wire mode */ ++ ++const char *acpi_gbl_wm_decode[] = { ++ "FourWireMode", ++ "ThreeWireMode" ++}; ++ ++/* SPI serial clock phase */ ++ ++const char *acpi_gbl_cph_decode[] = { ++ "ClockPhaseFirst", ++ "ClockPhaseSecond" ++}; ++ ++/* SPI serial bus clock polarity */ ++ ++const char *acpi_gbl_cpo_decode[] = { ++ "ClockPolarityLow", ++ "ClockPolarityHigh" ++}; ++ ++/* SPI serial bus device polarity */ ++ ++const char *acpi_gbl_dp_decode[] = { ++ "PolarityLow", ++ "PolarityHigh" ++}; ++ ++/* UART serial bus endian */ ++ ++const char *acpi_gbl_ed_decode[] = { ++ "LittleEndian", ++ "BigEndian" ++}; ++ ++/* UART serial bus bits per byte */ ++ ++const char *acpi_gbl_bpb_decode[] = { ++ "DataBitsFive", ++ "DataBitsSix", ++ "DataBitsSeven", ++ "DataBitsEight", ++ "DataBitsNine", ++ "/* UNKNOWN Bits per byte */", ++ "/* UNKNOWN Bits per byte */", ++ "/* UNKNOWN Bits per byte */" ++}; ++ ++/* UART serial bus stop bits */ ++ ++const char *acpi_gbl_sb_decode[] = { ++ "StopBitsNone", ++ "StopBitsOne", ++ "StopBitsOnePlusHalf", ++ "StopBitsTwo" ++}; ++ ++/* UART serial bus flow control */ ++ ++const char *acpi_gbl_fc_decode[] = { ++ "FlowControlNone", ++ "FlowControlHardware", ++ "FlowControlXON", ++ "/* UNKNOWN flow control keyword */" ++}; ++ ++/* UART serial bus parity type */ ++ ++const char *acpi_gbl_pt_decode[] = { ++ "ParityTypeNone", ++ "ParityTypeEven", ++ "ParityTypeOdd", ++ "ParityTypeMark", ++ "ParityTypeSpace", ++ "/* UNKNOWN parity keyword */", ++ "/* UNKNOWN parity keyword */", ++ "/* UNKNOWN parity keyword */" ++}; ++ + #endif + + /* +@@ -173,7 +305,7 @@ + ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent), + ACPI_AML_SIZE_SMALL(struct aml_resource_io), + ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io), +- 0, ++ ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_dma), + 0, + 0, + 0, +@@ -193,7 +325,17 @@ + ACPI_AML_SIZE_LARGE(struct aml_resource_address16), + ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq), + ACPI_AML_SIZE_LARGE(struct aml_resource_address64), +- ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64) ++ ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64), ++ ACPI_AML_SIZE_LARGE(struct aml_resource_gpio), ++ 0, ++ ACPI_AML_SIZE_LARGE(struct aml_resource_common_serialbus), ++}; ++ ++const u8 acpi_gbl_resource_aml_serial_bus_sizes[] = { ++ 0, ++ ACPI_AML_SIZE_LARGE(struct aml_resource_i2c_serialbus), ++ ACPI_AML_SIZE_LARGE(struct aml_resource_spi_serialbus), ++ ACPI_AML_SIZE_LARGE(struct aml_resource_uart_serialbus), + }; + + /* +@@ -209,35 +351,49 @@ + 0, + 0, + 0, +- ACPI_SMALL_VARIABLE_LENGTH, +- ACPI_FIXED_LENGTH, +- ACPI_SMALL_VARIABLE_LENGTH, +- ACPI_FIXED_LENGTH, +- ACPI_FIXED_LENGTH, +- ACPI_FIXED_LENGTH, +- 0, ++ ACPI_SMALL_VARIABLE_LENGTH, /* 04 IRQ */ ++ ACPI_FIXED_LENGTH, /* 05 DMA */ ++ ACPI_SMALL_VARIABLE_LENGTH, /* 06 start_dependent_functions */ ++ ACPI_FIXED_LENGTH, /* 07 end_dependent_functions */ ++ ACPI_FIXED_LENGTH, /* 08 IO */ ++ ACPI_FIXED_LENGTH, /* 09 fixed_iO */ ++ ACPI_FIXED_LENGTH, /* 0_a fixed_dMA */ + 0, + 0, + 0, +- ACPI_VARIABLE_LENGTH, +- ACPI_FIXED_LENGTH, ++ ACPI_VARIABLE_LENGTH, /* 0_e vendor_short */ ++ ACPI_FIXED_LENGTH, /* 0_f end_tag */ + + /* Large descriptors */ + + 0, +- ACPI_FIXED_LENGTH, +- ACPI_FIXED_LENGTH, ++ ACPI_FIXED_LENGTH, /* 01 Memory24 */ ++ ACPI_FIXED_LENGTH, /* 02 generic_register */ ++ 0, ++ ACPI_VARIABLE_LENGTH, /* 04 vendor_long */ ++ ACPI_FIXED_LENGTH, /* 05 Memory32 */ ++ ACPI_FIXED_LENGTH, /* 06 memory32_fixed */ ++ ACPI_VARIABLE_LENGTH, /* 07 Dword* address */ ++ ACPI_VARIABLE_LENGTH, /* 08 Word* address */ ++ ACPI_VARIABLE_LENGTH, /* 09 extended_iRQ */ ++ ACPI_VARIABLE_LENGTH, /* 0_a Qword* address */ ++ ACPI_FIXED_LENGTH, /* 0_b Extended* address */ ++ ACPI_VARIABLE_LENGTH, /* 0_c Gpio* */ + 0, +- ACPI_VARIABLE_LENGTH, +- ACPI_FIXED_LENGTH, +- ACPI_FIXED_LENGTH, +- ACPI_VARIABLE_LENGTH, +- ACPI_VARIABLE_LENGTH, +- ACPI_VARIABLE_LENGTH, +- ACPI_VARIABLE_LENGTH, +- ACPI_FIXED_LENGTH ++ ACPI_VARIABLE_LENGTH /* 0_e *serial_bus */ + }; + ++/* ++ * For the i_aSL compiler/disassembler, we don't want any error messages ++ * because the disassembler uses the resource validation code to determine ++ * if Buffer objects are actually Resource Templates. ++ */ ++#ifdef ACPI_ASL_COMPILER ++#define ACPI_RESOURCE_ERROR(plist) ++#else ++#define ACPI_RESOURCE_ERROR(plist) ACPI_ERROR(plist) ++#endif ++ + /******************************************************************************* + * + * FUNCTION: acpi_ut_walk_aml_resources +@@ -265,6 +421,7 @@ + u8 resource_index; + u32 length; + u32 offset = 0; ++ u8 end_tag[2] = { 0x79, 0x00 }; + + ACPI_FUNCTION_TRACE(ut_walk_aml_resources); + +@@ -286,6 +443,10 @@ + + status = acpi_ut_validate_resource(aml, &resource_index); + if (ACPI_FAILURE(status)) { ++ /* ++ * Exit on failure. Cannot continue because the descriptor length ++ * may be bogus also. ++ */ + return_ACPI_STATUS(status); + } + +@@ -300,7 +461,7 @@ + user_function(aml, length, offset, resource_index, + context); + if (ACPI_FAILURE(status)) { +- return (status); ++ return_ACPI_STATUS(status); + } + } + +@@ -333,7 +494,19 @@ + + /* Did not find an end_tag descriptor */ + +- return (AE_AML_NO_RESOURCE_END_TAG); ++ if (user_function) { ++ ++ /* Insert an end_tag anyway. acpi_rs_get_list_length always leaves room */ ++ ++ (void)acpi_ut_validate_resource(end_tag, &resource_index); ++ status = ++ user_function(end_tag, 2, offset, resource_index, context); ++ if (ACPI_FAILURE(status)) { ++ return_ACPI_STATUS(status); ++ } ++ } ++ ++ return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); + } + + /******************************************************************************* +@@ -354,6 +527,7 @@ + + acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index) + { ++ union aml_resource *aml_resource; + u8 resource_type; + u8 resource_index; + acpi_rs_length resource_length; +@@ -375,7 +549,7 @@ + /* Verify the large resource type (name) against the max */ + + if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { +- return (AE_AML_INVALID_RESOURCE_TYPE); ++ goto invalid_resource; + } + + /* +@@ -392,15 +566,17 @@ + ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3); + } + +- /* Check validity of the resource type, zero indicates name is invalid */ +- ++ /* ++ * Check validity of the resource type, via acpi_gbl_resource_types. Zero ++ * indicates an invalid resource. ++ */ + if (!acpi_gbl_resource_types[resource_index]) { +- return (AE_AML_INVALID_RESOURCE_TYPE); ++ goto invalid_resource; + } + + /* +- * 2) Validate the resource_length field. This ensures that the length +- * is at least reasonable, and guarantees that it is non-zero. ++ * Validate the resource_length field. This ensures that the length ++ * is at least reasonable, and guarantees that it is non-zero. + */ + resource_length = acpi_ut_get_resource_length(aml); + minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index]; +@@ -413,7 +589,7 @@ + /* Fixed length resource, length must match exactly */ + + if (resource_length != minimum_resource_length) { +- return (AE_AML_BAD_RESOURCE_LENGTH); ++ goto bad_resource_length; + } + break; + +@@ -422,7 +598,7 @@ + /* Variable length resource, length must be at least the minimum */ + + if (resource_length < minimum_resource_length) { +- return (AE_AML_BAD_RESOURCE_LENGTH); ++ goto bad_resource_length; + } + break; + +@@ -432,7 +608,7 @@ + + if ((resource_length > minimum_resource_length) || + (resource_length < (minimum_resource_length - 1))) { +- return (AE_AML_BAD_RESOURCE_LENGTH); ++ goto bad_resource_length; + } + break; + +@@ -440,7 +616,23 @@ + + /* Shouldn't happen (because of validation earlier), but be sure */ + +- return (AE_AML_INVALID_RESOURCE_TYPE); ++ goto invalid_resource; ++ } ++ ++ aml_resource = ACPI_CAST_PTR(union aml_resource, aml); ++ if (resource_type == ACPI_RESOURCE_NAME_SERIAL_BUS) { ++ ++ /* Validate the bus_type field */ ++ ++ if ((aml_resource->common_serial_bus.type == 0) || ++ (aml_resource->common_serial_bus.type > ++ AML_RESOURCE_MAX_SERIALBUSTYPE)) { ++ ACPI_RESOURCE_ERROR((AE_INFO, ++ "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X", ++ aml_resource->common_serial_bus. ++ type)); ++ return (AE_AML_INVALID_RESOURCE_TYPE); ++ } + } + + /* Optionally return the resource table index */ +@@ -450,6 +642,22 @@ + } + + return (AE_OK); ++ ++ invalid_resource: ++ ++ ACPI_RESOURCE_ERROR((AE_INFO, ++ "Invalid/unsupported resource descriptor: Type 0x%2.2X", ++ resource_type)); ++ return (AE_AML_INVALID_RESOURCE_TYPE); ++ ++ bad_resource_length: ++ ++ ACPI_RESOURCE_ERROR((AE_INFO, ++ "Invalid resource descriptor length: Type " ++ "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X", ++ resource_type, resource_length, ++ minimum_resource_length)); ++ return (AE_AML_BAD_RESOURCE_LENGTH); + } + + /******************************************************************************* +diff -Naur linux-3.2.16/drivers/acpi/acpica/utxfmutex.c linux-3.2.16.patch/drivers/acpi/acpica/utxfmutex.c +--- linux-3.2.16/drivers/acpi/acpica/utxfmutex.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.2.16.patch/drivers/acpi/acpica/utxfmutex.c 2012-04-23 06:05:41.436125021 +0200 +@@ -0,0 +1,187 @@ ++/******************************************************************************* ++ * ++ * Module Name: utxfmutex - external AML mutex access functions ++ * ++ ******************************************************************************/ ++ ++/* ++ * Copyright (C) 2000 - 2011, Intel Corp. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce at minimum a disclaimer ++ * substantially similar to the "NO WARRANTY" disclaimer below ++ * ("Disclaimer") and any redistribution must be conditioned upon ++ * including a substantially similar Disclaimer requirement for further ++ * binary redistribution. ++ * 3. Neither the names of the above-listed copyright holders nor the names ++ * of any contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * Alternatively, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2 as published by the Free ++ * Software Foundation. ++ * ++ * NO WARRANTY ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGES. ++ */ ++ ++#include ++#include "accommon.h" ++#include "acnamesp.h" ++ ++#define _COMPONENT ACPI_UTILITIES ++ACPI_MODULE_NAME("utxfmutex") ++ ++/* Local prototypes */ ++static acpi_status ++acpi_ut_get_mutex_object(acpi_handle handle, ++ acpi_string pathname, ++ union acpi_operand_object **ret_obj); ++ ++/******************************************************************************* ++ * ++ * FUNCTION: acpi_ut_get_mutex_object ++ * ++ * PARAMETERS: Handle - Mutex or prefix handle (optional) ++ * Pathname - Mutex pathname (optional) ++ * ret_obj - Where the mutex object is returned ++ * ++ * RETURN: Status ++ * ++ * DESCRIPTION: Get an AML mutex object. The mutex node is pointed to by ++ * Handle:Pathname. Either Handle or Pathname can be NULL, but ++ * not both. ++ * ++ ******************************************************************************/ ++ ++static acpi_status ++acpi_ut_get_mutex_object(acpi_handle handle, ++ acpi_string pathname, ++ union acpi_operand_object **ret_obj) ++{ ++ struct acpi_namespace_node *mutex_node; ++ union acpi_operand_object *mutex_obj; ++ acpi_status status; ++ ++ /* Parameter validation */ ++ ++ if (!ret_obj || (!handle && !pathname)) { ++ return (AE_BAD_PARAMETER); ++ } ++ ++ /* Get a the namespace node for the mutex */ ++ ++ mutex_node = handle; ++ if (pathname != NULL) { ++ status = acpi_get_handle(handle, pathname, ++ ACPI_CAST_PTR(acpi_handle, ++ &mutex_node)); ++ if (ACPI_FAILURE(status)) { ++ return (status); ++ } ++ } ++ ++ /* Ensure that we actually have a Mutex object */ ++ ++ if (!mutex_node || (mutex_node->type != ACPI_TYPE_MUTEX)) { ++ return (AE_TYPE); ++ } ++ ++ /* Get the low-level mutex object */ ++ ++ mutex_obj = acpi_ns_get_attached_object(mutex_node); ++ if (!mutex_obj) { ++ return (AE_NULL_OBJECT); ++ } ++ ++ *ret_obj = mutex_obj; ++ return (AE_OK); ++} ++ ++/******************************************************************************* ++ * ++ * FUNCTION: acpi_acquire_mutex ++ * ++ * PARAMETERS: Handle - Mutex or prefix handle (optional) ++ * Pathname - Mutex pathname (optional) ++ * Timeout - Max time to wait for the lock (millisec) ++ * ++ * RETURN: Status ++ * ++ * DESCRIPTION: Acquire an AML mutex. This is a device driver interface to ++ * AML mutex objects, and allows for transaction locking between ++ * drivers and AML code. The mutex node is pointed to by ++ * Handle:Pathname. Either Handle or Pathname can be NULL, but ++ * not both. ++ * ++ ******************************************************************************/ ++ ++acpi_status ++acpi_acquire_mutex(acpi_handle handle, acpi_string pathname, u16 timeout) ++{ ++ acpi_status status; ++ union acpi_operand_object *mutex_obj; ++ ++ /* Get the low-level mutex associated with Handle:Pathname */ ++ ++ status = acpi_ut_get_mutex_object(handle, pathname, &mutex_obj); ++ if (ACPI_FAILURE(status)) { ++ return (status); ++ } ++ ++ /* Acquire the OS mutex */ ++ ++ status = acpi_os_acquire_mutex(mutex_obj->mutex.os_mutex, timeout); ++ return (status); ++} ++ ++/******************************************************************************* ++ * ++ * FUNCTION: acpi_release_mutex ++ * ++ * PARAMETERS: Handle - Mutex or prefix handle (optional) ++ * Pathname - Mutex pathname (optional) ++ * ++ * RETURN: Status ++ * ++ * DESCRIPTION: Release an AML mutex. This is a device driver interface to ++ * AML mutex objects, and allows for transaction locking between ++ * drivers and AML code. The mutex node is pointed to by ++ * Handle:Pathname. Either Handle or Pathname can be NULL, but ++ * not both. ++ * ++ ******************************************************************************/ ++ ++acpi_status acpi_release_mutex(acpi_handle handle, acpi_string pathname) ++{ ++ acpi_status status; ++ union acpi_operand_object *mutex_obj; ++ ++ /* Get the low-level mutex associated with Handle:Pathname */ ++ ++ status = acpi_ut_get_mutex_object(handle, pathname, &mutex_obj); ++ if (ACPI_FAILURE(status)) { ++ return (status); ++ } ++ ++ /* Release the OS mutex */ ++ ++ acpi_os_release_mutex(mutex_obj->mutex.os_mutex); ++ return (AE_OK); ++} +diff -Naur linux-3.2.16/include/acpi/acnames.h linux-3.2.16.patch/include/acpi/acnames.h +--- linux-3.2.16/include/acpi/acnames.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/include/acpi/acnames.h 2012-04-23 06:05:41.436125021 +0200 +@@ -58,6 +58,7 @@ + #define METHOD_NAME__PRT "_PRT" + #define METHOD_NAME__CRS "_CRS" + #define METHOD_NAME__PRS "_PRS" ++#define METHOD_NAME__AEI "_AEI" + #define METHOD_NAME__PRW "_PRW" + #define METHOD_NAME__SRS "_SRS" + +diff -Naur linux-3.2.16/include/acpi/acpixf.h linux-3.2.16.patch/include/acpi/acpixf.h +--- linux-3.2.16/include/acpi/acpixf.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/include/acpi/acpixf.h 2012-04-23 06:05:41.437125041 +0200 +@@ -47,7 +47,7 @@ + + /* Current ACPICA subsystem version in YYYYMMDD format */ + +-#define ACPI_CA_VERSION 0x20110623 ++#define ACPI_CA_VERSION 0x20111123 + + #include "actypes.h" + #include "actbl.h" +@@ -74,6 +74,7 @@ + extern u32 acpi_current_gpe_count; + extern struct acpi_table_fadt acpi_gbl_FADT; + extern u8 acpi_gbl_system_awake_and_running; ++extern u8 acpi_gbl_reduced_hardware; /* ACPI 5.0 */ + + extern u32 acpi_rsdt_forced; + /* +@@ -276,12 +277,23 @@ + acpi_status acpi_install_interface_handler(acpi_interface_handler handler); + + /* +- * Event interfaces ++ * Global Lock interfaces + */ + acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle); + + acpi_status acpi_release_global_lock(u32 handle); + ++/* ++ * Interfaces to AML mutex objects ++ */ ++acpi_status ++acpi_acquire_mutex(acpi_handle handle, acpi_string pathname, u16 timeout); ++ ++acpi_status acpi_release_mutex(acpi_handle handle, acpi_string pathname); ++ ++/* ++ * Fixed Event interfaces ++ */ + acpi_status acpi_enable_event(u32 event, u32 flags); + + acpi_status acpi_disable_event(u32 event, u32 flags); +@@ -291,7 +303,7 @@ + acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status); + + /* +- * GPE Interfaces ++ * General Purpose Event (GPE) Interfaces + */ + acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number); + +@@ -346,6 +358,10 @@ + #endif + + acpi_status ++acpi_get_event_resources(acpi_handle device_handle, ++ struct acpi_buffer *ret_buffer); ++ ++acpi_status + acpi_walk_resources(acpi_handle device, + char *name, + acpi_walk_resource_callback user_function, void *context); +@@ -360,6 +376,11 @@ + acpi_resource_to_address64(struct acpi_resource *resource, + struct acpi_resource_address64 *out); + ++acpi_status ++acpi_buffer_to_resource(u8 *aml_buffer, ++ u16 aml_buffer_length, ++ struct acpi_resource **resource_ptr); ++ + /* + * Hardware (ACPI device) interfaces + */ +diff -Naur linux-3.2.16/include/acpi/acrestyp.h linux-3.2.16.patch/include/acpi/acrestyp.h +--- linux-3.2.16/include/acpi/acrestyp.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/include/acpi/acrestyp.h 2012-04-23 06:05:41.438125061 +0200 +@@ -61,11 +61,14 @@ + #define ACPI_WRITE_COMBINING_MEMORY (u8) 0x02 + #define ACPI_PREFETCHABLE_MEMORY (u8) 0x03 + ++/*! [Begin] no source code translation */ + /* + * IO Attributes +- * The ISA IO ranges are: n000-n0_fFh, n400-n4_fFh, n800-n8_fFh, n_c00-n_cFFh. +- * The non-ISA IO ranges are: n100-n3_fFh, n500-n7_fFh, n900-n_bFFh, n_cd0-n_fFFh. ++ * The ISA IO ranges are: n000-n0FFh, n400-n4FFh, n800-n8FFh, nC00-nCFFh. ++ * The non-ISA IO ranges are: n100-n3FFh, n500-n7FFh, n900-nBFFh, nCD0-nFFFh. + */ ++/*! [End] no source code translation !*/ ++ + #define ACPI_NON_ISA_ONLY_RANGES (u8) 0x01 + #define ACPI_ISA_ONLY_RANGES (u8) 0x02 + #define ACPI_ENTIRE_RANGE (ACPI_NON_ISA_ONLY_RANGES | ACPI_ISA_ONLY_RANGES) +@@ -81,16 +84,26 @@ + #define ACPI_DECODE_16 (u8) 0x01 /* 16-bit IO address decode */ + + /* +- * IRQ Attributes ++ * Interrupt attributes - used in multiple descriptors + */ ++ ++/* Triggering */ ++ + #define ACPI_LEVEL_SENSITIVE (u8) 0x00 + #define ACPI_EDGE_SENSITIVE (u8) 0x01 + ++/* Polarity */ ++ + #define ACPI_ACTIVE_HIGH (u8) 0x00 + #define ACPI_ACTIVE_LOW (u8) 0x01 ++#define ACPI_ACTIVE_BOTH (u8) 0x02 ++ ++/* Sharing */ + + #define ACPI_EXCLUSIVE (u8) 0x00 + #define ACPI_SHARED (u8) 0x01 ++#define ACPI_EXCLUSIVE_AND_WAKE (u8) 0x02 ++#define ACPI_SHARED_AND_WAKE (u8) 0x03 + + /* + * DMA Attributes +@@ -127,6 +140,8 @@ + #define ACPI_POS_DECODE (u8) 0x00 + #define ACPI_SUB_DECODE (u8) 0x01 + ++/* Producer/Consumer */ ++ + #define ACPI_PRODUCER (u8) 0x00 + #define ACPI_CONSUMER (u8) 0x01 + +@@ -192,6 +207,21 @@ + u8 address_length; + }; + ++struct acpi_resource_fixed_dma { ++ u16 request_lines; ++ u16 channels; ++ u8 width; ++}; ++ ++/* Values for Width field above */ ++ ++#define ACPI_DMA_WIDTH8 0 ++#define ACPI_DMA_WIDTH16 1 ++#define ACPI_DMA_WIDTH32 2 ++#define ACPI_DMA_WIDTH64 3 ++#define ACPI_DMA_WIDTH128 4 ++#define ACPI_DMA_WIDTH256 5 ++ + struct acpi_resource_vendor { + u16 byte_length; + u8 byte_data[1]; +@@ -329,6 +359,166 @@ + u64 address; + }; + ++struct acpi_resource_gpio { ++ u8 revision_id; ++ u8 connection_type; ++ u8 producer_consumer; /* For values, see Producer/Consumer above */ ++ u8 pin_config; ++ u8 sharable; /* For values, see Interrupt Attributes above */ ++ u8 io_restriction; ++ u8 triggering; /* For values, see Interrupt Attributes above */ ++ u8 polarity; /* For values, see Interrupt Attributes above */ ++ u16 drive_strength; ++ u16 debounce_timeout; ++ u16 pin_table_length; ++ u16 vendor_length; ++ struct acpi_resource_source resource_source; ++ u16 *pin_table; ++ u8 *vendor_data; ++}; ++ ++/* Values for GPIO connection_type field above */ ++ ++#define ACPI_RESOURCE_GPIO_TYPE_INT 0 ++#define ACPI_RESOURCE_GPIO_TYPE_IO 1 ++ ++/* Values for pin_config field above */ ++ ++#define ACPI_PIN_CONFIG_DEFAULT 0 ++#define ACPI_PIN_CONFIG_PULLUP 1 ++#define ACPI_PIN_CONFIG_PULLDOWN 2 ++#define ACPI_PIN_CONFIG_NOPULL 3 ++ ++/* Values for io_restriction field above */ ++ ++#define ACPI_IO_RESTRICT_NONE 0 ++#define ACPI_IO_RESTRICT_INPUT 1 ++#define ACPI_IO_RESTRICT_OUTPUT 2 ++#define ACPI_IO_RESTRICT_NONE_PRESERVE 3 ++ ++/* Common structure for I2C, SPI, and UART serial descriptors */ ++ ++#define ACPI_RESOURCE_SERIAL_COMMON \ ++ u8 revision_id; \ ++ u8 type; \ ++ u8 producer_consumer; /* For values, see Producer/Consumer above */\ ++ u8 slave_mode; \ ++ u8 type_revision_id; \ ++ u16 type_data_length; \ ++ u16 vendor_length; \ ++ struct acpi_resource_source resource_source; \ ++ u8 *vendor_data; ++ ++struct acpi_resource_common_serialbus { ++ACPI_RESOURCE_SERIAL_COMMON}; ++ ++/* Values for the Type field above */ ++ ++#define ACPI_RESOURCE_SERIAL_TYPE_I2C 1 ++#define ACPI_RESOURCE_SERIAL_TYPE_SPI 2 ++#define ACPI_RESOURCE_SERIAL_TYPE_UART 3 ++ ++/* Values for slave_mode field above */ ++ ++#define ACPI_CONTROLLER_INITIATED 0 ++#define ACPI_DEVICE_INITIATED 1 ++ ++struct acpi_resource_i2c_serialbus { ++ ACPI_RESOURCE_SERIAL_COMMON u8 access_mode; ++ u16 slave_address; ++ u32 connection_speed; ++}; ++ ++/* Values for access_mode field above */ ++ ++#define ACPI_I2C_7BIT_MODE 0 ++#define ACPI_I2C_10BIT_MODE 1 ++ ++struct acpi_resource_spi_serialbus { ++ ACPI_RESOURCE_SERIAL_COMMON u8 wire_mode; ++ u8 device_polarity; ++ u8 data_bit_length; ++ u8 clock_phase; ++ u8 clock_polarity; ++ u16 device_selection; ++ u32 connection_speed; ++}; ++ ++/* Values for wire_mode field above */ ++ ++#define ACPI_SPI_4WIRE_MODE 0 ++#define ACPI_SPI_3WIRE_MODE 1 ++ ++/* Values for device_polarity field above */ ++ ++#define ACPI_SPI_ACTIVE_LOW 0 ++#define ACPI_SPI_ACTIVE_HIGH 1 ++ ++/* Values for clock_phase field above */ ++ ++#define ACPI_SPI_FIRST_PHASE 0 ++#define ACPI_SPI_SECOND_PHASE 1 ++ ++/* Values for clock_polarity field above */ ++ ++#define ACPI_SPI_START_LOW 0 ++#define ACPI_SPI_START_HIGH 1 ++ ++struct acpi_resource_uart_serialbus { ++ ACPI_RESOURCE_SERIAL_COMMON u8 endian; ++ u8 data_bits; ++ u8 stop_bits; ++ u8 flow_control; ++ u8 parity; ++ u8 lines_enabled; ++ u16 rx_fifo_size; ++ u16 tx_fifo_size; ++ u32 default_baud_rate; ++}; ++ ++/* Values for Endian field above */ ++ ++#define ACPI_UART_LITTLE_ENDIAN 0 ++#define ACPI_UART_BIG_ENDIAN 1 ++ ++/* Values for data_bits field above */ ++ ++#define ACPI_UART_5_DATA_BITS 0 ++#define ACPI_UART_6_DATA_BITS 1 ++#define ACPI_UART_7_DATA_BITS 2 ++#define ACPI_UART_8_DATA_BITS 3 ++#define ACPI_UART_9_DATA_BITS 4 ++ ++/* Values for stop_bits field above */ ++ ++#define ACPI_UART_NO_STOP_BITS 0 ++#define ACPI_UART_1_STOP_BIT 1 ++#define ACPI_UART_1P5_STOP_BITS 2 ++#define ACPI_UART_2_STOP_BITS 3 ++ ++/* Values for flow_control field above */ ++ ++#define ACPI_UART_FLOW_CONTROL_NONE 0 ++#define ACPI_UART_FLOW_CONTROL_HW 1 ++#define ACPI_UART_FLOW_CONTROL_XON_XOFF 2 ++ ++/* Values for Parity field above */ ++ ++#define ACPI_UART_PARITY_NONE 0 ++#define ACPI_UART_PARITY_EVEN 1 ++#define ACPI_UART_PARITY_ODD 2 ++#define ACPI_UART_PARITY_MARK 3 ++#define ACPI_UART_PARITY_SPACE 4 ++ ++/* Values for lines_enabled bitfield above */ ++ ++#define ACPI_UART_CARRIER_DETECT (1<<2) ++#define ACPI_UART_RING_INDICATOR (1<<3) ++#define ACPI_UART_DATA_SET_READY (1<<4) ++#define ACPI_UART_DATA_TERMINAL_READY (1<<5) ++#define ACPI_UART_CLEAR_TO_SEND (1<<6) ++#define ACPI_UART_REQUEST_TO_SEND (1<<7) ++ + /* ACPI_RESOURCE_TYPEs */ + + #define ACPI_RESOURCE_TYPE_IRQ 0 +@@ -348,7 +538,10 @@ + #define ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64 14 /* ACPI 3.0 */ + #define ACPI_RESOURCE_TYPE_EXTENDED_IRQ 15 + #define ACPI_RESOURCE_TYPE_GENERIC_REGISTER 16 +-#define ACPI_RESOURCE_TYPE_MAX 16 ++#define ACPI_RESOURCE_TYPE_GPIO 17 /* ACPI 5.0 */ ++#define ACPI_RESOURCE_TYPE_FIXED_DMA 18 /* ACPI 5.0 */ ++#define ACPI_RESOURCE_TYPE_SERIAL_BUS 19 /* ACPI 5.0 */ ++#define ACPI_RESOURCE_TYPE_MAX 19 + + /* Master union for resource descriptors */ + +@@ -358,6 +551,7 @@ + struct acpi_resource_start_dependent start_dpf; + struct acpi_resource_io io; + struct acpi_resource_fixed_io fixed_io; ++ struct acpi_resource_fixed_dma fixed_dma; + struct acpi_resource_vendor vendor; + struct acpi_resource_vendor_typed vendor_typed; + struct acpi_resource_end_tag end_tag; +@@ -370,6 +564,11 @@ + struct acpi_resource_extended_address64 ext_address64; + struct acpi_resource_extended_irq extended_irq; + struct acpi_resource_generic_register generic_reg; ++ struct acpi_resource_gpio gpio; ++ struct acpi_resource_i2c_serialbus i2c_serial_bus; ++ struct acpi_resource_spi_serialbus spi_serial_bus; ++ struct acpi_resource_uart_serialbus uart_serial_bus; ++ struct acpi_resource_common_serialbus common_serial_bus; + + /* Common fields */ + +diff -Naur linux-3.2.16/include/acpi/actbl1.h linux-3.2.16.patch/include/acpi/actbl1.h +--- linux-3.2.16/include/acpi/actbl1.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/include/acpi/actbl1.h 2012-04-23 06:05:41.439125081 +0200 +@@ -228,7 +228,8 @@ + ACPI_EINJ_EXECUTE_OPERATION = 5, + ACPI_EINJ_CHECK_BUSY_STATUS = 6, + ACPI_EINJ_GET_COMMAND_STATUS = 7, +- ACPI_EINJ_ACTION_RESERVED = 8, /* 8 and greater are reserved */ ++ ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS = 8, ++ ACPI_EINJ_ACTION_RESERVED = 9, /* 9 and greater are reserved */ + ACPI_EINJ_TRIGGER_ERROR = 0xFF /* Except for this value */ + }; + +@@ -240,7 +241,27 @@ + ACPI_EINJ_WRITE_REGISTER = 2, + ACPI_EINJ_WRITE_REGISTER_VALUE = 3, + ACPI_EINJ_NOOP = 4, +- ACPI_EINJ_INSTRUCTION_RESERVED = 5 /* 5 and greater are reserved */ ++ ACPI_EINJ_FLUSH_CACHELINE = 5, ++ ACPI_EINJ_INSTRUCTION_RESERVED = 6 /* 6 and greater are reserved */ ++}; ++ ++struct acpi_einj_error_type_with_addr { ++ u32 error_type; ++ u32 vendor_struct_offset; ++ u32 flags; ++ u32 apic_id; ++ u64 address; ++ u64 range; ++ u32 pcie_id; ++}; ++ ++struct acpi_einj_vendor { ++ u32 length; ++ u32 pcie_id; ++ u16 vendor_id; ++ u16 device_id; ++ u8 revision_id; ++ u8 reserved[3]; + }; + + /* EINJ Trigger Error Action Table */ +@@ -275,6 +296,7 @@ + #define ACPI_EINJ_PLATFORM_CORRECTABLE (1<<9) + #define ACPI_EINJ_PLATFORM_UNCORRECTABLE (1<<10) + #define ACPI_EINJ_PLATFORM_FATAL (1<<11) ++#define ACPI_EINJ_VENDOR_DEFINED (1<<31) + + /******************************************************************************* + * +@@ -631,7 +653,9 @@ + ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8, + ACPI_MADT_TYPE_LOCAL_X2APIC = 9, + ACPI_MADT_TYPE_LOCAL_X2APIC_NMI = 10, +- ACPI_MADT_TYPE_RESERVED = 11 /* 11 and greater are reserved */ ++ ACPI_MADT_TYPE_GENERIC_INTERRUPT = 11, ++ ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR = 12, ++ ACPI_MADT_TYPE_RESERVED = 13 /* 13 and greater are reserved */ + }; + + /* +@@ -752,11 +776,36 @@ + u8 reserved[3]; + }; + ++/* 11: Generic Interrupt (ACPI 5.0) */ ++ ++struct acpi_madt_generic_interrupt { ++ struct acpi_subtable_header header; ++ u16 reserved; /* Reserved - must be zero */ ++ u32 gic_id; ++ u32 uid; ++ u32 flags; ++ u32 parking_version; ++ u32 performance_interrupt; ++ u64 parked_address; ++ u64 base_address; ++}; ++ ++/* 12: Generic Distributor (ACPI 5.0) */ ++ ++struct acpi_madt_generic_distributor { ++ struct acpi_subtable_header header; ++ u16 reserved; /* Reserved - must be zero */ ++ u32 gic_id; ++ u64 base_address; ++ u32 global_irq_base; ++ u32 reserved2; /* Reserved - must be zero */ ++}; ++ + /* + * Common flags fields for MADT subtables + */ + +-/* MADT Local APIC flags (lapic_flags) */ ++/* MADT Local APIC flags (lapic_flags) and GIC flags */ + + #define ACPI_MADT_ENABLED (1) /* 00: Processor is usable if set */ + +diff -Naur linux-3.2.16/include/acpi/actbl3.h linux-3.2.16.patch/include/acpi/actbl3.h +--- linux-3.2.16/include/acpi/actbl3.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.2.16.patch/include/acpi/actbl3.h 2012-04-23 06:05:41.441125121 +0200 +@@ -0,0 +1,552 @@ ++/****************************************************************************** ++ * ++ * Name: actbl3.h - ACPI Table Definitions ++ * ++ *****************************************************************************/ ++ ++/* ++ * Copyright (C) 2000 - 2011, Intel Corp. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce at minimum a disclaimer ++ * substantially similar to the "NO WARRANTY" disclaimer below ++ * ("Disclaimer") and any redistribution must be conditioned upon ++ * including a substantially similar Disclaimer requirement for further ++ * binary redistribution. ++ * 3. Neither the names of the above-listed copyright holders nor the names ++ * of any contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * Alternatively, this software may be distributed under the terms of the ++ * GNU General Public License ("GPL") version 2 as published by the Free ++ * Software Foundation. ++ * ++ * NO WARRANTY ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGES. ++ */ ++ ++#ifndef __ACTBL3_H__ ++#define __ACTBL3_H__ ++ ++/******************************************************************************* ++ * ++ * Additional ACPI Tables (3) ++ * ++ * These tables are not consumed directly by the ACPICA subsystem, but are ++ * included here to support device drivers and the AML disassembler. ++ * ++ * The tables in this file are fully defined within the ACPI specification. ++ * ++ ******************************************************************************/ ++ ++/* ++ * Values for description table header signatures for tables defined in this ++ * file. Useful because they make it more difficult to inadvertently type in ++ * the wrong signature. ++ */ ++#define ACPI_SIG_BGRT "BGRT" /* Boot Graphics Resource Table */ ++#define ACPI_SIG_DRTM "DRTM" /* Dynamic Root of Trust for Measurement table */ ++#define ACPI_SIG_FPDT "FPDT" /* Firmware Performance Data Table */ ++#define ACPI_SIG_GTDT "GTDT" /* Generic Timer Description Table */ ++#define ACPI_SIG_MPST "MPST" /* Memory Power State Table */ ++#define ACPI_SIG_PCCT "PCCT" /* Platform Communications Channel Table */ ++#define ACPI_SIG_PMTT "PMTT" /* Platform Memory Topology Table */ ++#define ACPI_SIG_RASF "RASF" /* RAS Feature table */ ++ ++#define ACPI_SIG_S3PT "S3PT" /* S3 Performance (sub)Table */ ++#define ACPI_SIG_PCCS "PCC" /* PCC Shared Memory Region */ ++ ++/* Reserved table signatures */ ++ ++#define ACPI_SIG_CSRT "CSRT" /* Core System Resources Table */ ++#define ACPI_SIG_DBG2 "DBG2" /* Debug Port table 2 */ ++#define ACPI_SIG_MATR "MATR" /* Memory Address Translation Table */ ++#define ACPI_SIG_MSDM "MSDM" /* Microsoft Data Management Table */ ++#define ACPI_SIG_WPBT "WPBT" /* Windows Platform Binary Table */ ++ ++/* ++ * All tables must be byte-packed to match the ACPI specification, since ++ * the tables are provided by the system BIOS. ++ */ ++#pragma pack(1) ++ ++/* ++ * Note about bitfields: The u8 type is used for bitfields in ACPI tables. ++ * This is the only type that is even remotely portable. Anything else is not ++ * portable, so do not use any other bitfield types. ++ */ ++ ++/******************************************************************************* ++ * ++ * BGRT - Boot Graphics Resource Table (ACPI 5.0) ++ * Version 1 ++ * ++ ******************************************************************************/ ++ ++struct acpi_table_bgrt { ++ struct acpi_table_header header; /* Common ACPI table header */ ++ u16 version; ++ u8 status; ++ u8 image_type; ++ u64 image_address; ++ u32 image_offset_x; ++ u32 image_offset_y; ++}; ++ ++/******************************************************************************* ++ * ++ * DRTM - Dynamic Root of Trust for Measurement table ++ * ++ ******************************************************************************/ ++ ++struct acpi_table_drtm { ++ struct acpi_table_header header; /* Common ACPI table header */ ++ u64 entry_base_address; ++ u64 entry_length; ++ u32 entry_address32; ++ u64 entry_address64; ++ u64 exit_address; ++ u64 log_area_address; ++ u32 log_area_length; ++ u64 arch_dependent_address; ++ u32 flags; ++}; ++ ++/* 1) Validated Tables List */ ++ ++struct acpi_drtm_vtl_list { ++ u32 validated_table_list_count; ++}; ++ ++/* 2) Resources List */ ++ ++struct acpi_drtm_resource_list { ++ u32 resource_list_count; ++}; ++ ++/* 3) Platform-specific Identifiers List */ ++ ++struct acpi_drtm_id_list { ++ u32 id_list_count; ++}; ++ ++/******************************************************************************* ++ * ++ * FPDT - Firmware Performance Data Table (ACPI 5.0) ++ * Version 1 ++ * ++ ******************************************************************************/ ++ ++struct acpi_table_fpdt { ++ struct acpi_table_header header; /* Common ACPI table header */ ++}; ++ ++/* FPDT subtable header */ ++ ++struct acpi_fpdt_header { ++ u16 type; ++ u8 length; ++ u8 revision; ++}; ++ ++/* Values for Type field above */ ++ ++enum acpi_fpdt_type { ++ ACPI_FPDT_TYPE_BOOT = 0, ++ ACPI_FPDT_TYPE_S3PERF = 1, ++}; ++ ++/* ++ * FPDT subtables ++ */ ++ ++/* 0: Firmware Basic Boot Performance Record */ ++ ++struct acpi_fpdt_boot { ++ struct acpi_fpdt_header header; ++ u8 reserved[4]; ++ u64 reset_end; ++ u64 load_start; ++ u64 startup_start; ++ u64 exit_services_entry; ++ u64 exit_services_exit; ++}; ++ ++/* 1: S3 Performance Table Pointer Record */ ++ ++struct acpi_fpdt_s3pt_ptr { ++ struct acpi_fpdt_header header; ++ u8 reserved[4]; ++ u64 address; ++}; ++ ++/* ++ * S3PT - S3 Performance Table. This table is pointed to by the ++ * FPDT S3 Pointer Record above. ++ */ ++struct acpi_table_s3pt { ++ u8 signature[4]; /* "S3PT" */ ++ u32 length; ++}; ++ ++/* ++ * S3PT Subtables ++ */ ++struct acpi_s3pt_header { ++ u16 type; ++ u8 length; ++ u8 revision; ++}; ++ ++/* Values for Type field above */ ++ ++enum acpi_s3pt_type { ++ ACPI_S3PT_TYPE_RESUME = 0, ++ ACPI_S3PT_TYPE_SUSPEND = 1, ++}; ++ ++struct acpi_s3pt_resume { ++ struct acpi_s3pt_header header; ++ u32 resume_count; ++ u64 full_resume; ++ u64 average_resume; ++}; ++ ++struct acpi_s3pt_suspend { ++ struct acpi_s3pt_header header; ++ u64 suspend_start; ++ u64 suspend_end; ++}; ++ ++/******************************************************************************* ++ * ++ * GTDT - Generic Timer Description Table (ACPI 5.0) ++ * Version 1 ++ * ++ ******************************************************************************/ ++ ++struct acpi_table_gtdt { ++ struct acpi_table_header header; /* Common ACPI table header */ ++ u64 address; ++ u32 flags; ++ u32 secure_pl1_interrupt; ++ u32 secure_pl1_flags; ++ u32 non_secure_pl1_interrupt; ++ u32 non_secure_pl1_flags; ++ u32 virtual_timer_interrupt; ++ u32 virtual_timer_flags; ++ u32 non_secure_pl2_interrupt; ++ u32 non_secure_pl2_flags; ++}; ++ ++/* Values for Flags field above */ ++ ++#define ACPI_GTDT_MAPPED_BLOCK_PRESENT 1 ++ ++/* Values for all "TimerFlags" fields above */ ++ ++#define ACPI_GTDT_INTERRUPT_MODE 1 ++#define ACPI_GTDT_INTERRUPT_POLARITY 2 ++ ++/******************************************************************************* ++ * ++ * MPST - Memory Power State Table (ACPI 5.0) ++ * Version 1 ++ * ++ ******************************************************************************/ ++ ++#define ACPI_MPST_CHANNEL_INFO \ ++ u16 reserved1; \ ++ u8 channel_id; \ ++ u8 reserved2; \ ++ u16 power_node_count; ++ ++/* Main table */ ++ ++struct acpi_table_mpst { ++ struct acpi_table_header header; /* Common ACPI table header */ ++ ACPI_MPST_CHANNEL_INFO /* Platform Communication Channel */ ++}; ++ ++/* Memory Platform Communication Channel Info */ ++ ++struct acpi_mpst_channel { ++ ACPI_MPST_CHANNEL_INFO /* Platform Communication Channel */ ++}; ++ ++/* Memory Power Node Structure */ ++ ++struct acpi_mpst_power_node { ++ u8 flags; ++ u8 reserved1; ++ u16 node_id; ++ u32 length; ++ u64 range_address; ++ u64 range_length; ++ u8 num_power_states; ++ u8 num_physical_components; ++ u16 reserved2; ++}; ++ ++/* Values for Flags field above */ ++ ++#define ACPI_MPST_ENABLED 1 ++#define ACPI_MPST_POWER_MANAGED 2 ++#define ACPI_MPST_HOT_PLUG_CAPABLE 4 ++ ++/* Memory Power State Structure (follows POWER_NODE above) */ ++ ++struct acpi_mpst_power_state { ++ u8 power_state; ++ u8 info_index; ++}; ++ ++/* Physical Component ID Structure (follows POWER_STATE above) */ ++ ++struct acpi_mpst_component { ++ u16 component_id; ++}; ++ ++/* Memory Power State Characteristics Structure (follows all POWER_NODEs) */ ++ ++struct acpi_mpst_data_hdr { ++ u16 characteristics_count; ++}; ++ ++struct acpi_mpst_power_data { ++ u8 revision; ++ u8 flags; ++ u16 reserved1; ++ u32 average_power; ++ u32 power_saving; ++ u64 exit_latency; ++ u64 reserved2; ++}; ++ ++/* Values for Flags field above */ ++ ++#define ACPI_MPST_PRESERVE 1 ++#define ACPI_MPST_AUTOENTRY 2 ++#define ACPI_MPST_AUTOEXIT 4 ++ ++/* Shared Memory Region (not part of an ACPI table) */ ++ ++struct acpi_mpst_shared { ++ u32 signature; ++ u16 pcc_command; ++ u16 pcc_status; ++ u16 command_register; ++ u16 status_register; ++ u16 power_state_id; ++ u16 power_node_id; ++ u64 energy_consumed; ++ u64 average_power; ++}; ++ ++/******************************************************************************* ++ * ++ * PCCT - Platform Communications Channel Table (ACPI 5.0) ++ * Version 1 ++ * ++ ******************************************************************************/ ++ ++struct acpi_table_pcct { ++ struct acpi_table_header header; /* Common ACPI table header */ ++ u32 flags; ++ u32 latency; ++ u32 reserved; ++}; ++ ++/* Values for Flags field above */ ++ ++#define ACPI_PCCT_DOORBELL 1 ++ ++/* ++ * PCCT subtables ++ */ ++ ++/* 0: Generic Communications Subspace */ ++ ++struct acpi_pcct_subspace { ++ struct acpi_subtable_header header; ++ u8 reserved[6]; ++ u64 base_address; ++ u64 length; ++ struct acpi_generic_address doorbell_register; ++ u64 preserve_mask; ++ u64 write_mask; ++}; ++ ++/* ++ * PCC memory structures (not part of the ACPI table) ++ */ ++ ++/* Shared Memory Region */ ++ ++struct acpi_pcct_shared_memory { ++ u32 signature; ++ u16 command; ++ u16 status; ++}; ++ ++/******************************************************************************* ++ * ++ * PMTT - Platform Memory Topology Table (ACPI 5.0) ++ * Version 1 ++ * ++ ******************************************************************************/ ++ ++struct acpi_table_pmtt { ++ struct acpi_table_header header; /* Common ACPI table header */ ++ u32 reserved; ++}; ++ ++/* Common header for PMTT subtables that follow main table */ ++ ++struct acpi_pmtt_header { ++ u8 type; ++ u8 reserved1; ++ u16 length; ++ u16 flags; ++ u16 reserved2; ++}; ++ ++/* Values for Type field above */ ++ ++#define ACPI_PMTT_TYPE_SOCKET 0 ++#define ACPI_PMTT_TYPE_CONTROLLER 1 ++#define ACPI_PMTT_TYPE_DIMM 2 ++#define ACPI_PMTT_TYPE_RESERVED 3 /* 0x03-0xFF are reserved */ ++ ++/* Values for Flags field above */ ++ ++#define ACPI_PMTT_TOP_LEVEL 0x0001 ++#define ACPI_PMTT_PHYSICAL 0x0002 ++#define ACPI_PMTT_MEMORY_TYPE 0x000C ++ ++/* ++ * PMTT subtables, correspond to Type in struct acpi_pmtt_header ++ */ ++ ++/* 0: Socket Structure */ ++ ++struct acpi_pmtt_socket { ++ struct acpi_pmtt_header header; ++ u16 socket_id; ++ u16 reserved; ++}; ++ ++/* 1: Memory Controller subtable */ ++ ++struct acpi_pmtt_controller { ++ struct acpi_pmtt_header header; ++ u32 read_latency; ++ u32 write_latency; ++ u32 read_bandwidth; ++ u32 write_bandwidth; ++ u16 access_width; ++ u16 alignment; ++ u16 reserved; ++ u16 domain_count; ++}; ++ ++/* 1a: Proximity Domain substructure */ ++ ++struct acpi_pmtt_domain { ++ u32 proximity_domain; ++}; ++ ++/* 2: Physical Component Identifier (DIMM) */ ++ ++struct acpi_pmtt_physical_component { ++ struct acpi_pmtt_header header; ++ u16 component_id; ++ u16 reserved; ++ u32 memory_size; ++ u32 bios_handle; ++}; ++ ++/******************************************************************************* ++ * ++ * RASF - RAS Feature Table (ACPI 5.0) ++ * Version 1 ++ * ++ ******************************************************************************/ ++ ++struct acpi_table_rasf { ++ struct acpi_table_header header; /* Common ACPI table header */ ++ u8 channel_id[12]; ++}; ++ ++/* RASF Platform Communication Channel Shared Memory Region */ ++ ++struct acpi_rasf_shared_memory { ++ u32 signature; ++ u16 command; ++ u16 status; ++ u64 requested_address; ++ u64 requested_length; ++ u64 actual_address; ++ u64 actual_length; ++ u16 flags; ++ u8 speed; ++}; ++ ++/* Masks for Flags and Speed fields above */ ++ ++#define ACPI_RASF_SCRUBBER_RUNNING 1 ++#define ACPI_RASF_SPEED (7<<1) ++ ++/* Channel Commands */ ++ ++enum acpi_rasf_commands { ++ ACPI_RASF_GET_RAS_CAPABILITIES = 1, ++ ACPI_RASF_GET_PATROL_PARAMETERS = 2, ++ ACPI_RASF_START_PATROL_SCRUBBER = 3, ++ ACPI_RASF_STOP_PATROL_SCRUBBER = 4 ++}; ++ ++/* Channel Command flags */ ++ ++#define ACPI_RASF_GENERATE_SCI (1<<15) ++ ++/* Status values */ ++ ++enum acpi_rasf_status { ++ ACPI_RASF_SUCCESS = 0, ++ ACPI_RASF_NOT_VALID = 1, ++ ACPI_RASF_NOT_SUPPORTED = 2, ++ ACPI_RASF_BUSY = 3, ++ ACPI_RASF_FAILED = 4, ++ ACPI_RASF_ABORTED = 5, ++ ACPI_RASF_INVALID_DATA = 6 ++}; ++ ++/* Status flags */ ++ ++#define ACPI_RASF_COMMAND_COMPLETE (1) ++#define ACPI_RASF_SCI_DOORBELL (1<<1) ++#define ACPI_RASF_ERROR (1<<2) ++#define ACPI_RASF_STATUS (0x1F<<3) ++ ++/* Reset to default packing */ ++ ++#pragma pack() ++ ++#endif /* __ACTBL3_H__ */ +diff -Naur linux-3.2.16/include/acpi/actbl.h linux-3.2.16.patch/include/acpi/actbl.h +--- linux-3.2.16/include/acpi/actbl.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/include/acpi/actbl.h 2012-04-23 06:05:41.441125121 +0200 +@@ -255,6 +255,8 @@ + struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */ + struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */ + struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */ ++ struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register */ ++ struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register */ + }; + + /* Masks for FADT Boot Architecture Flags (boot_flags) */ +@@ -264,6 +266,7 @@ + #define ACPI_FADT_NO_VGA (1<<2) /* 02: [V4] It is not safe to probe for VGA hardware */ + #define ACPI_FADT_NO_MSI (1<<3) /* 03: [V4] Message Signaled Interrupts (MSI) must not be enabled */ + #define ACPI_FADT_NO_ASPM (1<<4) /* 04: [V4] PCIe ASPM control must not be enabled */ ++#define ACPI_FADT_NO_CMOS_RTC (1<<5) /* 05: [V5] No CMOS real-time clock present */ + + #define FADT2_REVISION_ID 3 + +@@ -289,6 +292,8 @@ + #define ACPI_FADT_REMOTE_POWER_ON (1<<17) /* 17: [V4] System is compatible with remote power on (ACPI 3.0) */ + #define ACPI_FADT_APIC_CLUSTER (1<<18) /* 18: [V4] All local APICs must use cluster model (ACPI 3.0) */ + #define ACPI_FADT_APIC_PHYSICAL (1<<19) /* 19: [V4] All local x_aPICs must use physical dest mode (ACPI 3.0) */ ++#define ACPI_FADT_HW_REDUCED (1<<20) /* 20: [V5] ACPI hardware is not implemented (ACPI 5.0) */ ++#define ACPI_FADT_LOW_POWER_S0 (1<<21) /* 21: [V5] S0 power savings are equal or better than S3 (ACPI 5.0) */ + + /* Values for preferred_profile (Preferred Power Management Profiles) */ + +@@ -299,14 +304,16 @@ + PM_WORKSTATION = 3, + PM_ENTERPRISE_SERVER = 4, + PM_SOHO_SERVER = 5, +- PM_APPLIANCE_PC = 6 ++ PM_APPLIANCE_PC = 6, ++ PM_PERFORMANCE_SERVER = 7, ++ PM_TABLET = 8 + }; + + /* Reset to default packing */ + + #pragma pack() + +-#define ACPI_FADT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_fadt, f) ++#define ACPI_FADT_OFFSET(f) (u16) ACPI_OFFSET (struct acpi_table_fadt, f) + + /* + * Internal table-related structures +@@ -342,6 +349,7 @@ + + #include + #include ++#include + + /* + * Sizes of the various flavors of FADT. We need to look closely +@@ -351,12 +359,15 @@ + * FADT is the bottom line as to what the version really is. + * + * For reference, the values below are as follows: +- * FADT V1 size: 0x74 +- * FADT V2 size: 0x84 +- * FADT V3+ size: 0xF4 ++ * FADT V1 size: 0x074 ++ * FADT V2 size: 0x084 ++ * FADT V3 size: 0x0F4 ++ * FADT V4 size: 0x0F4 ++ * FADT V5 size: 0x10C + */ + #define ACPI_FADT_V1_SIZE (u32) (ACPI_FADT_OFFSET (flags) + 4) + #define ACPI_FADT_V2_SIZE (u32) (ACPI_FADT_OFFSET (reserved4[0]) + 3) +-#define ACPI_FADT_V3_SIZE (u32) (sizeof (struct acpi_table_fadt)) ++#define ACPI_FADT_V3_SIZE (u32) (ACPI_FADT_OFFSET (sleep_control)) ++#define ACPI_FADT_V5_SIZE (u32) (sizeof (struct acpi_table_fadt)) + + #endif /* __ACTBL_H__ */ +diff -Naur linux-3.2.16/include/acpi/actypes.h linux-3.2.16.patch/include/acpi/actypes.h +--- linux-3.2.16/include/acpi/actypes.h 2012-04-23 00:31:32.000000000 +0200 ++++ linux-3.2.16.patch/include/acpi/actypes.h 2012-04-23 06:05:41.442125141 +0200 +@@ -712,8 +712,10 @@ + #define ACPI_ADR_SPACE_CMOS (acpi_adr_space_type) 5 + #define ACPI_ADR_SPACE_PCI_BAR_TARGET (acpi_adr_space_type) 6 + #define ACPI_ADR_SPACE_IPMI (acpi_adr_space_type) 7 ++#define ACPI_ADR_SPACE_GPIO (acpi_adr_space_type) 8 ++#define ACPI_ADR_SPACE_GSBUS (acpi_adr_space_type) 9 + +-#define ACPI_NUM_PREDEFINED_REGIONS 8 ++#define ACPI_NUM_PREDEFINED_REGIONS 10 + + /* + * Special Address Spaces +@@ -957,6 +959,14 @@ + + #define ACPI_DEFAULT_HANDLER NULL + ++/* Special Context data for generic_serial_bus/general_purpose_io (ACPI 5.0) */ ++ ++struct acpi_connection_info { ++ u8 *connection; ++ u16 length; ++ u8 access_length; ++}; ++ + typedef + acpi_status(*acpi_adr_space_setup) (acpi_handle region_handle, + u32 function, diff --git a/packages/linux/patches/linux-3.2.28-601-RPi_support-e33263e.patch b/packages/linux/patches/linux-3.2.30-601-RPi_support-8524c78.patch similarity index 99% rename from packages/linux/patches/linux-3.2.28-601-RPi_support-e33263e.patch rename to packages/linux/patches/linux-3.2.30-601-RPi_support-8524c78.patch index 818c93deab..f8d7654cc3 100644 --- a/packages/linux/patches/linux-3.2.28-601-RPi_support-e33263e.patch +++ b/packages/linux/patches/linux-3.2.30-601-RPi_support-8524c78.patch @@ -619,10 +619,10 @@ index 0000000..3b8bd74 +CONFIG_LIBCRC32C=y diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig new file mode 100644 -index 0000000..35c5042 +index 0000000..b4a3da1 --- /dev/null +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -0,0 +1,913 @@ +@@ -0,0 +1,945 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_EXPERIMENTAL=y +# CONFIG_LOCALVERSION_AUTO is not set @@ -673,9 +673,10 @@ index 0000000..35c5042 +CONFIG_KEXEC=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT=m -+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_IDLE=y +CONFIG_VFP=y @@ -854,6 +855,7 @@ index 0000000..35c5042 +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_NFLOG=m ++CONFIG_L2TP=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y @@ -1049,6 +1051,7 @@ index 0000000..35c5042 +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT53XX=y ++CONFIG_RT2800USB_UNKNOWN=y +CONFIG_WL1251=m +CONFIG_WL12XX_MENU=m +CONFIG_ZD1211RW=m @@ -1108,6 +1111,8 @@ index 0000000..35c5042 +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_BQ27000=m +# CONFIG_HWMON is not set ++CONFIG_THERMAL=y ++CONFIG_THERMAL_BCM2835=y +CONFIG_WATCHDOG=y +CONFIG_BCM2708_WDT=m +CONFIG_MEDIA_SUPPORT=m @@ -1394,6 +1399,33 @@ index 0000000..35c5042 +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DS1307=m ++CONFIG_RTC_DRV_DS1374=m ++CONFIG_RTC_DRV_DS1672=m ++CONFIG_RTC_DRV_DS3232=m ++CONFIG_RTC_DRV_MAX6900=m ++CONFIG_RTC_DRV_RS5C372=m ++CONFIG_RTC_DRV_ISL1208=m ++CONFIG_RTC_DRV_ISL12022=m ++CONFIG_RTC_DRV_X1205=m ++CONFIG_RTC_DRV_PCF8563=m ++CONFIG_RTC_DRV_PCF8583=m ++CONFIG_RTC_DRV_M41T80=m ++CONFIG_RTC_DRV_BQ32K=m ++CONFIG_RTC_DRV_S35390A=m ++CONFIG_RTC_DRV_FM3130=m ++CONFIG_RTC_DRV_RX8581=m ++CONFIG_RTC_DRV_RX8025=m ++CONFIG_RTC_DRV_EM3027=m ++CONFIG_RTC_DRV_RV3029C2=m ++CONFIG_RTC_DRV_M41T93=m ++CONFIG_RTC_DRV_M41T94=m ++CONFIG_RTC_DRV_DS1305=m ++CONFIG_RTC_DRV_DS1390=m ++CONFIG_RTC_DRV_MAX6902=m ++CONFIG_RTC_DRV_R9701=m ++CONFIG_RTC_DRV_RS5C348=m ++CONFIG_RTC_DRV_DS3234=m ++CONFIG_RTC_DRV_PCF2123=m +CONFIG_UIO=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m @@ -2642,10 +2674,10 @@ index 0000000..0aa916e +#endif diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c new file mode 100644 -index 0000000..b3dbbd1 +index 0000000..72dcf31 --- /dev/null +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -0,0 +1,825 @@ +@@ -0,0 +1,867 @@ +/* + * linux/arch/arm/mach-bcm2708/bcm2708.c + * @@ -3164,6 +3196,48 @@ index 0000000..b3dbbd1 + .resource = 0, + .num_resources = 0, + }, ++ [1] = { ++ .name = "bcm2835_AUD1", ++ .id = 1, /* second audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [2] = { ++ .name = "bcm2835_AUD2", ++ .id = 2, /* third audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [3] = { ++ .name = "bcm2835_AUD3", ++ .id = 3, /* forth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [4] = { ++ .name = "bcm2835_AUD4", ++ .id = 4, /* fifth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [5] = { ++ .name = "bcm2835_AUD5", ++ .id = 5, /* sixth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [6] = { ++ .name = "bcm2835_AUD6", ++ .id = 6, /* seventh audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [7] = { ++ .name = "bcm2835_AUD7", ++ .id = 7, /* eighth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, +}; + +static struct resource bcm2708_spi_resources[] = { @@ -7271,7 +7345,7 @@ index a48bc02..51ebbb3 100644 # PowerPC platform drivers diff --git a/drivers/cpufreq/bcm2835-cpufreq.c b/drivers/cpufreq/bcm2835-cpufreq.c new file mode 100755 -index 0000000..aa6fc66 +index 0000000..6ff1edb --- /dev/null +++ b/drivers/cpufreq/bcm2835-cpufreq.c @@ -0,0 +1,239 @@ @@ -7473,7 +7547,7 @@ index 0000000..aa6fc66 + policy->cur = bcm2835_cpufreq_get_clock(VCMSG_GET_CLOCK_RATE); + return -EINVAL; + } -+ print_info("Freq %d->%d (min=%d max=%d target=%d request=%d)", cur, policy->cur, policy->min, policy->max, target_freq, target); ++ print_debug("Freq %d->%d (min=%d max=%d target=%d request=%d)", cur, policy->cur, policy->min, policy->max, target_freq, target); + return 0; +} + @@ -7515,14 +7589,15 @@ index 0000000..aa6fc66 +module_exit(bcm2835_cpufreq_module_exit); + diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig -index 83e3e9d..761b528 100644 +index 83e3e9d..a22de2a 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig -@@ -1361,6 +1361,15 @@ config SENSORS_MC13783_ADC +@@ -1361,6 +1361,16 @@ config SENSORS_MC13783_ADC help Support for the A/D converter on MC13783 PMIC. +config SENSORS_BCM2835 ++ depends on THERMAL_BCM2835=n + tristate "Broadcom BCM2835 HWMON Driver" + help + If you say yes here you get support for the hardware @@ -7548,11 +7623,23 @@ index 8251ce8..8f2743b 100644 diff --git a/drivers/hwmon/bcm2835-hwmon.c b/drivers/hwmon/bcm2835-hwmon.c new file mode 100644 -index 0000000..4976387 +index 0000000..5bbed45 --- /dev/null +++ b/drivers/hwmon/bcm2835-hwmon.c -@@ -0,0 +1,211 @@ -+//bcm2835-hwmon.c +@@ -0,0 +1,219 @@ ++/***************************************************************************** ++* Copyright 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ + +#include +#include @@ -7579,12 +7666,12 @@ index 0000000..4976387 + +#define VC_TAG_GET_TEMP 0x00030006 +#define VC_TAG_GET_MAX_TEMP 0x0003000A ++ ++/* --- STRUCTS --- */ +struct bcm2835_hwmon_data { + struct device *hwmon_dev; +}; + -+/* --- STRUCTS --- */ -+ +/* tag part of the message */ +struct vc_msg_tag { + uint32_t tag_id; /* the tag ID for the temperature */ @@ -7618,16 +7705,12 @@ index 0000000..4976387 + +static SENSOR_DEVICE_ATTR(name, S_IRUGO,bcm2835_get_name,NULL,0); +static SENSOR_DEVICE_ATTR(temp1_input,S_IRUGO,bcm2835_get_temp,NULL,TEMP); -+static SENSOR_DEVICE_ATTR(temp,S_IRUGO,bcm2835_get_temp,NULL,TEMP); +static SENSOR_DEVICE_ATTR(temp1_max,S_IRUGO,bcm2835_get_temp,NULL,MAX_TEMP); -+static SENSOR_DEVICE_ATTR(trip_point_0_temp,S_IRUGO,bcm2835_get_temp,NULL,MAX_TEMP); + +static struct attribute* bcm2835_attributes[] = { + &sensor_dev_attr_name.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, -+ &sensor_dev_attr_temp.dev_attr.attr, -+ &sensor_dev_attr_trip_point_0_temp.dev_attr.attr, + NULL, +}; + @@ -30097,7 +30180,7 @@ index 0000000..2703103 + + diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c -index 6ce32a7..0562295 100644 +index 6ce32a7..b4ffbe3 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -27,6 +27,7 @@ @@ -30134,9 +30217,9 @@ index 6ce32a7..0562295 100644 + if(enable_llm) + { + local_irq_disable(); -+ enable_irq(host->irq); + if(host->second_irq) + enable_irq(host->second_irq); ++ enable_irq(host->irq); + } +#endif + spin_unlock(&host->lock); @@ -30168,9 +30251,9 @@ index 6ce32a7..0562295 100644 + if(enable_llm) + { + local_irq_disable(); -+ enable_irq(host->irq); + if(host->second_irq) + enable_irq(host->second_irq); ++ enable_irq(host->irq); + } +#endif + spin_unlock_irqrestore(&host->lock,flags); @@ -30200,17 +30283,7 @@ index 6ce32a7..0562295 100644 static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set) { -@@ -206,7 +292,9 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) - return; - } - timeout--; -+ sdhci_spin_enable_schedule(host); - mdelay(1); -+ sdhci_spin_disable_schedule(host); - } - - if (host->ops->platform_reset_exit) -@@ -269,7 +357,7 @@ static void sdhci_led_control(struct led_classdev *led, +@@ -269,7 +355,7 @@ static void sdhci_led_control(struct led_classdev *led, struct sdhci_host *host = container_of(led, struct sdhci_host, led); unsigned long flags; @@ -30219,7 +30292,7 @@ index 6ce32a7..0562295 100644 if (host->runtime_suspended) goto out; -@@ -279,7 +367,7 @@ static void sdhci_led_control(struct led_classdev *led, +@@ -279,7 +365,7 @@ static void sdhci_led_control(struct led_classdev *led, else sdhci_activate_led(host); out: @@ -30228,7 +30301,7 @@ index 6ce32a7..0562295 100644 } #endif -@@ -296,7 +384,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host) +@@ -296,7 +382,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host) u32 uninitialized_var(scratch); u8 *buf; @@ -30237,7 +30310,7 @@ index 6ce32a7..0562295 100644 blksize = host->data->blksz; chunk = 0; -@@ -341,7 +429,7 @@ static void sdhci_write_block_pio(struct sdhci_host *host) +@@ -341,7 +427,7 @@ static void sdhci_write_block_pio(struct sdhci_host *host) u32 scratch; u8 *buf; @@ -30246,7 +30319,7 @@ index 6ce32a7..0562295 100644 blksize = host->data->blksz; chunk = 0; -@@ -380,19 +468,28 @@ static void sdhci_write_block_pio(struct sdhci_host *host) +@@ -380,19 +466,28 @@ static void sdhci_write_block_pio(struct sdhci_host *host) local_irq_restore(flags); } @@ -30278,7 +30351,7 @@ index 6ce32a7..0562295 100644 /* * Some controllers (JMicron JMB38x) mess up the buffer bits -@@ -403,7 +500,7 @@ static void sdhci_transfer_pio(struct sdhci_host *host) +@@ -403,7 +498,7 @@ static void sdhci_transfer_pio(struct sdhci_host *host) (host->data->blocks == 1)) mask = ~0; @@ -30287,7 +30360,7 @@ index 6ce32a7..0562295 100644 if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY) udelay(100); -@@ -415,9 +512,11 @@ static void sdhci_transfer_pio(struct sdhci_host *host) +@@ -415,9 +510,11 @@ static void sdhci_transfer_pio(struct sdhci_host *host) host->blocks--; if (host->blocks == 0) break; @@ -30300,7 +30373,7 @@ index 6ce32a7..0562295 100644 } static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags) -@@ -690,7 +789,9 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host) +@@ -690,7 +787,9 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host) u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL; u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR; @@ -30311,7 +30384,7 @@ index 6ce32a7..0562295 100644 sdhci_clear_set_irqs(host, pio_irqs, dma_irqs); else sdhci_clear_set_irqs(host, dma_irqs, pio_irqs); -@@ -722,44 +823,25 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) +@@ -722,44 +821,25 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) host->data_early = 0; host->data->bytes_xfered = 0; @@ -30364,7 +30437,7 @@ index 6ce32a7..0562295 100644 int broken, i; struct scatterlist *sg; -@@ -818,7 +900,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) +@@ -818,7 +898,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) */ WARN_ON(1); host->flags &= ~SDHCI_REQ_USE_DMA; @@ -30374,7 +30447,7 @@ index 6ce32a7..0562295 100644 WARN_ON(sg_cnt != 1); sdhci_writel(host, sg_dma_address(data->sg), SDHCI_DMA_ADDRESS); -@@ -834,11 +917,13 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) +@@ -834,11 +915,13 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) if (host->version >= SDHCI_SPEC_200) { ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); ctrl &= ~SDHCI_CTRL_DMA_MASK; @@ -30393,7 +30466,7 @@ index 6ce32a7..0562295 100644 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); } -@@ -890,7 +975,8 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, +@@ -890,7 +973,8 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, if (data->flags & MMC_DATA_READ) mode |= SDHCI_TRNS_READ; @@ -30403,7 +30476,7 @@ index 6ce32a7..0562295 100644 mode |= SDHCI_TRNS_DMA; sdhci_writew(host, mode, SDHCI_TRANSFER_MODE); -@@ -906,13 +992,16 @@ static void sdhci_finish_data(struct sdhci_host *host) +@@ -906,13 +990,16 @@ static void sdhci_finish_data(struct sdhci_host *host) host->data = NULL; if (host->flags & SDHCI_REQ_USE_DMA) { @@ -30424,7 +30497,7 @@ index 6ce32a7..0562295 100644 } /* -@@ -965,6 +1054,12 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) +@@ -965,6 +1052,12 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY)) mask |= SDHCI_DATA_INHIBIT; @@ -30437,7 +30510,7 @@ index 6ce32a7..0562295 100644 /* We shouldn't wait for data inihibit for stop commands, even though they might use busy signaling */ if (host->mrq->data && (cmd == host->mrq->data->stop)) -@@ -980,12 +1075,20 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) +@@ -980,12 +1073,20 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) return; } timeout--; @@ -30458,7 +30531,7 @@ index 6ce32a7..0562295 100644 sdhci_prepare_data(host, cmd); -@@ -1150,7 +1253,9 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) +@@ -1150,7 +1251,9 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) return; } timeout--; @@ -30468,7 +30541,7 @@ index 6ce32a7..0562295 100644 } clk |= SDHCI_CLOCK_CARD_EN; -@@ -1218,6 +1323,35 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) +@@ -1218,6 +1321,35 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) mdelay(10); } @@ -30504,7 +30577,7 @@ index 6ce32a7..0562295 100644 /*****************************************************************************\ * * * MMC callbacks * -@@ -1234,7 +1368,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) +@@ -1234,7 +1366,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) sdhci_runtime_pm_get(host); @@ -30513,7 +30586,7 @@ index 6ce32a7..0562295 100644 WARN_ON(host->mrq != NULL); -@@ -1276,9 +1410,9 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) +@@ -1276,9 +1408,9 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) */ if ((host->flags & SDHCI_NEEDS_RETUNING) && !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { @@ -30525,7 +30598,7 @@ index 6ce32a7..0562295 100644 /* Restore original mmc_request structure */ host->mrq = mrq; -@@ -1291,15 +1425,16 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) +@@ -1291,15 +1423,16 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) } mmiowb(); @@ -30544,7 +30617,7 @@ index 6ce32a7..0562295 100644 if (host->flags & SDHCI_DEVICE_DEAD) goto out; -@@ -1356,7 +1491,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) +@@ -1356,7 +1489,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) else ctrl &= ~SDHCI_CTRL_HISPD; @@ -30553,7 +30626,7 @@ index 6ce32a7..0562295 100644 u16 clk, ctrl_2; unsigned int clock; -@@ -1364,7 +1499,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) +@@ -1364,7 +1497,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) if ((ios->timing == MMC_TIMING_UHS_SDR50) || (ios->timing == MMC_TIMING_UHS_SDR104) || (ios->timing == MMC_TIMING_UHS_DDR50) || @@ -30563,7 +30636,7 @@ index 6ce32a7..0562295 100644 ctrl |= SDHCI_CTRL_HISPD; ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); -@@ -1444,7 +1580,13 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) +@@ -1444,7 +1578,13 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) out: mmiowb(); @@ -30578,7 +30651,7 @@ index 6ce32a7..0562295 100644 } static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -@@ -1461,7 +1603,7 @@ static int sdhci_check_ro(struct sdhci_host *host) +@@ -1461,7 +1601,7 @@ static int sdhci_check_ro(struct sdhci_host *host) unsigned long flags; int is_readonly; @@ -30587,7 +30660,7 @@ index 6ce32a7..0562295 100644 if (host->flags & SDHCI_DEVICE_DEAD) is_readonly = 0; -@@ -1471,7 +1613,7 @@ static int sdhci_check_ro(struct sdhci_host *host) +@@ -1471,7 +1611,7 @@ static int sdhci_check_ro(struct sdhci_host *host) is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_WRITE_PROTECT); @@ -30596,7 +30669,7 @@ index 6ce32a7..0562295 100644 /* This quirk needs to be replaced by a callback-function later */ return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ? -@@ -1544,9 +1686,9 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) +@@ -1544,9 +1684,9 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) struct sdhci_host *host = mmc_priv(mmc); unsigned long flags; @@ -30608,7 +30681,7 @@ index 6ce32a7..0562295 100644 } static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host, -@@ -1849,7 +1991,7 @@ static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable) +@@ -1849,7 +1989,7 @@ static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable) if (host->version < SDHCI_SPEC_300) return; @@ -30617,7 +30690,7 @@ index 6ce32a7..0562295 100644 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); -@@ -1867,7 +2009,7 @@ static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable) +@@ -1867,7 +2007,7 @@ static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable) host->flags &= ~SDHCI_PV_ENABLED; } @@ -30626,7 +30699,7 @@ index 6ce32a7..0562295 100644 } static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable) -@@ -1888,6 +2030,8 @@ static const struct mmc_host_ops sdhci_ops = { +@@ -1888,6 +2028,8 @@ static const struct mmc_host_ops sdhci_ops = { .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, .execute_tuning = sdhci_execute_tuning, .enable_preset_value = sdhci_enable_preset_value, @@ -30635,7 +30708,7 @@ index 6ce32a7..0562295 100644 }; /*****************************************************************************\ -@@ -1903,7 +2047,7 @@ static void sdhci_tasklet_card(unsigned long param) +@@ -1903,7 +2045,7 @@ static void sdhci_tasklet_card(unsigned long param) host = (struct sdhci_host*)param; @@ -30644,7 +30717,7 @@ index 6ce32a7..0562295 100644 /* Check host->mrq first in case we are runtime suspended */ if (host->mrq && -@@ -1920,7 +2064,7 @@ static void sdhci_tasklet_card(unsigned long param) +@@ -1920,7 +2062,7 @@ static void sdhci_tasklet_card(unsigned long param) tasklet_schedule(&host->finish_tasklet); } @@ -30653,7 +30726,7 @@ index 6ce32a7..0562295 100644 mmc_detect_change(host->mmc, msecs_to_jiffies(200)); } -@@ -1933,14 +2077,14 @@ static void sdhci_tasklet_finish(unsigned long param) +@@ -1933,14 +2075,14 @@ static void sdhci_tasklet_finish(unsigned long param) host = (struct sdhci_host*)param; @@ -30670,7 +30743,7 @@ index 6ce32a7..0562295 100644 return; } -@@ -1983,7 +2127,7 @@ static void sdhci_tasklet_finish(unsigned long param) +@@ -1983,7 +2125,7 @@ static void sdhci_tasklet_finish(unsigned long param) #endif mmiowb(); @@ -30679,7 +30752,7 @@ index 6ce32a7..0562295 100644 mmc_request_done(host->mmc, mrq); sdhci_runtime_pm_put(host); -@@ -1996,11 +2140,11 @@ static void sdhci_timeout_timer(unsigned long data) +@@ -1996,11 +2138,11 @@ static void sdhci_timeout_timer(unsigned long data) host = (struct sdhci_host*)data; @@ -30693,7 +30766,7 @@ index 6ce32a7..0562295 100644 sdhci_dumpregs(host); if (host->data) { -@@ -2017,7 +2161,7 @@ static void sdhci_timeout_timer(unsigned long data) +@@ -2017,7 +2159,7 @@ static void sdhci_timeout_timer(unsigned long data) } mmiowb(); @@ -30702,7 +30775,7 @@ index 6ce32a7..0562295 100644 } static void sdhci_tuning_timer(unsigned long data) -@@ -2027,11 +2171,11 @@ static void sdhci_tuning_timer(unsigned long data) +@@ -2027,11 +2169,11 @@ static void sdhci_tuning_timer(unsigned long data) host = (struct sdhci_host *)data; @@ -30716,7 +30789,7 @@ index 6ce32a7..0562295 100644 } /*****************************************************************************\ -@@ -2045,10 +2189,13 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) +@@ -2045,10 +2187,13 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) BUG_ON(intmask == 0); if (!host->cmd) { @@ -30734,7 +30807,7 @@ index 6ce32a7..0562295 100644 return; } -@@ -2118,6 +2265,19 @@ static void sdhci_show_adma_error(struct sdhci_host *host) +@@ -2118,6 +2263,19 @@ static void sdhci_show_adma_error(struct sdhci_host *host) static void sdhci_show_adma_error(struct sdhci_host *host) { } #endif @@ -30754,7 +30827,7 @@ index 6ce32a7..0562295 100644 static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) { BUG_ON(intmask == 0); -@@ -2144,34 +2304,57 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) +@@ -2144,34 +2302,57 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) return; } } @@ -30827,7 +30900,7 @@ index 6ce32a7..0562295 100644 /* * We currently don't do anything fancy with DMA -@@ -2200,18 +2383,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) +@@ -2200,18 +2381,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS); } @@ -30848,7 +30921,7 @@ index 6ce32a7..0562295 100644 } } -@@ -2222,10 +2395,10 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) +@@ -2222,10 +2393,10 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) u32 intmask; int cardint = 0; @@ -30861,7 +30934,7 @@ index 6ce32a7..0562295 100644 pr_warning("%s: got irq while runtime suspended\n", mmc_hostname(host->mmc)); return IRQ_HANDLED; -@@ -2266,6 +2439,22 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) +@@ -2266,6 +2437,22 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) tasklet_schedule(&host->card_tasklet); } @@ -30884,7 +30957,7 @@ index 6ce32a7..0562295 100644 if (intmask & SDHCI_INT_CMD_MASK) { sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK, SDHCI_INT_STATUS); -@@ -2280,7 +2469,13 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) +@@ -2280,7 +2467,13 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK); @@ -30899,7 +30972,7 @@ index 6ce32a7..0562295 100644 if (intmask & SDHCI_INT_BUS_POWER) { pr_err("%s: Card is consuming too much power!\n", -@@ -2307,7 +2502,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) +@@ -2307,7 +2500,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) mmiowb(); out: @@ -30908,7 +30981,7 @@ index 6ce32a7..0562295 100644 /* * We have to delay this as it calls back into the driver. -@@ -2363,7 +2558,8 @@ int sdhci_resume_host(struct sdhci_host *host) +@@ -2363,7 +2556,8 @@ int sdhci_resume_host(struct sdhci_host *host) return ret; } @@ -30918,7 +30991,7 @@ index 6ce32a7..0562295 100644 if (host->ops->enable_dma) host->ops->enable_dma(host); } -@@ -2426,15 +2622,15 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host) +@@ -2426,15 +2620,15 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host) host->flags &= ~SDHCI_NEEDS_RETUNING; } @@ -30938,7 +31011,7 @@ index 6ce32a7..0562295 100644 return ret; } -@@ -2466,7 +2662,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host) +@@ -2466,7 +2660,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host) (host->tuning_mode == SDHCI_TUNING_MODE_1)) host->flags |= SDHCI_NEEDS_RETUNING; @@ -30947,7 +31020,7 @@ index 6ce32a7..0562295 100644 host->runtime_suspended = false; -@@ -2477,7 +2673,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host) +@@ -2477,7 +2671,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host) /* Enable Card Detection */ sdhci_enable_card_detection(host); @@ -30956,7 +31029,7 @@ index 6ce32a7..0562295 100644 return ret; } -@@ -2570,14 +2766,16 @@ int sdhci_add_host(struct sdhci_host *host) +@@ -2570,14 +2764,16 @@ int sdhci_add_host(struct sdhci_host *host) host->flags &= ~SDHCI_USE_ADMA; } @@ -30975,7 +31048,7 @@ index 6ce32a7..0562295 100644 } } } -@@ -2688,7 +2886,7 @@ int sdhci_add_host(struct sdhci_host *host) +@@ -2688,7 +2884,7 @@ int sdhci_add_host(struct sdhci_host *host) /* Auto-CMD23 stuff only works in ADMA or PIO. */ if ((host->version >= SDHCI_SPEC_300) && ((host->flags & SDHCI_USE_ADMA) || @@ -30984,7 +31057,7 @@ index 6ce32a7..0562295 100644 host->flags |= SDHCI_AUTO_CMD23; DBG("%s: Auto-CMD23 available\n", mmc_hostname(mmc)); } else { -@@ -2821,6 +3019,12 @@ int sdhci_add_host(struct sdhci_host *host) +@@ -2821,6 +3017,12 @@ int sdhci_add_host(struct sdhci_host *host) mmc->caps |= MMC_CAP_MAX_CURRENT_200; } @@ -30997,7 +31070,7 @@ index 6ce32a7..0562295 100644 mmc->ocr_avail = ocr_avail; mmc->ocr_avail_sdio = ocr_avail; if (host->ocr_avail_sdio) -@@ -2915,7 +3119,7 @@ int sdhci_add_host(struct sdhci_host *host) +@@ -2915,7 +3117,7 @@ int sdhci_add_host(struct sdhci_host *host) host->tuning_timer.function = sdhci_tuning_timer; } @@ -31006,7 +31079,7 @@ index 6ce32a7..0562295 100644 mmc_hostname(mmc), host); if (ret) goto untasklet; -@@ -2953,6 +3157,7 @@ int sdhci_add_host(struct sdhci_host *host) +@@ -2953,6 +3155,7 @@ int sdhci_add_host(struct sdhci_host *host) pr_info("%s: SDHCI controller on %s [%s] using %s\n", mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), @@ -31014,7 +31087,7 @@ index 6ce32a7..0562295 100644 (host->flags & SDHCI_USE_ADMA) ? "ADMA" : (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"); -@@ -2979,7 +3184,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) +@@ -2979,7 +3182,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) unsigned long flags; if (dead) { @@ -31023,7 +31096,7 @@ index 6ce32a7..0562295 100644 host->flags |= SDHCI_DEVICE_DEAD; -@@ -2991,7 +3196,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) +@@ -2991,7 +3194,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) tasklet_schedule(&host->finish_tasklet); } @@ -32347,11 +32420,24 @@ index 31108a0..48081d1 100644 +obj-$(CONFIG_THERMAL_BCM2835) += bcm2835-thermal.o diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c new file mode 100644 -index 0000000..c6420de +index 0000000..72454d4 --- /dev/null +++ b/drivers/thermal/bcm2835-thermal.c -@@ -0,0 +1,195 @@ -+//bcm2835-thermal.c +@@ -0,0 +1,208 @@ ++/***************************************************************************** ++* Copyright 2011 Broadcom Corporation. All rights reserved. ++* ++* Unless you and Broadcom execute a separate written software license ++* agreement governing use of this software, this software is licensed to you ++* under the terms of the GNU General Public License version 2, available at ++* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). ++* ++* Notwithstanding the above, under no circumstances may you combine this ++* software in any way with any other Broadcom software provided under a ++* license other than the GPL, without Broadcom's express prior written ++* consent. ++*****************************************************************************/ ++ +#include +#include +#include @@ -86615,10 +86701,10 @@ index 9b9d8ff..6e9e8e9 100644 obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c new file mode 100644 -index 0000000..5ca8aca +index 0000000..efdee9d --- /dev/null +++ b/drivers/video/bcm2708_fb.c -@@ -0,0 +1,487 @@ +@@ -0,0 +1,491 @@ +/* + * linux/drivers/video/bcm2708_fb.c + * @@ -86657,6 +86743,12 @@ index 0000000..5ca8aca +#include +#include + ++#ifdef BCM2708_FB_DEBUG ++#define print_debug(fmt,...) pr_debug("%s:%s:%d: "fmt, MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) ++#else ++#define print_debug(fmt,...) ++#endif ++ +/* This is limited to 16 characters when displayed by X startup */ +static const char *bcm2708_name = "BCM2708 FB"; + @@ -86756,17 +86848,15 @@ index 0000000..5ca8aca +{ + /* info input, var output */ + int yres; -+ /* memory size in pixels */ -+ unsigned pixels = info->screen_size * 8 / var->bits_per_pixel; + + /* info input, var output */ -+ pr_info("bcm2708_fb_check_var info(%p) %dx%d (%dx%d), %d, %d\n", info, ++ print_debug("bcm2708_fb_check_var info(%p) %dx%d (%dx%d), %d, %d\n", info, + info->var.xres, info->var.yres, info->var.xres_virtual, + info->var.yres_virtual, (int)info->screen_size, + info->var.bits_per_pixel); -+ pr_info("bcm2708_fb_check_var var(%p) %dx%d (%dx%d), %d, %d\n", var, ++ print_debug("bcm2708_fb_check_var var(%p) %dx%d (%dx%d), %d\n", var, + var->xres, var->yres, var->xres_virtual, var->yres_virtual, -+ var->bits_per_pixel, pixels); ++ var->bits_per_pixel); + + if (!var->bits_per_pixel) + var->bits_per_pixel = 16; @@ -86832,7 +86922,7 @@ index 0000000..5ca8aca + fbinfo->base = 0; /* filled in by VC */ + fbinfo->pitch = 0; /* filled in by VC */ + -+ pr_info("bcm2708_fb_set_par info(%p) %dx%d (%dx%d), %d, %d\n", info, ++ print_debug("bcm2708_fb_set_par info(%p) %dx%d (%dx%d), %d, %d\n", info, + info->var.xres, info->var.yres, info->var.xres_virtual, + info->var.yres_virtual, (int)info->screen_size, + info->var.bits_per_pixel); @@ -86872,7 +86962,7 @@ index 0000000..5ca8aca + BUG(); /* what can we do here */ + } + } -+ pr_info ++ print_debug + ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d success=%d\n", + (void *)fb->fb.screen_base, (void *)fb->fb.fix.smem_start, + fbinfo->xres, fbinfo->yres, fbinfo->bpp, @@ -86895,7 +86985,7 @@ index 0000000..5ca8aca +{ + struct bcm2708_fb *fb = to_bcm2708(info); + -+ /*pr_info("BCM2708FB: setcolreg %d:(%02x,%02x,%02x,%02x) %x\n", regno, red, green, blue, transp, fb->fb.fix.visual);*/ ++ /*print_debug("BCM2708FB: setcolreg %d:(%02x,%02x,%02x,%02x) %x\n", regno, red, green, blue, transp, fb->fb.fix.visual);*/ + if (fb->fb.var.bits_per_pixel <= 8) { + if (regno < 256) { + /* blue [0:4], green [5:10], red [11:15] */ @@ -86918,28 +87008,28 @@ index 0000000..5ca8aca + +static int bcm2708_fb_blank(int blank_mode, struct fb_info *info) +{ -+ /*pr_info("bcm2708_fb_blank\n"); */ ++ /*print_debug("bcm2708_fb_blank\n"); */ + return -1; +} + +static void bcm2708_fb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) +{ -+ /* (is called) pr_info("bcm2708_fb_fillrect\n"); */ ++ /* (is called) print_debug("bcm2708_fb_fillrect\n"); */ + cfb_fillrect(info, rect); +} + +static void bcm2708_fb_copyarea(struct fb_info *info, + const struct fb_copyarea *region) +{ -+ /*pr_info("bcm2708_fb_copyarea\n"); */ ++ /*print_debug("bcm2708_fb_copyarea\n"); */ + cfb_copyarea(info, region); +} + +static void bcm2708_fb_imageblit(struct fb_info *info, + const struct fb_image *image) +{ -+ /* (is called) pr_info("bcm2708_fb_imageblit\n"); */ ++ /* (is called) print_debug("bcm2708_fb_imageblit\n"); */ + cfb_imageblit(info, image); +} + @@ -87014,15 +87104,15 @@ index 0000000..5ca8aca + + fb_set_var(&fb->fb, &fb->fb.var); + -+ pr_info("BCM2708FB: registering framebuffer (%dx%d@%d)\n", fbwidth, ++ print_debug("BCM2708FB: registering framebuffer (%dx%d@%d)\n", fbwidth, + fbheight, fbdepth); + + ret = register_framebuffer(&fb->fb); -+ pr_info("BCM2708FB: register framebuffer (%d)\n", ret); ++ print_debug("BCM2708FB: register framebuffer (%d)\n", ret); + if (ret == 0) + goto out; + -+ pr_info("BCM2708FB: cannot register framebuffer (%d)\n", ret); ++ print_debug("BCM2708FB: cannot register framebuffer (%d)\n", ret); +out: + return ret; +} @@ -90336,7 +90426,7 @@ index 0000000..0c1b80a +} diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c new file mode 100755 -index 0000000..bc146a2 +index 0000000..2f63ac6 --- /dev/null +++ b/sound/arm/bcm2835-pcm.c @@ -0,0 +1,408 @@ @@ -90440,7 +90530,7 @@ index 0000000..bc146a2 + + audio_info(" .. IN (%d)\n", substream->number); + -+ audio_warning("Alsa open (%d)\n", substream->number); ++ audio_info("Alsa open (%d)\n", substream->number); + idx = substream->number; + + if (idx > MAX_SUBSTREAMS) { @@ -90509,7 +90599,7 @@ index 0000000..bc146a2 + bcm2835_alsa_stream_t *alsa_stream = runtime->private_data; + + audio_info(" .. IN\n"); -+ audio_warning("Alsa close\n"); ++ audio_info("Alsa close\n"); + + /* + * Call stop if it's still running. This happens when app @@ -90750,10 +90840,10 @@ index 0000000..bc146a2 +} diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c new file mode 100755 -index 0000000..68d838d +index 0000000..3b7ed1e --- /dev/null +++ b/sound/arm/bcm2835-vchiq.c -@@ -0,0 +1,834 @@ +@@ -0,0 +1,825 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -90788,17 +90878,10 @@ index 0000000..68d838d +/* ---- Include Files -------------------------------------------------------- */ + +#include "interface/vchi/vchi.h" -+#include "interface/vcos/vcos.h" -+#include "interface/vcos/vcos_logging.h" +#include "vc_vchi_audioserv_defs.h" + +/* ---- Private Constants and Types ------------------------------------------ */ + -+/* VCOS logging category for this service */ -+#define VCOS_LOG_CATEGORY (&audio_log_category) -+ -+/* Default VCOS logging level */ -+#define LOG_LEVEL VCOS_LOG_WARN +/* Logging macros (for remapping to other logging mechanisms, i.e., printf) */ +#ifdef AUDIO_DEBUG_ENABLE + #define LOG_ERR( fmt, arg... ) pr_err( "%s:%d " fmt, __func__, __LINE__, ##arg) @@ -90806,26 +90889,23 @@ index 0000000..68d838d + #define LOG_INFO( fmt, arg... ) pr_info( "%s:%d " fmt, __func__, __LINE__, ##arg) + #define LOG_DBG( fmt, arg... ) pr_info( "%s:%d " fmt, __func__, __LINE__, ##arg) +#else -+ #define LOG_ERR( fmt, arg... ) vcos_log_error( "%s:%d " fmt, __func__, __LINE__, ##arg) -+ #define LOG_WARN( fmt, arg... ) vcos_log_warn( "%s:%d " fmt, __func__, __LINE__, ##arg) -+ #define LOG_INFO( fmt, arg... ) vcos_log_info( "%s:%d " fmt, __func__, __LINE__, ##arg) -+ #define LOG_DBG( fmt, arg... ) vcos_log_info( "%s:%d " fmt, __func__, __LINE__, ##arg) ++ #define LOG_ERR( fmt, arg... ) ++ #define LOG_WARN( fmt, arg... ) ++ #define LOG_INFO( fmt, arg... ) ++ #define LOG_DBG( fmt, arg... ) +#endif + +typedef struct opaque_AUDIO_INSTANCE_T { + uint32_t num_connections; + VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS]; -+ VCOS_EVENT_T msg_avail_event; -+ VCOS_MUTEX_T vchi_mutex; ++ struct semaphore msg_avail_event; ++ struct mutex vchi_mutex; + bcm2835_alsa_stream_t *alsa_stream; + int32_t result, got_result; +} AUDIO_INSTANCE_T; + +/* ---- Private Variables ---------------------------------------------------- */ + -+/* VCOS logging category for this service */ -+static VCOS_LOG_CAT_T audio_log_category; -+ +/* ---- Private Function Prototypes ------------------------------------------ */ + +/* ---- Private Functions ---------------------------------------------------- */ @@ -90942,7 +91022,7 @@ index 0000000..68d838d + BUG_ON(instance->got_result); + instance->result = m.u.result.success; + instance->got_result = 1; -+ vcos_event_signal(&instance->msg_avail_event); ++ up(&instance->msg_avail_event); + } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { + irq_handler_t callback = (irq_handler_t) m.u.complete.callback; + LOG_DBG @@ -90955,7 +91035,7 @@ index 0000000..68d838d + LOG_DBG(" .. unexpected alsa_stream=%p, callback=%p\n", + alsa_stream, callback); + } -+ vcos_event_signal(&instance->msg_avail_event); ++ up(&instance->msg_avail_event); + } else { + LOG_DBG(" .. unexpected m.type=%d\n", m.type); + } @@ -90968,7 +91048,7 @@ index 0000000..68d838d +{ + uint32_t i; + AUDIO_INSTANCE_T *instance; -+ VCOS_STATUS_T status; ++ int status; + + LOG_DBG("%s: start", __func__); + @@ -90979,27 +91059,16 @@ index 0000000..68d838d + return NULL; + } + /* Allocate memory for this instance */ -+ instance = vcos_malloc(sizeof(*instance), "audio_instance"); ++ instance = kmalloc(sizeof(*instance), GFP_KERNEL); ++ + memset(instance, 0, sizeof(*instance)); + + instance->num_connections = num_connections; + /* Create the message available event */ -+ status = -+ vcos_event_create(&instance->msg_avail_event, "audio_msg_avail"); -+ if (status != VCOS_SUCCESS) { -+ LOG_ERR("%s: failed to create event (status=%d)", __func__, -+ status); ++ sema_init(&instance->msg_avail_event,1); + -+ goto err_free_mem; -+ } + /* Create a lock for exclusive, serialized VCHI connection access */ -+ status = vcos_mutex_create(&instance->vchi_mutex, "audio_vchi_mutex"); -+ if (status != VCOS_SUCCESS) { -+ LOG_ERR("%s: failed to create event (status=%d)", __func__, -+ status); -+ -+ goto err_delete_event; -+ } ++ mutex_init(&instance->vchi_mutex); + /* Open the VCHI service connections */ + for (i = 0; i < num_connections; i++) { + SERVICE_CREATION_T params = { @@ -91009,14 +91078,14 @@ index 0000000..68d838d + 0, // tx fifo size (unused) + audio_vchi_callback, // service callback + instance, // service callback parameter -+ VCOS_TRUE, //TODO: remove VCOS_FALSE, // unaligned bulk recieves -+ VCOS_TRUE, //TODO: remove VCOS_FALSE, // unaligned bulk transmits -+ VCOS_FALSE // want crc check on bulk transfers ++ 1, //TODO: remove VCOS_FALSE, // unaligned bulk recieves ++ 1, //TODO: remove VCOS_FALSE, // unaligned bulk transmits ++ 0 // want crc check on bulk transfers + }; + + status = vchi_service_open(vchi_instance, ¶ms, + &instance->vchi_handle[i]); -+ if (status != VCOS_SUCCESS) { ++ if (status) { + LOG_ERR + ("%s: failed to open VCHI service connection (status=%d)", + __func__, status); @@ -91034,13 +91103,7 @@ index 0000000..68d838d + vchi_service_close(instance->vchi_handle[i]); + } + -+ vcos_mutex_delete(&instance->vchi_mutex); -+ -+err_delete_event: -+ vcos_event_delete(&instance->msg_avail_event); -+ -+err_free_mem: -+ vcos_free(instance); ++ kfree(instance); + + return NULL; +} @@ -91058,7 +91121,11 @@ index 0000000..68d838d + } + + LOG_DBG(" .. about to lock (%d)\n", instance->num_connections); -+ vcos_mutex_lock(&instance->vchi_mutex); ++ if(mutex_lock_interruptible(&instance->vchi_mutex)) ++ { ++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections); ++ return -EINTR; ++ } + + /* Close all VCHI service connections */ + for (i = 0; i < instance->num_connections; i++) { @@ -91074,16 +91141,9 @@ index 0000000..68d838d + } + } + -+ vcos_mutex_unlock(&instance->vchi_mutex); ++ mutex_unlock(&instance->vchi_mutex); + -+ vcos_mutex_delete(&instance->vchi_mutex); -+ -+ vcos_event_delete(&instance->msg_avail_event); -+ -+ vcos_free(instance); -+ -+ /* Unregister the log category so we can add it back next time */ -+ vcos_log_unregister(&audio_log_category); ++ kfree(instance); + + LOG_DBG(" .. OUT\n"); + @@ -91127,10 +91187,6 @@ index 0000000..68d838d + goto err_free_mem; + } + -+ /* Set up the VCOS logging */ -+ vcos_log_set_level(VCOS_LOG_CATEGORY, LOG_LEVEL); -+ vcos_log_register("audio", VCOS_LOG_CATEGORY); -+ + /* Initialize an instance of the audio service */ + instance = vc_vchi_audio_init(vchi_instance, &vchi_connection, 1); + @@ -91168,7 +91224,11 @@ index 0000000..68d838d + } + instance = alsa_stream->instance; + -+ vcos_mutex_lock(&instance->vchi_mutex); ++ if(mutex_lock_interruptible(&instance->vchi_mutex)) ++ { ++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections); ++ return -EINTR; ++ } + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_OPEN; @@ -91190,7 +91250,7 @@ index 0000000..68d838d + +unlock: + vchi_service_release(instance->vchi_handle[0]); -+ vcos_mutex_unlock(&instance->vchi_mutex); ++ mutex_unlock(&instance->vchi_mutex); +exit: + LOG_DBG(" .. OUT\n"); + return ret; @@ -91208,7 +91268,11 @@ index 0000000..68d838d + LOG_INFO + (" Setting ALSA dest(%d), volume(%d)\n", chip->dest, chip->volume); + -+ vcos_mutex_lock(&instance->vchi_mutex); ++ if(mutex_lock_interruptible(&instance->vchi_mutex)) ++ { ++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections); ++ return -EINTR; ++ } + vchi_service_use(instance->vchi_handle[0]); + + instance->got_result = 0; @@ -91233,8 +91297,7 @@ index 0000000..68d838d + + /* We are expecting a reply from the videocore */ + while (!instance->got_result) { -+ success = vcos_event_wait(&instance->msg_avail_event); -+ if (success != VCOS_SUCCESS) { ++ if (down_interruptible(&instance->msg_avail_event)) { + LOG_ERR("%s: failed on waiting for event (status=%d)", + __func__, success); + @@ -91254,7 +91317,7 @@ index 0000000..68d838d + +unlock: + vchi_service_release(instance->vchi_handle[0]); -+ vcos_mutex_unlock(&instance->vchi_mutex); ++ mutex_unlock(&instance->vchi_mutex); + + LOG_DBG(" .. OUT\n"); + return ret; @@ -91308,7 +91371,11 @@ index 0000000..68d838d + return -EINVAL; + } + -+ vcos_mutex_lock(&instance->vchi_mutex); ++ if(mutex_lock_interruptible(&instance->vchi_mutex)) ++ { ++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections); ++ return -EINTR; ++ } + vchi_service_use(instance->vchi_handle[0]); + + instance->got_result = 0; @@ -91334,8 +91401,7 @@ index 0000000..68d838d + + /* We are expecting a reply from the videocore */ + while (!instance->got_result) { -+ success = vcos_event_wait(&instance->msg_avail_event); -+ if (success != VCOS_SUCCESS) { ++ if (down_interruptible(&instance->msg_avail_event)) { + LOG_ERR("%s: failed on waiting for event (status=%d)", + __func__, success); + @@ -91355,7 +91421,7 @@ index 0000000..68d838d + +unlock: + vchi_service_release(instance->vchi_handle[0]); -+ vcos_mutex_unlock(&instance->vchi_mutex); ++ mutex_unlock(&instance->vchi_mutex); + + LOG_DBG(" .. OUT\n"); + return ret; @@ -91378,7 +91444,11 @@ index 0000000..68d838d + int ret; + LOG_DBG(" .. IN\n"); + -+ vcos_mutex_lock(&instance->vchi_mutex); ++ if(mutex_lock_interruptible(&instance->vchi_mutex)) ++ { ++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections); ++ return -EINTR; ++ } + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_START; @@ -91400,7 +91470,7 @@ index 0000000..68d838d + +unlock: + vchi_service_release(instance->vchi_handle[0]); -+ vcos_mutex_unlock(&instance->vchi_mutex); ++ mutex_unlock(&instance->vchi_mutex); + LOG_DBG(" .. OUT\n"); + return ret; +} @@ -91413,7 +91483,11 @@ index 0000000..68d838d + int ret; + LOG_DBG(" .. IN\n"); + -+ vcos_mutex_lock(&instance->vchi_mutex); ++ if(mutex_lock_interruptible(&instance->vchi_mutex)) ++ { ++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections); ++ return -EINTR; ++ } + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_STOP; @@ -91436,7 +91510,7 @@ index 0000000..68d838d + +unlock: + vchi_service_release(instance->vchi_handle[0]); -+ vcos_mutex_unlock(&instance->vchi_mutex); ++ mutex_unlock(&instance->vchi_mutex); + LOG_DBG(" .. OUT\n"); + return ret; +} @@ -91451,7 +91525,11 @@ index 0000000..68d838d + + my_workqueue_quit(alsa_stream); + -+ vcos_mutex_lock(&instance->vchi_mutex); ++ if(mutex_lock_interruptible(&instance->vchi_mutex)) ++ { ++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections); ++ return -EINTR; ++ } + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_CLOSE; @@ -91468,8 +91546,7 @@ index 0000000..68d838d + goto unlock; + } + while (!instance->got_result) { -+ success = vcos_event_wait(&instance->msg_avail_event); -+ if (success != VCOS_SUCCESS) { ++ if (down_interruptible(&instance->msg_avail_event)) { + LOG_ERR("%s: failed on waiting for event (status=%d)", + __func__, success); + @@ -91489,7 +91566,7 @@ index 0000000..68d838d + +unlock: + vchi_service_release(instance->vchi_handle[0]); -+ vcos_mutex_unlock(&instance->vchi_mutex); ++ mutex_unlock(&instance->vchi_mutex); + + /* Stop the audio service */ + if (instance) { @@ -91512,7 +91589,11 @@ index 0000000..68d838d + + LOG_INFO(" Writing %d bytes from %p\n", count, src); + -+ vcos_mutex_lock(&instance->vchi_mutex); ++ if(mutex_lock_interruptible(&instance->vchi_mutex)) ++ { ++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections); ++ return -EINTR; ++ } + vchi_service_use(instance->vchi_handle[0]); + + m.type = VC_AUDIO_MSG_TYPE_WRITE; @@ -91557,7 +91638,7 @@ index 0000000..68d838d + +unlock: + vchi_service_release(instance->vchi_handle[0]); -+ vcos_mutex_unlock(&instance->vchi_mutex); ++ mutex_unlock(&instance->vchi_mutex); + LOG_DBG(" .. OUT\n"); + return ret; +} @@ -91590,10 +91671,10 @@ index 0000000..68d838d +} diff --git a/sound/arm/bcm2835.c b/sound/arm/bcm2835.c new file mode 100755 -index 0000000..44bedb5 +index 0000000..9546fe6 --- /dev/null +++ b/sound/arm/bcm2835.c -@@ -0,0 +1,418 @@ +@@ -0,0 +1,413 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -91683,8 +91764,6 @@ index 0000000..44bedb5 + bcm2835_chip_t *chip; + struct snd_card *card; + int err; -+ printk(KERN_INFO "Probing FOR bcm2835 ALSA device (%d):(%d)\n", -+ dev, enable[dev]); + + if (dev >= MAX_SUBSTREAMS) + return -ENODEV; @@ -91697,7 +91776,6 @@ index 0000000..44bedb5 + if (dev > 0) + goto add_register_map; + -+ printk("Creating card...\n"); + err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &g_card); + if (err < 0) + goto out; @@ -91970,8 +92048,6 @@ index 0000000..44bedb5 + printk("Error registering bcm2835_alsa7_driver %d .\n", err); + goto unregister_6; + } -+ printk(KERN_INFO "BCM2835 ALSA driver init %s\n", -+ err ? "FAILED" : "OK"); + + return 0; + diff --git a/packages/linux/patches/linux-3.2.28-901_broken_bluetooth.patch b/packages/linux/patches/linux-3.2.30-901_broken_bluetooth.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-901_broken_bluetooth.patch rename to packages/linux/patches/linux-3.2.30-901_broken_bluetooth.patch diff --git a/packages/linux/patches/linux-3.2.30-920_add_rtl8168.patch b/packages/linux/patches/linux-3.2.30-920_add_rtl8168.patch new file mode 100644 index 0000000000..2346fa6778 --- /dev/null +++ b/packages/linux/patches/linux-3.2.30-920_add_rtl8168.patch @@ -0,0 +1,18189 @@ +commit 8b6446a75e84e593a100d76a47abd3cb876b876f +Author: Stefan Saraev +Date: Sun Apr 8 19:10:16 2012 +0300 + + add r8168 + +diff --git a/drivers/net/ethernet/realtek/Kconfig b/drivers/net/ethernet/realtek/Kconfig +index 0578859..1c46e3a 100644 +--- a/drivers/net/ethernet/realtek/Kconfig ++++ b/drivers/net/ethernet/realtek/Kconfig +@@ -102,6 +102,27 @@ config 8139_OLD_RX_RESET + experience problems, you can enable this option to restore the + old RX-reset behavior. If unsure, say N. + ++config R8168 ++ tristate "Realtek 8168 gigabit ethernet support" ++ depends on PCI ++ select FW_LOADER ++ select CRC32 ++ select NET_CORE ++ select MII ++ ---help--- ++ Say Y here if you have a Realtek 8168 Gigabit Ethernet adapter. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called r8168. This is recommended. ++ ++config R8168_NAPI ++ bool "Realtek 8168 NAPI support" ++ depends on R8168 ++ ++config R8168_VLAN ++ bool "Realtek 8168 VLAN support" ++ depends on R8168 ++ + config R8169 + tristate "Realtek 8169 gigabit ethernet support" + depends on PCI +diff --git a/drivers/net/ethernet/realtek/Makefile b/drivers/net/ethernet/realtek/Makefile +index 71b1da3..28ceee4 100644 +--- a/drivers/net/ethernet/realtek/Makefile ++++ b/drivers/net/ethernet/realtek/Makefile +@@ -6,3 +6,4 @@ obj-$(CONFIG_8139CP) += 8139cp.o + obj-$(CONFIG_8139TOO) += 8139too.o + obj-$(CONFIG_ATP) += atp.o + obj-$(CONFIG_R8169) += r8169.o ++obj-$(CONFIG_R8168) += r8168_n.o r8168_asf.o rtl_eeprom.o rtltool.o +diff --git a/drivers/net/ethernet/realtek/r8168.h b/drivers/net/ethernet/realtek/r8168.h +new file mode 100644 +index 0000000..1da23a6 +--- /dev/null ++++ b/drivers/net/ethernet/realtek/r8168.h +@@ -0,0 +1,1271 @@ ++/* ++################################################################################ ++# ++# r8168 is the Linux device driver released for RealTek RTL8168B/8111B, ++# RTL8168C/8111C, RTL8168CP/8111CP, RTL8168D/8111D, and RTL8168DP/8111DP, and ++# RTK8168E/8111E Gigabit Ethernet controllers with PCI-Express interface. ++# ++# Copyright(c) 2012 Realtek Semiconductor Corp. All rights reserved. ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the Free ++# Software Foundation; either version 2 of the License, or (at your option) ++# any later version. ++# ++# This program 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 ++# this program; if not, see . ++# ++# Author: ++# Realtek NIC software team ++# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan ++# ++################################################################################ ++*/ ++ ++/* ++ * This product is covered by one or more of the following patents: ++ * US5,307,459, US5,434,872, US5,732,094, US6,570,884, US6,115,776, and US6,327,625. ++ */ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) ++#define CHECKSUM_PARTIAL CHECKSUM_HW ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ++ #define irqreturn_t void ++ #define IRQ_HANDLED 1 ++ #define IRQ_NONE 0 ++ #define IRQ_RETVAL(x) ++#endif ++ ++#ifndef HAVE_FREE_NETDEV ++#define free_netdev(x) kfree(x) ++#endif ++ ++#ifndef SET_NETDEV_DEV ++#define SET_NETDEV_DEV(net, pdev) ++#endif ++ ++#ifndef SET_MODULE_OWNER ++#define SET_MODULE_OWNER(dev) ++#endif ++ ++#ifndef SA_SHIRQ ++#define SA_SHIRQ IRQF_SHARED ++#endif ++ ++#ifndef NETIF_F_GSO ++#define gso_size tso_size ++#define gso_segs tso_segs ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) ++ #ifdef CONFIG_NET_POLL_CONTROLLER ++ #define RTL_NET_POLL_CONTROLLER dev->poll_controller=rtl8168_netpoll ++ #else ++ #define RTL_NET_POLL_CONTROLLER ++ #endif ++ ++ #ifdef CONFIG_R8168_VLAN ++ #define RTL_SET_VLAN dev->vlan_rx_register=rtl8168_vlan_rx_register ++ #else ++ #define RTL_SET_VLAN ++ #endif ++ ++ #define RTL_NET_DEVICE_OPS(ops) dev->open=rtl8168_open; \ ++ dev->hard_start_xmit=rtl8168_start_xmit; \ ++ dev->get_stats=rtl8168_get_stats; \ ++ dev->stop=rtl8168_close; \ ++ dev->tx_timeout=rtl8168_tx_timeout; \ ++ dev->set_multicast_list=rtl8168_set_rx_mode; \ ++ dev->change_mtu=rtl8168_change_mtu; \ ++ dev->set_mac_address=rtl8168_set_mac_address; \ ++ dev->do_ioctl=rtl8168_do_ioctl; \ ++ RTL_NET_POLL_CONTROLLER; \ ++ RTL_SET_VLAN; ++#else ++ #define RTL_NET_DEVICE_OPS(ops) dev->netdev_ops=&ops ++#endif ++ ++//Due to the hardware design of RTL8111B, the low 32 bit address of receive ++//buffer must be 8-byte alignment. ++#ifndef NET_IP_ALIGN ++#define NET_IP_ALIGN 2 ++#endif ++#define RTK_RX_ALIGN 8 ++ ++#ifdef CONFIG_R8168_NAPI ++#define NAPI_SUFFIX "-NAPI" ++#else ++#define NAPI_SUFFIX "" ++#endif ++ ++#define RTL8168_VERSION "8.029.00" NAPI_SUFFIX ++#define MODULENAME "r8168" ++#define PFX MODULENAME ": " ++ ++#define GPL_CLAIM "\ ++r8168 Copyright (C) 2012 Realtek NIC software team \n \ ++This program comes with ABSOLUTELY NO WARRANTY; for details, please see . \n \ ++This is free software, and you are welcome to redistribute it under certain conditions; see . \n" ++ ++#ifdef RTL8168_DEBUG ++#define assert(expr) \ ++ if(!(expr)) { \ ++ printk( "Assertion failed! %s,%s,%s,line=%d\n", \ ++ #expr,__FILE__,__FUNCTION__,__LINE__); \ ++ } ++#define dprintk(fmt, args...) do { printk(PFX fmt, ## args); } while (0) ++#else ++#define assert(expr) do {} while (0) ++#define dprintk(fmt, args...) do {} while (0) ++#endif /* RTL8168_DEBUG */ ++ ++#define R8168_MSG_DEFAULT \ ++ (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN) ++ ++#define TX_BUFFS_AVAIL(tp) \ ++ (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1) ++ ++#ifdef CONFIG_R8168_NAPI ++#define rtl8168_rx_skb netif_receive_skb ++#define rtl8168_rx_hwaccel_skb vlan_hwaccel_receive_skb ++#define rtl8168_rx_quota(count, quota) min(count, quota) ++#else ++#define rtl8168_rx_skb netif_rx ++#define rtl8168_rx_hwaccel_skb vlan_hwaccel_rx ++#define rtl8168_rx_quota(count, quota) count ++#endif ++ ++/* MAC address length */ ++#ifndef MAC_ADDR_LEN ++#define MAC_ADDR_LEN 6 ++#endif ++ ++#ifndef MAC_PROTOCOL_LEN ++#define MAC_PROTOCOL_LEN 2 ++#endif ++ ++#define Reserved2_data 7 ++#define RX_DMA_BURST 7 /* Maximum PCI burst, '6' is 1024 */ ++#define TX_DMA_BURST_unlimited 7 ++#define TX_DMA_BURST_1024 6 ++#define TX_DMA_BURST_512 5 ++#define TX_DMA_BURST_256 4 ++#define TX_DMA_BURST_128 3 ++#define TX_DMA_BURST_64 2 ++#define TX_DMA_BURST_32 1 ++#define TX_DMA_BURST_16 0 ++#define Reserved1_data 0x3F ++#define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */ ++#define Jumbo_Frame_2k (2 * 1024) ++#define Jumbo_Frame_3k (3 * 1024) ++#define Jumbo_Frame_4k (4 * 1024) ++#define Jumbo_Frame_5k (5 * 1024) ++#define Jumbo_Frame_6k (6 * 1024) ++#define Jumbo_Frame_7k (7 * 1024) ++#define Jumbo_Frame_8k (8 * 1024) ++#define Jumbo_Frame_9k (9 * 1024) ++#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ ++ ++#define R8168_REGS_SIZE 256 ++#define R8168_NAPI_WEIGHT 64 ++ ++#define RX_BUF_SIZE 0x05F3 /* 0x05F3 = 1522bye + 1 */ ++#define R8168_TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) ++#define R8168_RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) ++ ++#define RTL8168_TX_TIMEOUT (6 * HZ) ++#define RTL8168_LINK_TIMEOUT (1 * HZ) ++#define RTL8168_ESD_TIMEOUT (2 * HZ) ++ ++#define NUM_TX_DESC 1024 /* Number of Tx descriptor registers */ ++#define NUM_RX_DESC 1024 /* Number of Rx descriptor registers */ ++ ++#define NODE_ADDRESS_SIZE 6 ++ ++/* write/read MMIO register */ ++#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) ++#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) ++#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) ++#define RTL_R8(reg) readb (ioaddr + (reg)) ++#define RTL_R16(reg) readw (ioaddr + (reg)) ++#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) ++ ++#ifndef DMA_64BIT_MASK ++#define DMA_64BIT_MASK 0xffffffffffffffffULL ++#endif ++ ++#ifndef DMA_32BIT_MASK ++#define DMA_32BIT_MASK 0x00000000ffffffffULL ++#endif ++ ++#ifndef NETDEV_TX_OK ++#define NETDEV_TX_OK 0 /* driver took care of packet */ ++#endif ++ ++#ifndef NETDEV_TX_BUSY ++#define NETDEV_TX_BUSY 1 /* driver tx path was busy*/ ++#endif ++ ++#ifndef NETDEV_TX_LOCKED ++#define NETDEV_TX_LOCKED -1 /* driver tx lock was already taken */ ++#endif ++ ++#ifndef ADVERTISED_Pause ++#define ADVERTISED_Pause (1 << 13) ++#endif ++ ++#ifndef ADVERTISED_Asym_Pause ++#define ADVERTISED_Asym_Pause (1 << 14) ++#endif ++ ++#ifndef ADVERTISE_PAUSE_CAP ++#define ADVERTISE_PAUSE_CAP 0x400 ++#endif ++ ++#ifndef ADVERTISE_PAUSE_ASYM ++#define ADVERTISE_PAUSE_ASYM 0x800 ++#endif ++ ++#ifndef MII_CTRL1000 ++#define MII_CTRL1000 0x09 ++#endif ++ ++#ifndef ADVERTISE_1000FULL ++#define ADVERTISE_1000FULL 0x200 ++#endif ++ ++#ifndef ADVERTISE_1000HALF ++#define ADVERTISE_1000HALF 0x100 ++#endif ++ ++/*****************************************************************************/ ++ ++//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) ++#if (( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) ) || \ ++ (( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) && \ ++ ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) ))) ++/* copied from linux kernel 2.6.20 include/linux/netdev.h */ ++#define NETDEV_ALIGN 32 ++#define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1) ++ ++static inline void *netdev_priv(struct net_device *dev) ++{ ++ return (char *)dev + ((sizeof(struct net_device) ++ + NETDEV_ALIGN_CONST) ++ & ~NETDEV_ALIGN_CONST); ++} ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) ++ ++/*****************************************************************************/ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ++ #define RTLDEV tp ++#else ++ #define RTLDEV dev ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ++/*****************************************************************************/ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ++ typedef struct net_device *napi_ptr; ++ typedef int *napi_budget; ++ ++ #define napi dev ++ #define RTL_NAPI_CONFIG(ndev, priv, function, weig) ndev->poll=function; \ ++ ndev->weight=weig; ++ #define RTL_NAPI_QUOTA(budget, ndev) min(*budget, ndev->quota) ++ #define RTL_GET_PRIV(stuct_ptr, priv_struct) netdev_priv(stuct_ptr) ++ #define RTL_GET_NETDEV(priv_ptr) ++ #define RTL_RX_QUOTA(ndev, budget) ndev->quota ++ #define RTL_NAPI_QUOTA_UPDATE(ndev, work_done, budget) *budget -= work_done; \ ++ ndev->quota -= work_done; ++ #define RTL_NETIF_RX_COMPLETE(dev, napi) netif_rx_complete(dev) ++ #define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(dev) ++ #define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(dev) ++ #define RTL_NAPI_RETURN_VALUE work_done >= work_to_do ++ #define RTL_NAPI_ENABLE(dev, napi) netif_poll_enable(dev) ++ #define RTL_NAPI_DISABLE(dev, napi) netif_poll_disable(dev) ++ #define DMA_BIT_MASK(value) ((1ULL << value) - 1) ++#else ++ typedef struct napi_struct *napi_ptr; ++ typedef int napi_budget; ++ ++ #define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add(ndev, &priv->napi, function, weight) ++ #define RTL_NAPI_QUOTA(budget, ndev) min(budget, budget) ++ #define RTL_GET_PRIV(stuct_ptr, priv_struct) container_of(stuct_ptr, priv_struct, stuct_ptr) ++ #define RTL_GET_NETDEV(priv_ptr) struct net_device *dev = priv_ptr->dev; ++ #define RTL_RX_QUOTA(ndev, budget) budget ++ #define RTL_NAPI_QUOTA_UPDATE(ndev, work_done, budget) ++ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) ++ #define RTL_NETIF_RX_COMPLETE(dev, napi) netif_rx_complete(dev, napi) ++ #define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(dev, napi) ++ #define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(dev, napi) ++ #endif ++ #if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,29) ++ #define RTL_NETIF_RX_COMPLETE(dev, napi) netif_rx_complete(napi) ++ #define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(napi) ++ #define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(napi) ++ #endif ++ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) ++ #define RTL_NETIF_RX_COMPLETE(dev, napi) napi_complete(napi) ++ #define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) napi_schedule_prep(napi) ++ #define __RTL_NETIF_RX_SCHEDULE(dev, napi) __napi_schedule(napi) ++ #endif ++ #define RTL_NAPI_RETURN_VALUE work_done ++ #define RTL_NAPI_ENABLE(dev, napi) napi_enable(napi) ++ #define RTL_NAPI_DISABLE(dev, napi) napi_disable(napi) ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ++ ++/*****************************************************************************/ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) ++#ifdef __CHECKER__ ++#define __iomem __attribute__((noderef, address_space(2))) ++extern void __chk_io_ptr(void __iomem *); ++#define __bitwise __attribute__((bitwise)) ++#else ++#define __iomem ++#define __chk_io_ptr(x) (void)0 ++#define __bitwise ++#endif ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) ++ ++/*****************************************************************************/ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) ++#ifdef __CHECKER__ ++#define __force __attribute__((force)) ++#else ++#define __force ++#endif ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) ++ ++#ifndef module_param ++#define module_param(v,t,p) MODULE_PARM(v, "i"); ++#endif ++ ++#ifndef PCI_DEVICE ++#define PCI_DEVICE(vend,dev) \ ++ .vendor = (vend), .device = (dev), \ ++ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID ++#endif ++ ++/*****************************************************************************/ ++/* 2.5.28 => 2.4.23 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) ) ++ ++static inline void _kc_synchronize_irq(void) ++{ ++ synchronize_irq(); ++} ++#undef synchronize_irq ++#define synchronize_irq(X) _kc_synchronize_irq() ++ ++#include ++#define work_struct tq_struct ++#undef INIT_WORK ++#define INIT_WORK(a,b,c) INIT_TQUEUE(a,(void (*)(void *))b,c) ++#undef container_of ++#define container_of list_entry ++#define schedule_work schedule_task ++#define flush_scheduled_work flush_scheduled_tasks ++#endif /* 2.5.28 => 2.4.17 */ ++ ++/*****************************************************************************/ ++/* 2.6.4 => 2.6.0 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) ++#define MODULE_VERSION(_version) MODULE_INFO(version, _version) ++#endif /* 2.6.4 => 2.6.0 */ ++/*****************************************************************************/ ++/* 2.6.0 => 2.5.28 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) ++#define MODULE_INFO(version, _version) ++#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT ++#define CONFIG_E1000_DISABLE_PACKET_SPLIT 1 ++#endif ++ ++#define pci_set_consistent_dma_mask(dev,mask) 1 ++ ++#undef dev_put ++#define dev_put(dev) __dev_put(dev) ++ ++#ifndef skb_fill_page_desc ++#define skb_fill_page_desc _kc_skb_fill_page_desc ++extern void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size); ++#endif ++ ++#ifndef pci_dma_mapping_error ++#define pci_dma_mapping_error _kc_pci_dma_mapping_error ++static inline int _kc_pci_dma_mapping_error(dma_addr_t dma_addr) ++{ ++ return dma_addr == 0; ++} ++#endif ++ ++#undef ALIGN ++#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1)) ++ ++#endif /* 2.6.0 => 2.5.28 */ ++ ++/*****************************************************************************/ ++/* 2.4.22 => 2.4.17 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) ) ++#define pci_name(x) ((x)->slot_name) ++#endif /* 2.4.22 => 2.4.17 */ ++ ++/*****************************************************************************/ ++/* 2.6.5 => 2.6.0 */ ++#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_device pci_dma_sync_single_for_cpu ++#endif /* 2.6.5 => 2.6.0 */ ++ ++/*****************************************************************************/ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ++/* ++ * initialize a work-struct's func and data pointers: ++ */ ++#define PREPARE_WORK(_work, _func, _data) \ ++ do { \ ++ (_work)->func = _func; \ ++ (_work)->data = _data; \ ++ } while (0) ++ ++#endif ++/*****************************************************************************/ ++/* 2.6.4 => 2.6.0 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25) || \ ++ ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \ ++ LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) ) ++#define ETHTOOL_OPS_COMPAT ++#endif /* 2.6.4 => 2.6.0 */ ++ ++/*****************************************************************************/ ++/* Installations with ethtool version without eeprom, adapter id, or statistics ++ * support */ ++ ++#ifndef ETH_GSTRING_LEN ++#define ETH_GSTRING_LEN 32 ++#endif ++ ++#ifndef ETHTOOL_GSTATS ++#define ETHTOOL_GSTATS 0x1d ++#undef ethtool_drvinfo ++#define ethtool_drvinfo k_ethtool_drvinfo ++struct k_ethtool_drvinfo { ++ u32 cmd; ++ char driver[32]; ++ char version[32]; ++ char fw_version[32]; ++ char bus_info[32]; ++ char reserved1[32]; ++ char reserved2[16]; ++ u32 n_stats; ++ u32 testinfo_len; ++ u32 eedump_len; ++ u32 regdump_len; ++}; ++ ++struct ethtool_stats { ++ u32 cmd; ++ u32 n_stats; ++ u64 data[0]; ++}; ++#endif /* ETHTOOL_GSTATS */ ++ ++#ifndef ETHTOOL_PHYS_ID ++#define ETHTOOL_PHYS_ID 0x1c ++#endif /* ETHTOOL_PHYS_ID */ ++ ++#ifndef ETHTOOL_GSTRINGS ++#define ETHTOOL_GSTRINGS 0x1b ++enum ethtool_stringset { ++ ETH_SS_TEST = 0, ++ ETH_SS_STATS, ++}; ++struct ethtool_gstrings { ++ u32 cmd; /* ETHTOOL_GSTRINGS */ ++ u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/ ++ u32 len; /* number of strings in the string set */ ++ u8 data[0]; ++}; ++#endif /* ETHTOOL_GSTRINGS */ ++ ++#ifndef ETHTOOL_TEST ++#define ETHTOOL_TEST 0x1a ++enum ethtool_test_flags { ++ ETH_TEST_FL_OFFLINE = (1 << 0), ++ ETH_TEST_FL_FAILED = (1 << 1), ++}; ++struct ethtool_test { ++ u32 cmd; ++ u32 flags; ++ u32 reserved; ++ u32 len; ++ u64 data[0]; ++}; ++#endif /* ETHTOOL_TEST */ ++ ++#ifndef ETHTOOL_GEEPROM ++#define ETHTOOL_GEEPROM 0xb ++#undef ETHTOOL_GREGS ++struct ethtool_eeprom { ++ u32 cmd; ++ u32 magic; ++ u32 offset; ++ u32 len; ++ u8 data[0]; ++}; ++ ++struct ethtool_value { ++ u32 cmd; ++ u32 data; ++}; ++#endif /* ETHTOOL_GEEPROM */ ++ ++#ifndef ETHTOOL_GLINK ++#define ETHTOOL_GLINK 0xa ++#endif /* ETHTOOL_GLINK */ ++ ++#ifndef ETHTOOL_GREGS ++#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers */ ++#define ethtool_regs _kc_ethtool_regs ++/* for passing big chunks of data */ ++struct _kc_ethtool_regs { ++ u32 cmd; ++ u32 version; /* driver-specific, indicates different chips/revs */ ++ u32 len; /* bytes */ ++ u8 data[0]; ++}; ++#endif /* ETHTOOL_GREGS */ ++ ++#ifndef ETHTOOL_GMSGLVL ++#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */ ++#endif ++#ifndef ETHTOOL_SMSGLVL ++#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level, priv. */ ++#endif ++#ifndef ETHTOOL_NWAY_RST ++#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation, priv */ ++#endif ++#ifndef ETHTOOL_GLINK ++#define ETHTOOL_GLINK 0x0000000a /* Get link status */ ++#endif ++#ifndef ETHTOOL_GEEPROM ++#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */ ++#endif ++#ifndef ETHTOOL_SEEPROM ++#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data */ ++#endif ++#ifndef ETHTOOL_GCOALESCE ++#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */ ++/* for configuring coalescing parameters of chip */ ++#define ethtool_coalesce _kc_ethtool_coalesce ++struct _kc_ethtool_coalesce { ++ u32 cmd; /* ETHTOOL_{G,S}COALESCE */ ++ ++ /* How many usecs to delay an RX interrupt after ++ * a packet arrives. If 0, only rx_max_coalesced_frames ++ * is used. ++ */ ++ u32 rx_coalesce_usecs; ++ ++ /* How many packets to delay an RX interrupt after ++ * a packet arrives. If 0, only rx_coalesce_usecs is ++ * used. It is illegal to set both usecs and max frames ++ * to zero as this would cause RX interrupts to never be ++ * generated. ++ */ ++ u32 rx_max_coalesced_frames; ++ ++ /* Same as above two parameters, except that these values ++ * apply while an IRQ is being serviced by the host. Not ++ * all cards support this feature and the values are ignored ++ * in that case. ++ */ ++ u32 rx_coalesce_usecs_irq; ++ u32 rx_max_coalesced_frames_irq; ++ ++ /* How many usecs to delay a TX interrupt after ++ * a packet is sent. If 0, only tx_max_coalesced_frames ++ * is used. ++ */ ++ u32 tx_coalesce_usecs; ++ ++ /* How many packets to delay a TX interrupt after ++ * a packet is sent. If 0, only tx_coalesce_usecs is ++ * used. It is illegal to set both usecs and max frames ++ * to zero as this would cause TX interrupts to never be ++ * generated. ++ */ ++ u32 tx_max_coalesced_frames; ++ ++ /* Same as above two parameters, except that these values ++ * apply while an IRQ is being serviced by the host. Not ++ * all cards support this feature and the values are ignored ++ * in that case. ++ */ ++ u32 tx_coalesce_usecs_irq; ++ u32 tx_max_coalesced_frames_irq; ++ ++ /* How many usecs to delay in-memory statistics ++ * block updates. Some drivers do not have an in-memory ++ * statistic block, and in such cases this value is ignored. ++ * This value must not be zero. ++ */ ++ u32 stats_block_coalesce_usecs; ++ ++ /* Adaptive RX/TX coalescing is an algorithm implemented by ++ * some drivers to improve latency under low packet rates and ++ * improve throughput under high packet rates. Some drivers ++ * only implement one of RX or TX adaptive coalescing. Anything ++ * not implemented by the driver causes these values to be ++ * silently ignored. ++ */ ++ u32 use_adaptive_rx_coalesce; ++ u32 use_adaptive_tx_coalesce; ++ ++ /* When the packet rate (measured in packets per second) ++ * is below pkt_rate_low, the {rx,tx}_*_low parameters are ++ * used. ++ */ ++ u32 pkt_rate_low; ++ u32 rx_coalesce_usecs_low; ++ u32 rx_max_coalesced_frames_low; ++ u32 tx_coalesce_usecs_low; ++ u32 tx_max_coalesced_frames_low; ++ ++ /* When the packet rate is below pkt_rate_high but above ++ * pkt_rate_low (both measured in packets per second) the ++ * normal {rx,tx}_* coalescing parameters are used. ++ */ ++ ++ /* When the packet rate is (measured in packets per second) ++ * is above pkt_rate_high, the {rx,tx}_*_high parameters are ++ * used. ++ */ ++ u32 pkt_rate_high; ++ u32 rx_coalesce_usecs_high; ++ u32 rx_max_coalesced_frames_high; ++ u32 tx_coalesce_usecs_high; ++ u32 tx_max_coalesced_frames_high; ++ ++ /* How often to do adaptive coalescing packet rate sampling, ++ * measured in seconds. Must not be zero. ++ */ ++ u32 rate_sample_interval; ++}; ++#endif /* ETHTOOL_GCOALESCE */ ++ ++#ifndef ETHTOOL_SCOALESCE ++#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */ ++#endif ++#ifndef ETHTOOL_GRINGPARAM ++#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */ ++/* for configuring RX/TX ring parameters */ ++#define ethtool_ringparam _kc_ethtool_ringparam ++struct _kc_ethtool_ringparam { ++ u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */ ++ ++ /* Read only attributes. These indicate the maximum number ++ * of pending RX/TX ring entries the driver will allow the ++ * user to set. ++ */ ++ u32 rx_max_pending; ++ u32 rx_mini_max_pending; ++ u32 rx_jumbo_max_pending; ++ u32 tx_max_pending; ++ ++ /* Values changeable by the user. The valid values are ++ * in the range 1 to the "*_max_pending" counterpart above. ++ */ ++ u32 rx_pending; ++ u32 rx_mini_pending; ++ u32 rx_jumbo_pending; ++ u32 tx_pending; ++}; ++#endif /* ETHTOOL_GRINGPARAM */ ++ ++#ifndef ETHTOOL_SRINGPARAM ++#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters, priv. */ ++#endif ++#ifndef ETHTOOL_GPAUSEPARAM ++#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */ ++/* for configuring link flow control parameters */ ++#define ethtool_pauseparam _kc_ethtool_pauseparam ++struct _kc_ethtool_pauseparam { ++ u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */ ++ ++ /* If the link is being auto-negotiated (via ethtool_cmd.autoneg ++ * being true) the user may set 'autonet' here non-zero to have the ++ * pause parameters be auto-negotiated too. In such a case, the ++ * {rx,tx}_pause values below determine what capabilities are ++ * advertised. ++ * ++ * If 'autoneg' is zero or the link is not being auto-negotiated, ++ * then {rx,tx}_pause force the driver to use/not-use pause ++ * flow control. ++ */ ++ u32 autoneg; ++ u32 rx_pause; ++ u32 tx_pause; ++}; ++#endif /* ETHTOOL_GPAUSEPARAM */ ++ ++#ifndef ETHTOOL_SPAUSEPARAM ++#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */ ++#endif ++#ifndef ETHTOOL_GRXCSUM ++#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */ ++#endif ++#ifndef ETHTOOL_SRXCSUM ++#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */ ++#endif ++#ifndef ETHTOOL_GTXCSUM ++#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */ ++#endif ++#ifndef ETHTOOL_STXCSUM ++#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */ ++#endif ++#ifndef ETHTOOL_GSG ++#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable ++ * (ethtool_value) */ ++#endif ++#ifndef ETHTOOL_SSG ++#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable ++ * (ethtool_value). */ ++#endif ++#ifndef ETHTOOL_TEST ++#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test, priv. */ ++#endif ++#ifndef ETHTOOL_GSTRINGS ++#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */ ++#endif ++#ifndef ETHTOOL_PHYS_ID ++#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */ ++#endif ++#ifndef ETHTOOL_GSTATS ++#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */ ++#endif ++#ifndef ETHTOOL_GTSO ++#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */ ++#endif ++#ifndef ETHTOOL_STSO ++#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */ ++#endif ++ ++#ifndef ETHTOOL_BUSINFO_LEN ++#define ETHTOOL_BUSINFO_LEN 32 ++#endif ++ ++/*****************************************************************************/ ++ ++enum RTL8168_DSM_STATE { ++ DSM_MAC_INIT = 1, ++ DSM_NIC_GOTO_D3 = 2, ++ DSM_IF_DOWN = 3, ++ DSM_NIC_RESUME_D3 = 4, ++ DSM_IF_UP = 5, ++}; ++ ++enum RTL8168_registers { ++ MAC0 = 0x00, /* Ethernet hardware address. */ ++ MAC4 = 0x04, ++ MAR0 = 0x08, /* Multicast filter. */ ++ CounterAddrLow = 0x10, ++ CounterAddrHigh = 0x14, ++ CustomLED = 0x18, ++ TxDescStartAddrLow = 0x20, ++ TxDescStartAddrHigh = 0x24, ++ TxHDescStartAddrLow = 0x28, ++ TxHDescStartAddrHigh = 0x2c, ++ FLASH = 0x30, ++ ERSR = 0x36, ++ ChipCmd = 0x37, ++ TxPoll = 0x38, ++ IntrMask = 0x3C, ++ IntrStatus = 0x3E, ++ TxConfig = 0x40, ++ RxConfig = 0x44, ++ TCTR = 0x48, ++ Cfg9346 = 0x50, ++ Config0 = 0x51, ++ Config1 = 0x52, ++ Config2 = 0x53, ++ Config3 = 0x54, ++ Config4 = 0x55, ++ Config5 = 0x56, ++ TimeIntr = 0x58, ++ PHYAR = 0x60, ++ CSIDR = 0x64, ++ CSIAR = 0x68, ++ PHYstatus = 0x6C, ++ MACDBG = 0x6D, ++ GPIO = 0x6E, ++ PMCH = 0x6F, ++ ERIDR = 0x70, ++ ERIAR = 0x74, ++ EPHY_RXER_NUM = 0x7C, ++ EPHYAR = 0x80, ++ OCPDR = 0xB0, ++ OCPAR = 0xB4, ++ DBG_reg = 0xD1, ++ RxMaxSize = 0xDA, ++ EFUSEAR = 0xDC, ++ CPlusCmd = 0xE0, ++ IntrMitigate = 0xE2, ++ RxDescAddrLow = 0xE4, ++ RxDescAddrHigh = 0xE8, ++ MTPS = 0xEC, ++ FuncEvent = 0xF0, ++ FuncEventMask = 0xF4, ++ FuncPresetState = 0xF8, ++ FuncForceEvent = 0xFC, ++}; ++ ++enum RTL8168_register_content { ++ /* InterruptStatusBits */ ++ SYSErr = 0x8000, ++ PCSTimeout = 0x4000, ++ SWInt = 0x0100, ++ TxDescUnavail = 0x0080, ++ RxFIFOOver = 0x0040, ++ LinkChg = 0x0020, ++ RxDescUnavail = 0x0010, ++ TxErr = 0x0008, ++ TxOK = 0x0004, ++ RxErr = 0x0002, ++ RxOK = 0x0001, ++ ++ /* RxStatusDesc */ ++ RxRWT = (1 << 22), ++ RxRES = (1 << 21), ++ RxRUNT = (1 << 20), ++ RxCRC = (1 << 19), ++ ++ /* ChipCmdBits */ ++ StopReq = 0x80, ++ CmdReset = 0x10, ++ CmdRxEnb = 0x08, ++ CmdTxEnb = 0x04, ++ RxBufEmpty = 0x01, ++ ++ /* Cfg9346Bits */ ++ Cfg9346_Lock = 0x00, ++ Cfg9346_Unlock = 0xC0, ++ Cfg9346_EEDO = (1 << 0), ++ Cfg9346_EEDI = (1 << 1), ++ Cfg9346_EESK = (1 << 2), ++ Cfg9346_EECS = (1 << 3), ++ Cfg9346_EEM0 = (1 << 6), ++ Cfg9346_EEM1 = (1 << 7), ++ ++ /* rx_mode_bits */ ++ AcceptErr = 0x20, ++ AcceptRunt = 0x10, ++ AcceptBroadcast = 0x08, ++ AcceptMulticast = 0x04, ++ AcceptMyPhys = 0x02, ++ AcceptAllPhys = 0x01, ++ ++ /* Transmit Priority Polling*/ ++ HPQ = 0x80, ++ NPQ = 0x40, ++ FSWInt = 0x01, ++ ++ /* RxConfigBits */ ++ Reserved2_shift = 13, ++ RxCfgDMAShift = 8, ++ RxCfg_128_int_en = (1 << 15), ++ RxCfg_fet_multi_en = (1 << 14), ++ RxCfg_half_refetch = (1 << 13), ++ RxCfg_9356SEL = (1 << 6), ++ ++ /* TxConfigBits */ ++ TxInterFrameGapShift = 24, ++ TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ ++ TxMACLoopBack = (1 << 17), /* MAC loopback */ ++ ++ /* Config1 register p.24 */ ++ LEDS1 = (1 << 7), ++ LEDS0 = (1 << 6), ++ Speed_down = (1 << 4), ++ MEMMAP = (1 << 3), ++ IOMAP = (1 << 2), ++ VPD = (1 << 1), ++ PMEnable = (1 << 0), /* Power Management Enable */ ++ ++ /* Config3 register */ ++ MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ ++ LinkUp = (1 << 4), /* This bit is reserved in RTL8168B.*/ ++ /* Wake up when the cable connection is re-established */ ++ ECRCEN = (1 << 3), /* This bit is reserved in RTL8168B*/ ++ Jumbo_En0 = (1 << 2), /* This bit is reserved in RTL8168B*/ ++ RDY_TO_L23 = (1 << 1), /* This bit is reserved in RTL8168B*/ ++ Beacon_en = (1 << 0), /* This bit is reserved in RTL8168B*/ ++ ++ /* Config4 register */ ++ Jumbo_En1 = (1 << 1), /* This bit is reserved in RTL8168B*/ ++ ++ /* Config5 register */ ++ BWF = (1 << 6), /* Accept Broadcast wakeup frame */ ++ MWF = (1 << 5), /* Accept Multicast wakeup frame */ ++ UWF = (1 << 4), /* Accept Unicast wakeup frame */ ++ LanWake = (1 << 1), /* LanWake enable/disable */ ++ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ ++ ++ /* CPlusCmd */ ++ EnableBist = (1 << 15), ++ Macdbgo_oe = (1 << 14), ++ Normal_mode = (1 << 13), ++ Force_halfdup = (1 << 12), ++ Force_rxflow_en = (1 << 11), ++ Force_txflow_en = (1 << 10), ++ Cxpl_dbg_sel = (1 << 9),//This bit is reserved in RTL8168B ++ ASF = (1 << 8),//This bit is reserved in RTL8168C ++ PktCntrDisable = (1 << 7), ++ RxVlan = (1 << 6), ++ RxChkSum = (1 << 5), ++ Macdbgo_sel = 0x001C, ++ INTT_0 = 0x0000, ++ INTT_1 = 0x0001, ++ INTT_2 = 0x0002, ++ INTT_3 = 0x0003, ++ ++ /* rtl8168_PHYstatus */ ++ TxFlowCtrl = 0x40, ++ RxFlowCtrl = 0x20, ++ _1000bpsF = 0x10, ++ _100bps = 0x08, ++ _10bps = 0x04, ++ LinkStatus = 0x02, ++ FullDup = 0x01, ++ ++ /* DBG_reg */ ++ Fix_Nak_1 = (1 << 4), ++ Fix_Nak_2 = (1 << 3), ++ DBGPIN_E2 = (1 << 0), ++ ++ /* DumpCounterCommand */ ++ CounterDump = 0x8, ++ ++ /* PHY access */ ++ PHYAR_Flag = 0x80000000, ++ PHYAR_Write = 0x80000000, ++ PHYAR_Read = 0x00000000, ++ PHYAR_Reg_Mask = 0x1f, ++ PHYAR_Reg_shift = 16, ++ PHYAR_Data_Mask = 0xffff, ++ ++ /* EPHY access */ ++ EPHYAR_Flag = 0x80000000, ++ EPHYAR_Write = 0x80000000, ++ EPHYAR_Read = 0x00000000, ++ EPHYAR_Reg_Mask = 0x1f, ++ EPHYAR_Reg_shift = 16, ++ EPHYAR_Data_Mask = 0xffff, ++ ++ /* CSI access */ ++ CSIAR_Flag = 0x80000000, ++ CSIAR_Write = 0x80000000, ++ CSIAR_Read = 0x00000000, ++ CSIAR_ByteEn = 0x0f, ++ CSIAR_ByteEn_shift = 12, ++ CSIAR_Addr_Mask = 0x0fff, ++ ++ /* ERI access */ ++ ERIAR_Flag = 0x80000000, ++ ERIAR_Write = 0x80000000, ++ ERIAR_Read = 0x00000000, ++ ERIAR_Addr_Align = 4, /* ERI access register address must be 4 byte alignment */ ++ ERIAR_ExGMAC = 0, ++ ERIAR_MSIX = 1, ++ ERIAR_ASF = 2, ++ ERIAR_Type_shift = 16, ++ ERIAR_ByteEn = 0x0f, ++ ERIAR_ByteEn_shift = 12, ++ ++ /* OCP GPHY access */ ++ OCPDR_Write = 0x80000000, ++ OCPDR_Read = 0x00000000, ++ OCPDR_Reg_Mask = 0xFF, ++ OCPDR_Data_Mask = 0xFFFF, ++ OCPDR_GPHY_Reg_shift = 16, ++ OCPAR_Flag = 0x80000000, ++ OCPAR_GPHY_Write = 0x8000F060, ++ OCPAR_GPHY_Read = 0x0000F060, ++ ++ /* E-FUSE access */ ++ EFUSE_WRITE = 0x80000000, ++ EFUSE_WRITE_OK = 0x00000000, ++ EFUSE_READ = 0x00000000, ++ EFUSE_READ_OK = 0x80000000, ++ EFUSE_Reg_Mask = 0x03FF, ++ EFUSE_Reg_Shift = 8, ++ EFUSE_Check_Cnt = 300, ++ EFUSE_READ_FAIL = 0xFF, ++ EFUSE_Data_Mask = 0x000000FF, ++ ++ /* GPIO */ ++ GPIO_en = (1 << 0), ++ ++}; ++ ++enum _DescStatusBit { ++ DescOwn = (1 << 31), /* Descriptor is owned by NIC */ ++ RingEnd = (1 << 30), /* End of descriptor ring */ ++ FirstFrag = (1 << 29), /* First segment of a packet */ ++ LastFrag = (1 << 28), /* Final segment of a packet */ ++ ++ /* Tx private */ ++ /*------ offset 0 of tx descriptor ------*/ ++ LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ ++ MSSShift = 16, /* MSS value position */ ++ MSSMask = 0x7ffU, /* MSS value + LargeSend bit: 12 bits */ ++ TxIPCS = (1 << 18), /* Calculate IP checksum */ ++ TxUDPCS = (1 << 17), /* Calculate UDP/IP checksum */ ++ TxTCPCS = (1 << 16), /* Calculate TCP/IP checksum */ ++ TxVlanTag = (1 << 17), /* Add VLAN tag */ ++ ++ /*@@@@@@ offset 4 of tx descriptor => bits for RTL8168C/CP only begin @@@@@@*/ ++ TxUDPCS_C = (1 << 31), /* Calculate UDP/IP checksum */ ++ TxTCPCS_C = (1 << 30), /* Calculate TCP/IP checksum */ ++ TxIPCS_C = (1 << 29), /* Calculate IP checksum */ ++ /*@@@@@@ offset 4 of tx descriptor => bits for RTL8168C/CP only end @@@@@@*/ ++ ++ ++ /* Rx private */ ++ /*------ offset 0 of rx descriptor ------*/ ++ PID1 = (1 << 18), /* Protocol ID bit 1/2 */ ++ PID0 = (1 << 17), /* Protocol ID bit 2/2 */ ++ ++#define RxProtoUDP (PID1) ++#define RxProtoTCP (PID0) ++#define RxProtoIP (PID1 | PID0) ++#define RxProtoMask RxProtoIP ++ ++ RxIPF = (1 << 16), /* IP checksum failed */ ++ RxUDPF = (1 << 15), /* UDP/IP checksum failed */ ++ RxTCPF = (1 << 14), /* TCP/IP checksum failed */ ++ RxVlanTag = (1 << 16), /* VLAN tag available */ ++ ++ /*@@@@@@ offset 0 of rx descriptor => bits for RTL8168C/CP only begin @@@@@@*/ ++ RxUDPT = (1 << 18), ++ RxTCPT = (1 << 17), ++ /*@@@@@@ offset 0 of rx descriptor => bits for RTL8168C/CP only end @@@@@@*/ ++ ++ /*@@@@@@ offset 4 of rx descriptor => bits for RTL8168C/CP only begin @@@@@@*/ ++ RxV6F = (1 << 31), ++ RxV4F = (1 << 30), ++ /*@@@@@@ offset 4 of rx descriptor => bits for RTL8168C/CP only end @@@@@@*/ ++}; ++ ++enum features { ++// RTL_FEATURE_WOL = (1 << 0), ++ RTL_FEATURE_MSI = (1 << 1), ++}; ++ ++enum wol_capability { ++ WOL_DISABLED = 0, ++ WOL_ENABLED = 1 ++}; ++ ++enum bits { ++ BIT_0 = (1 << 0), ++ BIT_1 = (1 << 1), ++ BIT_2 = (1 << 2), ++ BIT_3 = (1 << 3), ++ BIT_4 = (1 << 4), ++ BIT_5 = (1 << 5), ++ BIT_6 = (1 << 6), ++ BIT_7 = (1 << 7), ++ BIT_8 = (1 << 8), ++ BIT_9 = (1 << 9), ++ BIT_10 = (1 << 10), ++ BIT_11 = (1 << 11), ++ BIT_12 = (1 << 12), ++ BIT_13 = (1 << 13), ++ BIT_14 = (1 << 14), ++ BIT_15 = (1 << 15), ++ BIT_16 = (1 << 16), ++ BIT_17 = (1 << 17), ++ BIT_18 = (1 << 18), ++ BIT_19 = (1 << 19), ++ BIT_20 = (1 << 20), ++ BIT_21 = (1 << 21), ++ BIT_22 = (1 << 22), ++ BIT_23 = (1 << 23), ++ BIT_24 = (1 << 24), ++ BIT_25 = (1 << 25), ++ BIT_26 = (1 << 26), ++ BIT_27 = (1 << 27), ++ BIT_28 = (1 << 28), ++ BIT_29 = (1 << 29), ++ BIT_30 = (1 << 30), ++ BIT_31 = (1 << 31) ++}; ++ ++enum effuse { ++ EFUSE_SUPPORT = 1, ++ EFUSE_NOT_SUPPORT = 0, ++}; ++#define RsvdMask 0x3fffc000 ++ ++struct TxDesc { ++ u32 opts1; ++ u32 opts2; ++ u64 addr; ++}; ++ ++struct RxDesc { ++ u32 opts1; ++ u32 opts2; ++ u64 addr; ++}; ++ ++struct ring_info { ++ struct sk_buff *skb; ++ u32 len; ++ u8 __pad[sizeof(void *) - sizeof(u32)]; ++}; ++ ++struct pci_resource { ++ u8 cmd; ++ u8 cls; ++ u16 io_base_h; ++ u16 io_base_l; ++ u16 mem_base_h; ++ u16 mem_base_l; ++ u8 ilr; ++ u16 resv_0x20_h; ++ u16 resv_0x20_l; ++ u16 resv_0x24_h; ++ u16 resv_0x24_l; ++}; ++ ++struct rtl8168_private { ++ void __iomem *mmio_addr; /* memory map physical address */ ++ struct pci_dev *pci_dev; /* Index of PCI device */ ++ struct net_device *dev; ++#ifdef CONFIG_R8168_NAPI ++ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++ struct napi_struct napi; ++ #endif ++#endif ++ struct net_device_stats stats; /* statistics of net device */ ++ spinlock_t lock; /* spin lock flag */ ++ spinlock_t phy_lock; /* spin lock flag for GPHY */ ++ u32 msg_enable; ++ u32 tx_tcp_csum_cmd; ++ u32 tx_udp_csum_cmd; ++ u32 tx_ip_csum_cmd; ++ int max_jumbo_frame_size; ++ int chipset; ++ u32 mcfg; ++ u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ ++ u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ ++ u32 dirty_rx; ++ u32 dirty_tx; ++ struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ ++ struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ ++ dma_addr_t TxPhyAddr; ++ dma_addr_t RxPhyAddr; ++ struct sk_buff *Rx_skbuff[NUM_RX_DESC]; /* Rx data buffers */ ++ struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ ++ unsigned rx_buf_sz; ++ int rx_fifo_overflow; ++ struct timer_list esd_timer; ++ struct timer_list link_timer; ++ int old_link_status; ++ struct pci_resource pci_cfg_space; ++ unsigned int esd_flag; ++ unsigned int pci_cfg_is_read; ++ unsigned int rtl8168_rx_config; ++ u16 cp_cmd; ++ u16 intr_mask; ++ int phy_auto_nego_reg; ++ int phy_1000_ctrl_reg; ++ u8 org_mac_addr[NODE_ADDRESS_SIZE]; ++#ifdef CONFIG_R8168_VLAN ++ struct vlan_group *vlgrp; ++#endif ++ u8 wol_enabled; ++ u8 efuse; ++ u8 eeprom_type; ++ u8 autoneg; ++ u8 duplex; ++ u16 speed; ++ u16 eeprom_len; ++ ++ int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); ++ void (*get_settings)(struct net_device *, struct ethtool_cmd *); ++ void (*phy_reset_enable)(struct net_device *); ++ unsigned int (*phy_reset_pending)(struct net_device *); ++ unsigned int (*link_ok)(struct net_device *); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ++ struct work_struct task; ++#else ++ struct delayed_work task; ++#endif ++ unsigned features; ++}; ++ ++enum eetype { ++ EEPROM_TYPE_NONE=0, ++ EEPROM_TYPE_93C46, ++ EEPROM_TYPE_93C56, ++ EEPROM_TWSI ++}; ++ ++enum mcfg { ++ CFG_METHOD_1=0, ++ CFG_METHOD_2, ++ CFG_METHOD_3, ++ CFG_METHOD_4, ++ CFG_METHOD_5, ++ CFG_METHOD_6, ++ CFG_METHOD_7, ++ CFG_METHOD_8, ++ CFG_METHOD_9 , ++ CFG_METHOD_10, ++ CFG_METHOD_11, ++ CFG_METHOD_12, ++ CFG_METHOD_13, ++ CFG_METHOD_14, ++ CFG_METHOD_15, ++ CFG_METHOD_16, ++ CFG_METHOD_17, ++ CFG_METHOD_18, ++ CFG_METHOD_19, ++ CFG_METHOD_20, ++ CFG_METHOD_MAX, ++ CFG_METHOD_DEFAULT = 0xFF ++}; ++ ++#define OOB_CMD_RESET 0x00 ++#define OOB_CMD_DRIVER_START 0x05 ++#define OOB_CMD_DRIVER_STOP 0x06 ++#define OOB_CMD_SET_IPMAC 0x41 ++ ++extern void mdio_write(struct rtl8168_private *tp, u32 RegAddr, u32 value); ++extern void rtl8168_ephy_write(void __iomem *ioaddr, int RegAddr, int value); ++extern void OCP_write(struct rtl8168_private *tp, u8 mask, u16 Reg, u32 data); ++extern void OOB_notify(struct rtl8168_private *tp, u8 cmd); ++extern void rtl8168_init_ring_indexes(struct rtl8168_private *tp); ++extern int rtl8168_eri_write(void __iomem *ioaddr, int addr, int len, u32 value, int type); ++extern u32 mdio_read(struct rtl8168_private *tp, u32 RegAddr); ++extern u32 OCP_read(struct rtl8168_private *tp, u8 mask, u16 Reg); ++extern u32 rtl8168_eri_read(void __iomem *ioaddr, int addr, int len, int type); ++extern u16 rtl8168_ephy_read(void __iomem *ioaddr, int RegAddr); ++ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) ++#define netdev_mc_count(dev) ((dev)->mc_count) ++#define netdev_mc_empty(dev) (netdev_mc_count(dev) == 0) ++#define netdev_for_each_mc_addr(mclist, dev) \ ++ for (mclist = dev->mc_list; mclist; mclist = mclist->next) ++#endif +diff --git a/drivers/net/ethernet/realtek/r8168_asf.c b/drivers/net/ethernet/realtek/r8168_asf.c +new file mode 100644 +index 0000000..fb97edd +--- /dev/null ++++ b/drivers/net/ethernet/realtek/r8168_asf.c +@@ -0,0 +1,420 @@ ++/* ++################################################################################ ++# ++# r8168 is the Linux device driver released for RealTek RTL8168B/8111B, ++# RTL8168C/8111C, RTL8168CP/8111CP, RTL8168D/8111D, and RTL8168DP/8111DP, and ++# RTK8168E/8111E Gigabit Ethernet controllers with PCI-Express interface. ++# ++# Copyright(c) 2012 Realtek Semiconductor Corp. All rights reserved. ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the Free ++# Software Foundation; either version 2 of the License, or (at your option) ++# any later version. ++# ++# This program 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 ++# this program; if not, see . ++# ++# Author: ++# Realtek NIC software team ++# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan ++# ++################################################################################ ++*/ ++ ++/* ++ * This product is covered by one or more of the following patents: ++ * US5,307,459, US5,434,872, US5,732,094, US6,570,884, US6,115,776, and US6,327,625. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "r8168.h" ++#include "r8168_asf.h" ++#include "rtl_eeprom.h" ++ ++int rtl8168_asf_ioctl(struct net_device *dev, ++ struct ifreq *ifr) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ void *user_data = ifr->ifr_data; ++ struct asf_ioctl_struct asf_usrdata; ++ ++ if (tp->mcfg != CFG_METHOD_7 && tp->mcfg != CFG_METHOD_8) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&asf_usrdata, user_data, sizeof(struct asf_ioctl_struct))) ++ return -EFAULT; ++ ++ switch (asf_usrdata.offset) { ++ case HBPeriod: ++ rtl8168_asf_hbperiod(ioaddr, asf_usrdata.arg, asf_usrdata.u.data); ++ break; ++ case WD8Timer: ++ break; ++ case WD16Rst: ++ rtl8168_asf_wd16rst(ioaddr, asf_usrdata.arg, asf_usrdata.u.data); ++ break; ++ case WD8Rst: ++ rtl8168_asf_time_period(ioaddr, asf_usrdata.arg, WD8Rst, asf_usrdata.u.data); ++ break; ++ case LSnsrPollCycle: ++ rtl8168_asf_time_period(ioaddr, asf_usrdata.arg, LSnsrPollCycle, asf_usrdata.u.data); ++ break; ++ case ASFSnsrPollPrd: ++ rtl8168_asf_time_period(ioaddr, asf_usrdata.arg, ASFSnsrPollPrd, asf_usrdata.u.data); ++ break; ++ case AlertReSendItvl: ++ rtl8168_asf_time_period(ioaddr, asf_usrdata.arg, AlertReSendItvl, asf_usrdata.u.data); ++ break; ++ case SMBAddr: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, SMBAddr, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case ASFConfigR0: ++ rtl8168_asf_config_regs(ioaddr, asf_usrdata.arg, ASFConfigR0, asf_usrdata.u.data); ++ break; ++ case ASFConfigR1: ++ rtl8168_asf_config_regs(ioaddr, asf_usrdata.arg, ASFConfigR1, asf_usrdata.u.data); ++ break; ++ case ConsoleMA: ++ rtl8168_asf_console_mac(tp, asf_usrdata.arg, asf_usrdata.u.data); ++ break; ++ case ConsoleIP: ++ rtl8168_asf_ip_address(ioaddr, asf_usrdata.arg, ConsoleIP, asf_usrdata.u.data); ++ break; ++ case IPAddr: ++ rtl8168_asf_ip_address(tp, asf_usrdata.arg, IPAddr, asf_usrdata.u.data); ++ break; ++ case UUID: ++ rtl8168_asf_rw_uuid(ioaddr, asf_usrdata.arg, asf_usrdata.u.data); ++ break; ++ case IANA: ++ rtl8168_asf_rw_iana(ioaddr, asf_usrdata.arg, asf_usrdata.u.data); ++ break; ++ case SysID: ++ rtl8168_asf_rw_systemid(ioaddr, asf_usrdata.arg, asf_usrdata.u.data); ++ break; ++ case Community: ++ rtl8168_asf_community_string(ioaddr, asf_usrdata.arg, asf_usrdata.u.string); ++ break; ++ case StringLength: ++ rtl8168_asf_community_string_len(ioaddr, asf_usrdata.arg, asf_usrdata.u.data); ++ break; ++ case FmCapMsk: ++ rtl8168_asf_capability_masks(ioaddr, asf_usrdata.arg, FmCapMsk, asf_usrdata.u.data); ++ break; ++ case SpCMDMsk: ++ rtl8168_asf_capability_masks(ioaddr, asf_usrdata.arg, SpCMDMsk, asf_usrdata.u.data); ++ break; ++ case SysCapMsk: ++ rtl8168_asf_capability_masks(ioaddr, asf_usrdata.arg, SysCapMsk, asf_usrdata.u.data); ++ break; ++ case RmtRstAddr: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtRstAddr, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case RmtRstCmd: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtRstCmd, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case RmtRstData: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtRstData, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case RmtPwrOffAddr: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtPwrOffAddr, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case RmtPwrOffCmd: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtPwrOffCmd, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case RmtPwrOffData: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtPwrOffData, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case RmtPwrOnAddr: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtPwrOnAddr, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case RmtPwrOnCmd: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtPwrOnCmd, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case RmtPwrOnData: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtPwrOnData, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case RmtPCRAddr: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtPCRAddr, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case RmtPCRCmd: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtPCRCmd, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case RmtPCRData: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, RmtPCRData, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case ASFSnsr0Addr: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, ASFSnsr0Addr, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case LSnsrAddr0: ++ rtl8168_asf_rw_hexadecimal(ioaddr, asf_usrdata.arg, LSnsrAddr0, RW_ONE_BYTE, asf_usrdata.u.data); ++ break; ++ case KO: ++ /* Get/Set Key Operation */ ++ rtl8168_asf_key_access(ioaddr, asf_usrdata.arg, KO, asf_usrdata.u.data); ++ break; ++ case KA: ++ /* Get/Set Key Administrator */ ++ rtl8168_asf_key_access(ioaddr, asf_usrdata.arg, KA, asf_usrdata.u.data); ++ break; ++ case KG: ++ /* Get/Set Key Generation */ ++ rtl8168_asf_key_access(ioaddr, asf_usrdata.arg, KG, asf_usrdata.u.data); ++ break; ++ case KR: ++ /* Get/Set Key Random */ ++ rtl8168_asf_key_access(tp, asf_usrdata.arg, KR, asf_usrdata.u.data); ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ if (copy_to_user(user_data, &asf_usrdata, sizeof(struct asf_ioctl_struct))) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++void rtl8168_asf_hbperiod(void __iomem *ioaddr, int arg, unsigned int *data) ++{ ++ if (arg == ASF_GET) ++ data[ASFHBPERIOD] = rtl8168_eri_read(ioaddr, HBPeriod, RW_TWO_BYTES, ERIAR_ASF); ++ else if (arg == ASF_SET) { ++ rtl8168_eri_write(ioaddr, HBPeriod, RW_TWO_BYTES, data[ASFHBPERIOD], ERIAR_ASF); ++ rtl8168_eri_write(ioaddr, 0x1EC, RW_ONE_BYTE, 0x07, ERIAR_ASF); ++ } ++} ++ ++void rtl8168_asf_wd16rst(void __iomem *ioaddr, int arg, unsigned int *data) ++{ ++ data[ASFWD16RST] = rtl8168_eri_read(ioaddr, WD16Rst, RW_TWO_BYTES, ERIAR_ASF); ++} ++ ++void rtl8168_asf_console_mac(struct rtl8168_private *tp, int arg, unsigned int *data) ++{ ++ void __iomem *ioaddr=tp->mmio_addr; ++ int i; ++ ++ if (arg == ASF_GET) { ++ for (i = 0; i < 6; i++) ++ data[i] = rtl8168_eri_read(ioaddr, ConsoleMA + i, RW_ONE_BYTE, ERIAR_ASF); ++ } else if (arg == ASF_SET) { ++ for (i = 0; i < 6; i++) ++ rtl8168_eri_write(ioaddr, ConsoleMA + i, RW_ONE_BYTE, data[i], ERIAR_ASF); ++ ++ /* write the new console MAC address to EEPROM */ ++ rtl_eeprom_write_sc(tp, 70, (data[1] << 8) | data[0]); ++ rtl_eeprom_write_sc(tp, 71, (data[3] << 8) | data[2]); ++ rtl_eeprom_write_sc(tp, 72, (data[5] << 8) | data[4]); ++ } ++} ++ ++void rtl8168_asf_ip_address(struct rtl8168_private *tp, int arg, int offset, unsigned int *data) ++{ ++ void __iomem *ioaddr=tp->mmio_addr; ++ int i; ++ int eeprom_off = 0; ++ ++ if (arg == ASF_GET) { ++ for (i = 0; i < 4; i++) ++ data[i] = rtl8168_eri_read(ioaddr, offset + i, RW_ONE_BYTE, ERIAR_ASF); ++ } else if (arg == ASF_SET) { ++ for (i = 0; i < 4; i++) ++ rtl8168_eri_write(ioaddr, offset + i, RW_ONE_BYTE, data[i], ERIAR_ASF); ++ ++ if (offset == ConsoleIP) ++ eeprom_off = 73; ++ else if (offset == IPAddr) ++ eeprom_off = 75; ++ ++ /* write the new IP address to EEPROM */ ++ rtl_eeprom_write_sc(tp, eeprom_off, (data[1] << 8) | data[0]); ++ rtl_eeprom_write_sc(tp, eeprom_off + 1, (data[3] << 8) | data[2]); ++ ++ } ++} ++ ++void rtl8168_asf_config_regs(void __iomem *ioaddr, int arg, int offset, unsigned int *data) ++{ ++ unsigned int value; ++ ++ if (arg == ASF_GET) { ++ data[ASFCAPABILITY] = (rtl8168_eri_read(ioaddr, offset, RW_ONE_BYTE, ERIAR_ASF) & data[ASFCONFIG]) ? FUNCTION_ENABLE : FUNCTION_DISABLE; ++ } else if (arg == ASF_SET) { ++ value = rtl8168_eri_read(ioaddr, offset, RW_ONE_BYTE, ERIAR_ASF); ++ ++ if (data[ASFCAPABILITY] == FUNCTION_ENABLE) ++ value |= data[ASFCONFIG]; ++ else if (data[ASFCAPABILITY] == FUNCTION_DISABLE) ++ value &= ~data[ASFCONFIG]; ++ ++ rtl8168_eri_write(ioaddr, offset, RW_ONE_BYTE, value, ERIAR_ASF); ++ } ++} ++ ++void rtl8168_asf_capability_masks(void __iomem *ioaddr, int arg, int offset, unsigned int *data) ++{ ++ unsigned int len, bit_mask; ++ ++ bit_mask = DISABLE_MASK; ++ ++ if (offset == FmCapMsk) { ++ /* System firmware capabilities */ ++ len = RW_FOUR_BYTES; ++ if (data[ASFCAPMASK] == FUNCTION_ENABLE) ++ bit_mask = FMW_CAP_MASK; ++ } else if (offset == SpCMDMsk) { ++ /* Special commands */ ++ len = RW_TWO_BYTES; ++ if (data[ASFCAPMASK] == FUNCTION_ENABLE) ++ bit_mask = SPC_CMD_MASK; ++ } else { ++ /* System capability (offset == SysCapMsk)*/ ++ len = RW_ONE_BYTE; ++ if (data[ASFCAPMASK] == FUNCTION_ENABLE) ++ bit_mask = SYS_CAP_MASK; ++ } ++ ++ if (arg == ASF_GET) ++ data[ASFCAPMASK] = rtl8168_eri_read(ioaddr, offset, len, ERIAR_ASF) ? FUNCTION_ENABLE : FUNCTION_DISABLE; ++ else /* arg == ASF_SET */ ++ rtl8168_eri_write(ioaddr, offset, len, bit_mask, ERIAR_ASF); ++} ++ ++void rtl8168_asf_community_string(void __iomem *ioaddr, int arg, char *string) ++{ ++ int i; ++ ++ if (arg == ASF_GET) { ++ for (i = 0; i < COMMU_STR_MAX_LEN; i++) ++ string[i] = rtl8168_eri_read(ioaddr, Community + i, RW_ONE_BYTE, ERIAR_ASF); ++ } else { /* arg == ASF_SET */ ++ for (i = 0; i < COMMU_STR_MAX_LEN; i++) ++ rtl8168_eri_write(ioaddr, Community + i, RW_ONE_BYTE, string[i], ERIAR_ASF); ++ } ++} ++ ++void rtl8168_asf_community_string_len(void __iomem *ioaddr, int arg, unsigned int *data) ++{ ++ if (arg == ASF_GET) ++ data[ASFCOMMULEN] = rtl8168_eri_read(ioaddr, StringLength, RW_ONE_BYTE, ERIAR_ASF); ++ else /* arg == ASF_SET */ ++ rtl8168_eri_write(ioaddr, StringLength, RW_ONE_BYTE, data[ASFCOMMULEN], ERIAR_ASF); ++} ++ ++void rtl8168_asf_time_period(void __iomem *ioaddr, int arg, int offset, unsigned int *data) ++{ ++ int pos = 0; ++ ++ if (offset == WD8Rst) ++ pos = ASFWD8RESET; ++ else if (offset == LSnsrPollCycle) ++ pos = ASFLSNRPOLLCYC; ++ else if (offset == ASFSnsrPollPrd) ++ pos = ASFSNRPOLLCYC; ++ else if (offset == AlertReSendItvl) ++ pos = ASFALERTRESND; ++ ++ if (arg == ASF_GET) ++ data[pos] = rtl8168_eri_read(ioaddr, offset, RW_ONE_BYTE, ERIAR_ASF); ++ else /* arg == ASF_SET */ ++ rtl8168_eri_write(ioaddr, offset, RW_ONE_BYTE, data[pos], ERIAR_ASF); ++ ++} ++ ++void rtl8168_asf_key_access(struct rtl8168_private *tp, int arg, int offset, unsigned int *data) ++{ ++ void __iomem *ioaddr=tp->mmio_addr; ++ int i, j; ++ int key_off = 0; ++ ++ if (arg == ASF_GET) { ++ for (i = 0; i < KEY_LEN; i++) ++ data[i] = rtl8168_eri_read(ioaddr, offset + KEY_LEN - (i + 1), RW_ONE_BYTE, ERIAR_ASF); ++ } else { ++ if (offset == KO) ++ key_off = 162; ++ else if (offset == KA) ++ key_off = 172; ++ else if (offset == KG) ++ key_off = 182; ++ else if (offset == KR) ++ key_off = 192; ++ ++ /* arg == ASF_SET */ ++ for (i = 0; i < KEY_LEN; i++) ++ rtl8168_eri_write(ioaddr, offset + KEY_LEN - (i + 1), RW_ONE_BYTE, data[i], ERIAR_ASF); ++ ++ /* write the new key to EEPROM */ ++ for (i = 0, j = 19; i < 10; i++, j = j - 2) ++ rtl_eeprom_write_sc(tp, key_off + i, (data[j - 1] << 8) | data[j]); ++ } ++} ++ ++void rtl8168_asf_rw_hexadecimal(void __iomem *ioaddr, int arg, int offset, int len, unsigned int *data) ++{ ++ if (arg == ASF_GET) ++ data[ASFRWHEXNUM] = rtl8168_eri_read(ioaddr, offset, len, ERIAR_ASF); ++ else /* arg == ASF_SET */ ++ rtl8168_eri_write(ioaddr, offset, len, data[ASFRWHEXNUM], ERIAR_ASF); ++} ++ ++void rtl8168_asf_rw_systemid(void __iomem *ioaddr, int arg, unsigned int *data) ++{ ++ int i; ++ ++ if (arg == ASF_GET) ++ for (i = 0; i < SYSID_LEN ; i++) ++ data[i] = rtl8168_eri_read(ioaddr, SysID + i, RW_ONE_BYTE, ERIAR_ASF); ++ else /* arg == ASF_SET */ ++ for (i = 0; i < SYSID_LEN ; i++) ++ rtl8168_eri_write(ioaddr, SysID + i, RW_ONE_BYTE, data[i], ERIAR_ASF); ++} ++ ++void rtl8168_asf_rw_iana(void __iomem *ioaddr, int arg, unsigned int *data) ++{ ++ int i; ++ ++ if (arg == ASF_GET) ++ for (i = 0; i < RW_FOUR_BYTES; i++) ++ data[i] = rtl8168_eri_read(ioaddr, IANA + i, RW_ONE_BYTE, ERIAR_ASF); ++ else /* arg == ASF_SET */ ++ for (i = 0; i < RW_FOUR_BYTES; i++) ++ rtl8168_eri_write(ioaddr, IANA + i, RW_ONE_BYTE, data[i], ERIAR_ASF); ++} ++ ++void rtl8168_asf_rw_uuid(void __iomem *ioaddr, int arg, unsigned int *data) ++{ ++ int i, j; ++ ++ if (arg == ASF_GET) ++ for (i = UUID_LEN - 1, j = 0; i >= 0 ; i--, j++) ++ data[j] = rtl8168_eri_read(ioaddr, UUID + i, RW_ONE_BYTE, ERIAR_ASF); ++ else /* arg == ASF_SET */ ++ for (i = UUID_LEN - 1, j = 0; i >= 0 ; i--, j++) ++ rtl8168_eri_write(ioaddr, UUID + i, RW_ONE_BYTE, data[j], ERIAR_ASF); ++} +diff --git a/drivers/net/ethernet/realtek/r8168_asf.h b/drivers/net/ethernet/realtek/r8168_asf.h +new file mode 100644 +index 0000000..3556c26 +--- /dev/null ++++ b/drivers/net/ethernet/realtek/r8168_asf.h +@@ -0,0 +1,295 @@ ++/* ++################################################################################ ++# ++# r8168 is the Linux device driver released for RealTek RTL8168B/8111B, ++# RTL8168C/8111C, RTL8168CP/8111CP, RTL8168D/8111D, and RTL8168DP/8111DP, and ++# RTK8168E/8111E Gigabit Ethernet controllers with PCI-Express interface. ++# ++# Copyright(c) 2012 Realtek Semiconductor Corp. All rights reserved. ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the Free ++# Software Foundation; either version 2 of the License, or (at your option) ++# any later version. ++# ++# This program 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 ++# this program; if not, see . ++# ++# Author: ++# Realtek NIC software team ++# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan ++# ++################################################################################ ++*/ ++ ++/************************************************************************************ ++ * This product is covered by one or more of the following patents: ++ * US5,307,459, US5,434,872, US5,732,094, US6,570,884, US6,115,776, and US6,327,625. ++ ***********************************************************************************/ ++ ++#define SIOCDEVPRIVATE_RTLASF SIOCDEVPRIVATE ++ ++#define FUNCTION_ENABLE 1 ++#define FUNCTION_DISABLE 0 ++ ++#define ASFCONFIG 0 ++#define ASFCAPABILITY 1 ++#define ASFCOMMULEN 0 ++#define ASFHBPERIOD 0 ++#define ASFWD16RST 0 ++#define ASFCAPMASK 0 ++#define ASFALERTRESND 0 ++#define ASFLSNRPOLLCYC 0 ++#define ASFSNRPOLLCYC 0 ++#define ASFWD8RESET 0 ++#define ASFRWHEXNUM 0 ++ ++#define FMW_CAP_MASK 0x0000F867 ++#define SPC_CMD_MASK 0x1F00 ++#define SYS_CAP_MASK 0xFF ++#define DISABLE_MASK 0x00 ++ ++#define MAX_DATA_LEN 200 ++#define MAX_STR_LEN 200 ++ ++#define COMMU_STR_MAX_LEN 23 ++ ++#define KEY_LEN 20 ++#define UUID_LEN 16 ++#define SYSID_LEN 2 ++ ++#define RW_ONE_BYTE 1 ++#define RW_TWO_BYTES 2 ++#define RW_FOUR_BYTES 4 ++ ++enum asf_registers { ++ HBPeriod = 0x0000, ++ WD8Rst = 0x0002, ++ WD8Timer = 0x0003, ++ WD16Rst = 0x0004, ++ LSnsrPollCycle = 0x0006, ++ ASFSnsrPollPrd = 0x0007, ++ AlertReSendCnt = 0x0008, ++ AlertReSendItvl = 0x0009, ++ SMBAddr = 0x000A, ++ SMBCap = 0x000B, ++ ASFConfigR0 = 0x000C, ++ ASFConfigR1 = 0x000D, ++ WD16Timer = 0x000E, ++ ConsoleMA = 0x0010, ++ ConsoleIP = 0x0016, ++ IPAddr = 0x001A, ++ ++ UUID = 0x0020, ++ IANA = 0x0030, ++ SysID = 0x0034, ++ Community = 0x0036, ++ StringLength = 0x004D, ++ LC = 0x004E, ++ EntityInst = 0x004F, ++ FmCapMsk = 0x0050, ++ SpCMDMsk = 0x0054, ++ SysCapMsk = 0x0056, ++ WDSysSt = 0x0057, ++ RxMsgType = 0x0058, ++ RxSpCMD = 0x0059, ++ RxSpCMDPa = 0x005A, ++ RxBtOpMsk = 0x005C, ++ RmtRstAddr = 0x005E, ++ RmtRstCmd = 0x005F, ++ RmtRstData = 0x0060, ++ RmtPwrOffAddr = 0x0061, ++ RmtPwrOffCmd = 0x0062, ++ RmtPwrOffData = 0x0063, ++ RmtPwrOnAddr = 0x0064, ++ RmtPwrOnCmd = 0x0065, ++ RmtPwrOnData = 0x0066, ++ RmtPCRAddr = 0x0067, ++ RmtPCRCmd = 0x0068, ++ RmtPCRData = 0x0069, ++ RMCP_IANA = 0x006A, ++ RMCP_OEM = 0x006E, ++ ASFSnsr0Addr = 0x0070, ++ ++ ASFSnsrEvSt = 0x0073, ++ ASFSnsrEvAlert = 0x0081, ++ ++ LSnsrNo = 0x00AD, ++ AssrtEvntMsk = 0x00AE, ++ DeAssrtEvntMsk = 0x00AF, ++ ++ LSnsrAddr0 = 0x00B0, ++ LAlertCMD0 = 0x00B1, ++ LAlertDataMsk0 = 0x00B2, ++ LAlertCmp0 = 0x00B3, ++ LAlertESnsrT0 = 0x00B4, ++ LAlertET0 = 0x00B5, ++ LAlertEOffset0 = 0x00B6, ++ LAlertES0 = 0x00B7, ++ LAlertSN0 = 0x00B8, ++ LAlertEntity0 = 0x00B9, ++ LAlertEI0 = 0x00BA, ++ LSnsrState0 = 0x00BB, ++ ++ LSnsrAddr1 = 0x00BD, ++ LAlertCMD1 = 0x00BE, ++ LAlertDataMsk1 = 0x00BF, ++ LAlertCmp1 = 0x00C0, ++ LAlertESnsrT1 = 0x00C1, ++ LAlertET1 = 0x00C2, ++ LAlertEOffset1 = 0x00C3, ++ LAlertES1 = 0x00C4, ++ LAlertSN1 = 0x00C5, ++ LAlertEntity1 = 0x00C6, ++ LAlertEI1 = 0x00C7, ++ LSnsrState1 = 0x00C8, ++ ++ LSnsrAddr2 = 0x00CA, ++ LAlertCMD2 = 0x00CB, ++ LAlertDataMsk2 = 0x00CC, ++ LAlertCmp2 = 0x00CD, ++ LAlertESnsrT2 = 0x00CE, ++ LAlertET2 = 0x00CF, ++ LAlertEOffset2 = 0x00D0, ++ LAlertES2 = 0x00D1, ++ LAlertSN2 = 0x00D2, ++ LAlertEntity2 = 0x00D3, ++ LAlertEI2 = 0x00D4, ++ LSnsrState2 = 0x00D5, ++ ++ LSnsrAddr3 = 0x00D7, ++ LAlertCMD3 = 0x00D8, ++ LAlertDataMsk3 = 0x00D9, ++ LAlertCmp3 = 0x00DA, ++ LAlertESnsrT3 = 0x00DB, ++ LAlertET3 = 0x00DC, ++ LAlertEOffset3 = 0x00DD, ++ LAlertES3 = 0x00DE, ++ LAlertSN3 = 0x00DF, ++ LAlertEntity3 = 0x00E0, ++ LAlertEI3 = 0x00E1, ++ LSnsrState3 = 0x00E2, ++ ++ LSnsrAddr4 = 0x00E4, ++ LAlertCMD4 = 0x00E5, ++ LAlertDataMsk4 = 0x00E6, ++ LAlertCmp4 = 0x00E7, ++ LAlertESnsrT4 = 0x00E8, ++ LAlertET4 = 0x00E9, ++ LAlertEOffset4 = 0x00EA, ++ LAlertES4 = 0x00EB, ++ LAlertSN4 = 0x00EC, ++ LAlertEntity4 = 0x00ED, ++ LAlertEI4 = 0x00EE, ++ LSnsrState4 = 0x00EF, ++ ++ LSnsrAddr5 = 0x00F1, ++ LAlertCMD5 = 0x00F2, ++ LAlertDataMsk5 = 0x00F3, ++ LAlertCmp5 = 0x00F4, ++ LAlertESnsrT5 = 0x00F5, ++ LAlertET5 = 0x00F6, ++ LAlertEOffset5 = 0x00F7, ++ LAlertES5 = 0x00F8, ++ LAlertSN5 = 0x00F9, ++ LAlertEntity5 = 0x00FA, ++ LAlertEI5 = 0x00FB, ++ LSnsrState5 = 0x00FC, ++ ++ LSnsrAddr6 = 0x00FE, ++ LAlertCMD6 = 0x00FF, ++ LAlertDataMsk6 = 0x0100, ++ LAlertCmp6 = 0x0101, ++ LAlertESnsrT6 = 0x0102, ++ LAlertET6 = 0x0103, ++ LAlertEOffset6 = 0x0104, ++ LAlertES6 = 0x0105, ++ LAlertSN6 = 0x0106, ++ LAlertEntity6 = 0x0107, ++ LAlertEI6 = 0x0108, ++ LSnsrState6 = 0x0109, ++ ++ LSnsrAddr7 = 0x010B, ++ LAlertCMD7 = 0x010C, ++ LAlertDataMsk7 = 0x010D, ++ LAlertCmp7 = 0x010E, ++ LAlertESnsrT7 = 0x010F, ++ LAlertET7 = 0x0110, ++ LAlertEOffset7 = 0x0111, ++ LAlertES7 = 0x0112, ++ LAlertSN7 = 0x0113, ++ LAlertEntity7 = 0x0114, ++ LAlertEI7 = 0x0115, ++ LSnsrState7 = 0x0116, ++ LAssert = 0x0117, ++ LDAssert = 0x0118, ++ IPServiceType = 0x0119, ++ IPIdfr = 0x011A, ++ FlagFOffset = 0x011C, ++ TTL = 0x011E, ++ HbtEI = 0x011F, ++ MgtConSID1 = 0x0120, ++ MgtConSID2 = 0x0124, ++ MgdCltSID = 0x0128, ++ StCd = 0x012C, ++ MgtConUR = 0x012D, ++ MgtConUNL = 0x012E, ++ ++ AuthPd = 0x0130, ++ IntyPd = 0x0138, ++ MgtConRN = 0x0140, ++ MgdCtlRN = 0x0150, ++ MgtConUN = 0x0160, ++ Rakp2IntCk = 0x0170, ++ KO = 0x017C, ++ KA = 0x0190, ++ KG = 0x01A4, ++ KR = 0x01B8, ++ CP = 0x01CC, ++ CQ = 0x01D0, ++ KC = 0x01D4, ++ ConsoleSid = 0x01E8, ++ ++ SIK1 = 0x01FC, ++ SIK2 = 0x0210, ++ Udpsrc_port = 0x0224, ++ Udpdes_port = 0x0226, ++ Asf_debug_mux = 0x0228 ++}; ++ ++enum asf_cmdln_opt { ++ ASF_GET, ++ ASF_SET, ++ ASF_HELP ++}; ++ ++struct asf_ioctl_struct { ++ unsigned int arg; ++ unsigned int offset; ++ union { ++ unsigned int data[MAX_DATA_LEN]; ++ char string[MAX_STR_LEN]; ++ } u; ++}; ++ ++int rtl8168_asf_ioctl(struct net_device *dev, struct ifreq *ifr); ++void rtl8168_asf_hbperiod(void __iomem *ioaddr, int arg, unsigned int *data); ++void rtl8168_asf_wd16rst(void __iomem *ioaddr, int arg, unsigned int *data); ++void rtl8168_asf_console_mac(struct rtl8168_private *, int arg, unsigned int *data); ++void rtl8168_asf_ip_address(struct rtl8168_private *, int arg, int offset, unsigned int *data); ++void rtl8168_asf_config_regs(void __iomem *ioaddr, int arg, int offset, unsigned int *data); ++void rtl8168_asf_capability_masks(void __iomem *ioaddr, int arg, int offset, unsigned int *data); ++void rtl8168_asf_community_string(void __iomem *ioaddr, int arg, char *string); ++void rtl8168_asf_community_string_len(void __iomem *ioaddr, int arg, unsigned int *data); ++void rtl8168_asf_alert_resend_interval(void __iomem *ioaddr, int arg, unsigned int *data); ++void rtl8168_asf_time_period(void __iomem *ioaddr, int arg, int offset, unsigned int *data); ++void rtl8168_asf_key_access(struct rtl8168_private *, int arg, int offset, unsigned int *data); ++void rtl8168_asf_rw_hexadecimal(void __iomem *ioaddr, int arg, int offset, int len, unsigned int *data); ++void rtl8168_asf_rw_iana(void __iomem *ioaddr, int arg, unsigned int *data); ++void rtl8168_asf_rw_uuid(void __iomem *ioaddr, int arg, unsigned int *data); ++void rtl8168_asf_rw_systemid(void __iomem *ioaddr, int arg, unsigned int *data); +diff --git a/drivers/net/ethernet/realtek/r8168_n.c b/drivers/net/ethernet/realtek/r8168_n.c +new file mode 100644 +index 0000000..ef297ce +--- /dev/null ++++ b/drivers/net/ethernet/realtek/r8168_n.c +@@ -0,0 +1,15369 @@ ++/* ++################################################################################ ++# ++# r8168 is the Linux device driver released for RealTek RTL8168B/8111B, ++# RTL8168C/8111C, RTL8168CP/8111CP, RTL8168D/8111D, RTL8168DP/8111DP, and ++# RTL8168E/8111E Gigabit Ethernet controllers with PCI-Express interface. ++# ++# Copyright(c) 2012 Realtek Semiconductor Corp. All rights reserved. ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the Free ++# Software Foundation; either version 2 of the License, or (at your option) ++# any later version. ++# ++# This program 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 ++# this program; if not, see . ++# ++# Author: ++# Realtek NIC software team ++# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan ++# ++################################################################################ ++*/ ++ ++/* ++ * This product is covered by one or more of the following patents: ++ * US5,307,459, US5,434,872, US5,732,094, US6,570,884, US6,115,776, and US6,327,625. ++ */ ++ ++/* ++ * This driver is modified from r8169.c in Linux kernel 2.6.18 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ++#define dev_printk(A,B,fmt,args...) printk(A fmt,##args) ++#else ++#include ++#include ++#endif ++ ++#include ++#include ++#include ++ ++#include "r8168.h" ++#include "r8168_asf.h" ++#include "rtl_eeprom.h" ++#include "rtltool.h" ++ ++static int eee_enable = 0 ; ++module_param(eee_enable, int, S_IRUGO); ++ ++#ifdef CONFIG_DOWN_SPEED_100 ++static int config_down_speed_100 = 1; ++#else ++static int config_down_speed_100 = 0; ++#endif ++ ++/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ ++static const int max_interrupt_work = 20; ++ ++/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). ++ The RTL chips use a 64 element hash table based on the Ethernet CRC. */ ++static const int multicast_filter_limit = 32; ++ ++#define _R(NAME,MAC,RCR,MASK, JumFrameSz) \ ++ { .name = NAME, .mcfg = MAC, .RCR_Cfg = RCR, .RxConfigMask = MASK, .jumbo_frame_sz = JumFrameSz } ++ ++static const struct { ++ const char *name; ++ u8 mcfg; ++ u32 RCR_Cfg; ++ u32 RxConfigMask; /* Clears the bits supported by this chip */ ++ u32 jumbo_frame_sz; ++} rtl_chip_info[] = { ++ _R("RTL8168B/8111B", ++ CFG_METHOD_1, ++ (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_4k), ++ ++ _R("RTL8168B/8111B", ++ CFG_METHOD_2, ++ (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_4k), ++ ++ _R("RTL8168B/8111B", ++ CFG_METHOD_3, ++ (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_4k), ++ ++ _R("RTL8168C/8111C", ++ CFG_METHOD_4, RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_6k), ++ ++ _R("RTL8168C/8111C", ++ CFG_METHOD_5, ++ RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_6k), ++ ++ _R("RTL8168C/8111C", ++ CFG_METHOD_6, ++ RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_6k), ++ ++ _R("RTL8168CP/8111CP", ++ CFG_METHOD_7, ++ RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_6k), ++ ++ _R("RTL8168CP/8111CP", ++ CFG_METHOD_8, ++ RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_6k), ++ ++ _R("RTL8168D/8111D", ++ CFG_METHOD_9, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_9k), ++ ++ _R("RTL8168D/8111D", ++ CFG_METHOD_10, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_9k), ++ ++ _R("RTL8168DP/8111DP", ++ CFG_METHOD_11, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_9k), ++ ++ _R("RTL8168DP/8111DP", ++ CFG_METHOD_12, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_9k), ++ ++ _R("RTL8168DP/8111DP", ++ CFG_METHOD_13, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_9k), ++ ++ _R("RTL8168E/8111E", ++ CFG_METHOD_14, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_9k), ++ ++ _R("RTL8168E/8111E", ++ CFG_METHOD_15, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_9k), ++ ++ _R("RTL8168E-VL/8111E-VL", ++ CFG_METHOD_16, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e0080, ++ Jumbo_Frame_9k), ++ ++ _R("RTL8168E-VL/8111E-VL", ++ CFG_METHOD_17, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_9k), ++ ++ _R("RTL8168F/8111F", ++ CFG_METHOD_18, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_9k), ++ ++ _R("RTL8168F/8111F", ++ CFG_METHOD_19, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_9k), ++ ++ _R("RTL8411", ++ CFG_METHOD_20, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ Jumbo_Frame_9k), ++ ++ _R("Unknown", ++ CFG_METHOD_DEFAULT, ++ RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift), ++ 0xff7e1880, ++ RX_BUF_SIZE) ++}; ++#undef _R ++ ++#ifndef PCI_VENDOR_ID_DLINK ++#define PCI_VENDOR_ID_DLINK 0x1186 ++#endif ++ ++static struct pci_device_id rtl8168_pci_tbl[] = { ++ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), }, ++ { PCI_VENDOR_ID_DLINK, 0x4300, 0x1186, 0x4b10,}, ++ {0,}, ++}; ++ ++MODULE_DEVICE_TABLE(pci, rtl8168_pci_tbl); ++ ++static int rx_copybreak = 200; ++static int use_dac; ++static struct { ++ u32 msg_enable; ++} debug = { -1 }; ++ ++/* media options */ ++#define MAX_UNITS 8 ++static int speed[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; ++static int duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; ++static int autoneg[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; ++ ++MODULE_AUTHOR("Realtek and the Linux r8168 crew "); ++MODULE_DESCRIPTION("RealTek RTL-8168 Gigabit Ethernet driver"); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) ++MODULE_PARM(speed, "1-" __MODULE_STRING(MAX_UNITS) "i"); ++MODULE_PARM(duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); ++MODULE_PARM(autoneg, "1-" __MODULE_STRING(MAX_UNITS) "i"); ++#else ++static int num_speed = 0; ++static int num_duplex = 0; ++static int num_autoneg = 0; ++ ++module_param_array(speed, int, &num_speed, 0); ++module_param_array(duplex, int, &num_duplex, 0); ++module_param_array(autoneg, int, &num_autoneg, 0); ++#endif ++ ++MODULE_PARM_DESC(speed, "force phy operation. Deprecated by ethtool (8)."); ++MODULE_PARM_DESC(duplex, "force phy operation. Deprecated by ethtool (8)."); ++MODULE_PARM_DESC(autoneg, "force phy operation. Deprecated by ethtool (8)."); ++ ++module_param(rx_copybreak, int, 0); ++MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); ++module_param(use_dac, int, 0); ++MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++module_param_named(debug, debug.msg_enable, int, 0); ++MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); ++#endif//LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ ++MODULE_LICENSE("GPL"); ++ ++MODULE_VERSION(RTL8168_VERSION); ++ ++static void rtl8168_sleep_rx_enable(struct net_device *dev); ++static void rtl8168_dsm(struct net_device *dev, int dev_state); ++ ++static void rtl8168_esd_timer(unsigned long __opaque); ++static void rtl8168_link_timer(unsigned long __opaque); ++static void rtl8168_tx_clear(struct rtl8168_private *tp); ++static void rtl8168_rx_clear(struct rtl8168_private *tp); ++ ++static int rtl8168_open(struct net_device *dev); ++static int rtl8168_start_xmit(struct sk_buff *skb, struct net_device *dev); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) ++static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance, struct pt_regs *regs); ++#else ++static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance); ++#endif ++static void rtl8168_rx_desc_offset0_init(struct rtl8168_private *, int); ++static int rtl8168_init_ring(struct net_device *dev); ++static void rtl8168_hw_start(struct net_device *dev); ++static int rtl8168_close(struct net_device *dev); ++static void rtl8168_set_rx_mode(struct net_device *dev); ++static void rtl8168_tx_timeout(struct net_device *dev); ++static struct net_device_stats *rtl8168_get_stats(struct net_device *dev); ++static int rtl8168_rx_interrupt(struct net_device *, struct rtl8168_private *, void __iomem *, u32 budget); ++static int rtl8168_change_mtu(struct net_device *dev, int new_mtu); ++static void rtl8168_down(struct net_device *dev); ++ ++static int rtl8168_set_mac_address(struct net_device *dev, void *p); ++void rtl8168_rar_set(struct rtl8168_private *tp, uint8_t *addr); ++static void rtl8168_tx_desc_init(struct rtl8168_private *tp); ++static void rtl8168_rx_desc_init(struct rtl8168_private *tp); ++ ++static void rtl8168_nic_reset(struct net_device *dev); ++ ++static void rtl8168_phy_power_up (struct net_device *dev); ++static void rtl8168_phy_power_down (struct net_device *dev); ++static int rtl8168_set_speed(struct net_device *dev, u8 autoneg, u16 speed, u8 duplex); ++ ++#ifdef CONFIG_R8168_NAPI ++static int rtl8168_poll(napi_ptr napi, napi_budget budget); ++#endif ++ ++static u16 rtl8168_intr_mask = SYSErr | LinkChg | RxDescUnavail | TxErr | TxOK | RxErr | RxOK; ++static const u16 rtl8168_napi_event = ++ RxOK | RxDescUnavail | RxFIFOOver | TxOK | TxErr; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ++#undef ethtool_ops ++#define ethtool_ops _kc_ethtool_ops ++ ++struct _kc_ethtool_ops { ++ int (*get_settings)(struct net_device *, struct ethtool_cmd *); ++ int (*set_settings)(struct net_device *, struct ethtool_cmd *); ++ void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); ++ int (*get_regs_len)(struct net_device *); ++ void (*get_regs)(struct net_device *, struct ethtool_regs *, void *); ++ void (*get_wol)(struct net_device *, struct ethtool_wolinfo *); ++ int (*set_wol)(struct net_device *, struct ethtool_wolinfo *); ++ u32 (*get_msglevel)(struct net_device *); ++ void (*set_msglevel)(struct net_device *, u32); ++ int (*nway_reset)(struct net_device *); ++ u32 (*get_link)(struct net_device *); ++ int (*get_eeprom_len)(struct net_device *); ++ int (*get_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *); ++ int (*set_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *); ++ int (*get_coalesce)(struct net_device *, struct ethtool_coalesce *); ++ int (*set_coalesce)(struct net_device *, struct ethtool_coalesce *); ++ void (*get_ringparam)(struct net_device *, struct ethtool_ringparam *); ++ int (*set_ringparam)(struct net_device *, struct ethtool_ringparam *); ++ void (*get_pauseparam)(struct net_device *, ++ struct ethtool_pauseparam*); ++ int (*set_pauseparam)(struct net_device *, ++ struct ethtool_pauseparam*); ++ u32 (*get_rx_csum)(struct net_device *); ++ int (*set_rx_csum)(struct net_device *, u32); ++ u32 (*get_tx_csum)(struct net_device *); ++ int (*set_tx_csum)(struct net_device *, u32); ++ u32 (*get_sg)(struct net_device *); ++ int (*set_sg)(struct net_device *, u32); ++ u32 (*get_tso)(struct net_device *); ++ int (*set_tso)(struct net_device *, u32); ++ int (*self_test_count)(struct net_device *); ++ void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); ++ void (*get_strings)(struct net_device *, u32 stringset, u8 *); ++ int (*phys_id)(struct net_device *, u32); ++ int (*get_stats_count)(struct net_device *); ++ void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, ++ u64 *); ++} *ethtool_ops = NULL; ++ ++#undef SET_ETHTOOL_OPS ++#define SET_ETHTOOL_OPS(netdev, ops) (ethtool_ops = (ops)) ++ ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ++ ++ ++//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ++#ifndef netif_msg_init ++#define netif_msg_init _kc_netif_msg_init ++/* copied from linux kernel 2.6.20 include/linux/netdevice.h */ ++static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits) ++{ ++ /* use default */ ++ if (debug_value < 0 || debug_value >= (sizeof(u32) * 8)) ++ return default_msg_enable_bits; ++ if (debug_value == 0) /* no output */ ++ return 0; ++ /* set low N bits */ ++ return (1 << debug_value) - 1; ++} ++ ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) ++static inline void eth_copy_and_sum (struct sk_buff *dest, ++ const unsigned char *src, ++ int len, int base) ++{ ++ memcpy (dest->data, src, len); ++} ++#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) ++/* copied from linux kernel 2.6.20 /include/linux/time.h */ ++/* Parameters used to convert the timespec values: */ ++#define MSEC_PER_SEC 1000L ++ ++/* copied from linux kernel 2.6.20 /include/linux/jiffies.h */ ++/* ++ * Change timeval to jiffies, trying to avoid the ++ * most obvious overflows.. ++ * ++ * And some not so obvious. ++ * ++ * Note that we don't want to return MAX_LONG, because ++ * for various timeout reasons we often end up having ++ * to wait "jiffies+1" in order to guarantee that we wait ++ * at _least_ "jiffies" - so "jiffies+1" had better still ++ * be positive. ++ */ ++#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1) ++ ++/* ++ * Convert jiffies to milliseconds and back. ++ * ++ * Avoid unnecessary multiplications/divisions in the ++ * two most common HZ cases: ++ */ ++static inline unsigned int _kc_jiffies_to_msecs(const unsigned long j) ++{ ++#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) ++ return (MSEC_PER_SEC / HZ) * j; ++#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) ++ return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC); ++#else ++ return (j * MSEC_PER_SEC) / HZ; ++#endif ++} ++ ++static inline unsigned long _kc_msecs_to_jiffies(const unsigned int m) ++{ ++ if (m > _kc_jiffies_to_msecs(MAX_JIFFY_OFFSET)) ++ return MAX_JIFFY_OFFSET; ++#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) ++ return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ); ++#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) ++ return m * (HZ / MSEC_PER_SEC); ++#else ++ return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC; ++#endif ++} ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) ++ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) ++ ++/* copied from linux kernel 2.6.12.6 /include/linux/pm.h */ ++typedef int __bitwise pci_power_t; ++ ++/* copied from linux kernel 2.6.12.6 /include/linux/pci.h */ ++typedef u32 __bitwise pm_message_t; ++ ++#define PCI_D0 ((pci_power_t __force) 0) ++#define PCI_D1 ((pci_power_t __force) 1) ++#define PCI_D2 ((pci_power_t __force) 2) ++#define PCI_D3hot ((pci_power_t __force) 3) ++#define PCI_D3cold ((pci_power_t __force) 4) ++#define PCI_POWER_ERROR ((pci_power_t __force) -1) ++ ++/* copied from linux kernel 2.6.12.6 /drivers/pci/pci.c */ ++/** ++ * pci_choose_state - Choose the power state of a PCI device ++ * @dev: PCI device to be suspended ++ * @state: target sleep state for the whole system. This is the value ++ * that is passed to suspend() function. ++ * ++ * Returns PCI power state suitable for given device and given system ++ * message. ++ */ ++ ++pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) ++{ ++ if (!pci_find_capability(dev, PCI_CAP_ID_PM)) ++ return PCI_D0; ++ ++ switch (state) { ++ case 0: return PCI_D0; ++ case 3: return PCI_D3hot; ++ default: ++ printk("They asked me for state %d\n", state); ++// BUG(); ++ } ++ return PCI_D0; ++} ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) ++/** ++ * msleep_interruptible - sleep waiting for waitqueue interruptions ++ * @msecs: Time in milliseconds to sleep for ++ */ ++#define msleep_interruptible _kc_msleep_interruptible ++unsigned long _kc_msleep_interruptible(unsigned int msecs) ++{ ++ unsigned long timeout = _kc_msecs_to_jiffies(msecs); ++ ++ while (timeout && !signal_pending(current)) { ++ set_current_state(TASK_INTERRUPTIBLE); ++ timeout = schedule_timeout(timeout); ++ } ++ return _kc_jiffies_to_msecs(timeout); ++} ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) ++/* copied from linux kernel 2.6.20 include/linux/sched.h */ ++#ifndef __sched ++#define __sched __attribute__((__section__(".sched.text"))) ++#endif ++ ++/* copied from linux kernel 2.6.20 kernel/timer.c */ ++signed long __sched schedule_timeout_uninterruptible(signed long timeout) ++{ ++ __set_current_state(TASK_UNINTERRUPTIBLE); ++ return schedule_timeout(timeout); ++} ++ ++/* copied from linux kernel 2.6.20 include/linux/mii.h */ ++#undef if_mii ++#define if_mii _kc_if_mii ++static inline struct mii_ioctl_data *if_mii(struct ifreq *rq) ++{ ++ return (struct mii_ioctl_data *) &rq->ifr_ifru; ++} ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) ++ ++void mdio_write(struct rtl8168_private *tp, ++ u32 RegAddr, ++ u32 value) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ int i; ++ ++ if (tp->mcfg==CFG_METHOD_11) ++ { ++ RTL_W32(OCPDR, OCPDR_Write | ++ (RegAddr & OCPDR_Reg_Mask) << OCPDR_GPHY_Reg_shift | ++ (value & OCPDR_Data_Mask)); ++ RTL_W32(OCPAR, OCPAR_GPHY_Write); ++ RTL_W32(EPHY_RXER_NUM, 0); ++ ++ for (i = 0; i < 100; i++) ++ { ++ mdelay(1); ++ if (!(RTL_R32(OCPAR) & OCPAR_Flag)) ++ break; ++ } ++ } ++ else ++ { ++ if (tp->mcfg == CFG_METHOD_12 || tp->mcfg == CFG_METHOD_13) ++ RTL_W32(0xD0, RTL_R32(0xD0) & ~0x00020000); ++ ++ RTL_W32(PHYAR, PHYAR_Write | ++ (RegAddr & PHYAR_Reg_Mask) << PHYAR_Reg_shift | ++ (value & PHYAR_Data_Mask)); ++ ++ for (i = 0; i < 10; i++) { ++ udelay(100); ++ ++ /* Check if the RTL8168 has completed writing to the specified MII register */ ++ if (!(RTL_R32(PHYAR) & PHYAR_Flag)) ++ { ++ udelay(20); ++ break; ++ } ++ } ++ ++ if (tp->mcfg == CFG_METHOD_12 || tp->mcfg == CFG_METHOD_13) ++ RTL_W32(0xD0, RTL_R32(0xD0) | 0x00020000); ++ } ++} ++ ++u32 mdio_read(struct rtl8168_private *tp, ++ u32 RegAddr) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ int i, value = -1; ++ ++ if (tp->mcfg==CFG_METHOD_11) ++ { ++ RTL_W32(OCPDR, OCPDR_Read | ++ (RegAddr & OCPDR_Reg_Mask) << OCPDR_GPHY_Reg_shift); ++ RTL_W32(OCPAR, OCPAR_GPHY_Write); ++ RTL_W32(EPHY_RXER_NUM, 0); ++ ++ for (i = 0; i < 100; i++) ++ { ++ mdelay(1); ++ if (!(RTL_R32(OCPAR) & OCPAR_Flag)) ++ break; ++ } ++ ++ mdelay(1); ++ RTL_W32(OCPAR, OCPAR_GPHY_Read); ++ RTL_W32(EPHY_RXER_NUM, 0); ++ ++ for (i = 0; i < 100; i++) ++ { ++ mdelay(1); ++ if (RTL_R32(OCPAR) & OCPAR_Flag) ++ break; ++ } ++ ++ value = (int) (RTL_R32(OCPDR) & OCPDR_Data_Mask); ++ } ++ else ++ { ++ if (tp->mcfg == CFG_METHOD_12 || tp->mcfg == CFG_METHOD_13) ++ RTL_W32(0xD0, RTL_R32(0xD0) & ~0x00020000); ++ ++ RTL_W32(PHYAR, ++ PHYAR_Read | (RegAddr & PHYAR_Reg_Mask) << PHYAR_Reg_shift); ++ ++ for (i = 0; i < 10; i++) { ++ udelay(100); ++ ++ /* Check if the RTL8168 has completed retrieving data from the specified MII register */ ++ if (RTL_R32(PHYAR) & PHYAR_Flag) { ++ value = (int) (RTL_R32(PHYAR) & PHYAR_Data_Mask); ++ udelay(20); ++ break; ++ } ++ } ++ ++ if (tp->mcfg == CFG_METHOD_12 || tp->mcfg == CFG_METHOD_13) ++ RTL_W32(0xD0, RTL_R32(0xD0) | 0x00020000); ++ } ++ ++ return value; ++} ++ ++u32 OCP_read(struct rtl8168_private *tp, u8 mask, u16 Reg) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ int i; ++ ++ RTL_W32(OCPAR, ((u32)mask&0xF)<<12 | (Reg&0xFFF)); ++ for (i=0;i<20;i++) ++ { ++ udelay(100); ++ if (RTL_R32(OCPAR) & OCPAR_Flag) ++ break; ++ } ++ return RTL_R32(OCPDR); ++} ++ ++void OCP_write(struct rtl8168_private *tp, u8 mask, u16 Reg, u32 data) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ int i; ++ ++ RTL_W32(OCPDR, data); ++ RTL_W32(OCPAR, OCPAR_Flag | ((u32)mask&0xF)<<12 | (Reg&0xFFF)); ++ for (i=0;i<20;i++) ++ { ++ udelay(100); ++ if ( (RTL_R32(OCPAR)&OCPAR_Flag) == 0) ++ break; ++ } ++} ++ ++static void OOB_mutex_lock(struct rtl8168_private *tp) ++{ ++ u32 reg; ++ ++ if (tp->mcfg == CFG_METHOD_13) ++ reg = 0x04; ++ else ++ reg = 0x14; ++ ++ OCP_write(tp, 0x8, reg, 0x01000000); ++ ++ while (OCP_read(tp, 0xF, reg) & 0x00FF0000) { ++ if (OCP_read(tp, 0xF, 0x09C) & 0x000000FF) { ++ OCP_write(tp, 0x8, reg, 0x00000000); ++ ++ while (OCP_read(tp, 0xF, 0x09C) & 0x000000FF); ++ ++ OCP_write(tp, 0x8, reg, 0x01000000); ++ } ++ } ++} ++ ++static void OOB_mutex_unlock(struct rtl8168_private *tp) ++{ ++ u32 reg; ++ ++ if (tp->mcfg == CFG_METHOD_13) ++ reg = 0x04; ++ else ++ reg = 0x14; ++ ++ OCP_write(tp, 0x1, 0x9C, 0x00000001); ++ OCP_write(tp, 0x8, reg, 0x00000000); ++} ++ ++void OOB_notify(struct rtl8168_private *tp, u8 cmd) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ int i; ++ ++ RTL_W8(ERIDR, cmd); ++ RTL_W32(ERIAR, 0x800010E8); ++ mdelay(2); ++ for (i = 0; i < 5; i++) { ++ udelay(100); ++ if ( !(RTL_R32(ERIAR) & ERIAR_Flag)) ++ break; ++ } ++ ++ OCP_write(tp, 0x1, 0x30, 0x00000001); ++} ++ ++static int rtl8168_check_dash(struct rtl8168_private *tp) ++{ ++ u32 reg; ++ ++ if (tp->mcfg == CFG_METHOD_13) ++ reg = 0xb8; ++ else ++ reg = 0x10; ++ ++ if (OCP_read(tp, 0xF, reg) & 0x00008000) ++ return 1; ++ else ++ return 0; ++} ++ ++static void rtl8168_mac_loopback_test(struct rtl8168_private *tp) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ struct net_device *dev = tp->dev; ++ struct sk_buff *skb, *rx_skb; ++ dma_addr_t mapping; ++ struct TxDesc *txd; ++ struct RxDesc *rxd; ++ void *tmpAddr; ++ u32 len, rx_len, rx_cmd; ++ u16 type; ++ u8 pattern; ++ int i; ++ ++ if (rtl8168_check_dash(tp)) ++ return; ++ ++ pattern = 0x5A; ++ len = 60; ++ type = htons(ETH_P_IP); ++ txd = tp->TxDescArray; ++ rxd = tp->RxDescArray; ++ rx_skb = tp->Rx_skbuff[0]; ++ RTL_W32(TxConfig, (RTL_R32(TxConfig) & ~0x00060000) | 0x00020000); ++ ++ do { ++ skb = dev_alloc_skb(len + RTK_RX_ALIGN); ++ if (unlikely(!skb)) ++ dev_printk(KERN_NOTICE, &tp->pci_dev->dev, "-ENOMEM;\n"); ++ } while (unlikely(skb == NULL)); ++ skb_reserve(skb, RTK_RX_ALIGN); ++ ++ memcpy(skb_put(skb, dev->addr_len), dev->dev_addr, dev->addr_len); ++ memcpy(skb_put(skb, dev->addr_len), dev->dev_addr, dev->addr_len); ++ memcpy(skb_put(skb, sizeof(type)), &type, sizeof(type)); ++ tmpAddr = skb_put(skb, len - 14); ++ ++ mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE); ++ pci_dma_sync_single_for_cpu(tp->pci_dev, le64_to_cpu(mapping), ++ len, PCI_DMA_TODEVICE); ++ txd->addr = cpu_to_le64(mapping); ++ txd->opts2 = 0; ++ while (1) { ++ memset(tmpAddr, pattern++, len - 14); ++ pci_dma_sync_single_for_device(tp->pci_dev, ++ le64_to_cpu(mapping), ++ len, PCI_DMA_TODEVICE); ++ txd->opts1 = cpu_to_le32(DescOwn | FirstFrag | LastFrag | len); ++ ++ RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptMyPhys); ++ ++ smp_wmb(); ++ RTL_W8(TxPoll, NPQ); /* set polling bit */ ++ ++ for (i = 0; i < 50; i++) { ++ udelay(200); ++ rx_cmd = le32_to_cpu(rxd->opts1); ++ if ((rx_cmd & DescOwn) == 0) ++ break; ++ } ++ ++ RTL_W32(RxConfig, RTL_R32(RxConfig) & ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys)); ++ ++ rx_len = rx_cmd & 0x3FFF; ++ rx_len -= 4; ++ rxd->opts1 = cpu_to_le32(DescOwn | tp->rx_buf_sz); ++ ++ pci_dma_sync_single_for_cpu(tp->pci_dev, le64_to_cpu(mapping), len, PCI_DMA_TODEVICE); ++ ++ if (rx_len == len) { ++ pci_dma_sync_single_for_cpu(tp->pci_dev, le64_to_cpu(rxd->addr), tp->rx_buf_sz, PCI_DMA_FROMDEVICE); ++ i = memcmp(skb->data, rx_skb->data, rx_len); ++ pci_dma_sync_single_for_device(tp->pci_dev, le64_to_cpu(rxd->addr), tp->rx_buf_sz, PCI_DMA_FROMDEVICE); ++ if (i == 0) { ++// dev_printk(KERN_INFO, &tp->pci_dev->dev, "loopback test finished\n",rx_len,len); ++ break; ++ } ++ } ++ ++ rtl8168_nic_reset(dev); ++ RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); ++ } ++ tp->dirty_tx++; ++ tp->dirty_rx++; ++ tp->cur_tx++; ++ tp->cur_rx++; ++ pci_unmap_single(tp->pci_dev, le64_to_cpu(mapping), ++ len, PCI_DMA_TODEVICE); ++ RTL_W32(TxConfig, RTL_R32(TxConfig) & ~0x00060000); ++ dev_kfree_skb_any(skb); ++ RTL_W16(IntrStatus, 0xFFBF); ++} ++ ++static void rtl8168_driver_start(struct rtl8168_private *tp) ++{ ++ int timeout; ++ u32 reg; ++ ++ OOB_notify(tp, OOB_CMD_DRIVER_START); ++ ++ if (tp->mcfg == CFG_METHOD_13) ++ reg = 0xB8; ++ else ++ reg = 0x10; ++ ++ for (timeout = 0; timeout < 10; timeout++) { ++ mdelay(10); ++ if (OCP_read(tp, 0xF, reg) & BIT_11) ++ break; ++ } ++} ++ ++static void rtl8168_driver_stop(struct rtl8168_private *tp) ++{ ++ int timeout; ++ u32 reg; ++ ++ OOB_notify(tp, OOB_CMD_DRIVER_STOP); ++ ++ if (tp->mcfg == CFG_METHOD_13) ++ reg = 0xB8; ++ else ++ reg = 0x10; ++ ++ for (timeout = 0; timeout < 10; timeout++) { ++ mdelay(10); ++ if ((OCP_read(tp, 0xF, reg) & BIT_11) == 0) ++ break; ++ } ++} ++ ++void rtl8168_ephy_write(void __iomem *ioaddr, int RegAddr, int value) ++{ ++ int i; ++ ++ RTL_W32(EPHYAR, ++ EPHYAR_Write | ++ (RegAddr & EPHYAR_Reg_Mask) << EPHYAR_Reg_shift | ++ (value & EPHYAR_Data_Mask)); ++ ++ for (i = 0; i < 10; i++) { ++ udelay(100); ++ ++ /* Check if the RTL8168 has completed EPHY write */ ++ if (!(RTL_R32(EPHYAR) & EPHYAR_Flag)) ++ break; ++ } ++ ++ udelay(20); ++} ++ ++u16 rtl8168_ephy_read(void __iomem *ioaddr, int RegAddr) ++{ ++ int i; ++ u16 value = 0xffff; ++ ++ RTL_W32(EPHYAR, ++ EPHYAR_Read | (RegAddr & EPHYAR_Reg_Mask) << EPHYAR_Reg_shift); ++ ++ for (i = 0; i < 10; i++) { ++ udelay(100); ++ ++ /* Check if the RTL8168 has completed EPHY read */ ++ if (RTL_R32(EPHYAR) & EPHYAR_Flag) { ++ value = (u16) (RTL_R32(EPHYAR) & EPHYAR_Data_Mask); ++ break; ++ } ++ } ++ ++ udelay(20); ++ ++ return value; ++} ++ ++static void ++rtl8168_csi_write(struct rtl8168_private *tp, ++ u32 addr, ++ u32 value) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ u32 cmd; ++ int i; ++ ++ RTL_W32(CSIDR, value); ++ cmd = CSIAR_Write | CSIAR_ByteEn << CSIAR_ByteEn_shift | (addr & CSIAR_Addr_Mask); ++ if (tp->mcfg == CFG_METHOD_20) ++ cmd |= 0x00020000; ++ RTL_W32(CSIAR, cmd); ++ ++ for (i = 0; i < 10; i++) { ++ udelay(100); ++ ++ /* Check if the RTL8168 has completed CSI write */ ++ if (!(RTL_R32(CSIAR) & CSIAR_Flag)) ++ break; ++ } ++ ++ udelay(20); ++} ++ ++static int ++rtl8168_csi_read(struct rtl8168_private *tp, ++ u32 addr) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ u32 cmd; ++ int i, value = -1; ++ ++ cmd = CSIAR_Read | CSIAR_ByteEn << CSIAR_ByteEn_shift | (addr & CSIAR_Addr_Mask); ++ ++ if (tp->mcfg == CFG_METHOD_20) ++ cmd |= 0x00020000; ++ ++ RTL_W32(CSIAR, cmd); ++ ++ for (i = 0; i < 10; i++) { ++ udelay(100); ++ ++ /* Check if the RTL8168 has completed CSI read */ ++ if (RTL_R32(CSIAR) & CSIAR_Flag) { ++ value = (int)RTL_R32(CSIDR); ++ break; ++ } ++ } ++ ++ udelay(20); ++ ++ return value; ++} ++ ++u32 rtl8168_eri_read(void __iomem *ioaddr, int addr, int len, int type) ++{ ++ int i, val_shift, shift = 0; ++ u32 value1 = 0, value2 = 0, mask; ++ ++ if (len > 4 || len <= 0) ++ return -1; ++ ++ while (len > 0) { ++ val_shift = addr % ERIAR_Addr_Align; ++ addr = addr & ~0x3; ++ ++ RTL_W32(ERIAR, ++ ERIAR_Read | ++ type << ERIAR_Type_shift | ++ ERIAR_ByteEn << ERIAR_ByteEn_shift | ++ addr); ++ ++ for (i = 0; i < 10; i++) { ++ udelay(100); ++ ++ /* Check if the RTL8168 has completed ERI read */ ++ if (RTL_R32(ERIAR) & ERIAR_Flag) ++ break; ++ } ++ ++ if (len == 1) mask = (0xFF << (val_shift * 8)) & 0xFFFFFFFF; ++ else if (len == 2) mask = (0xFFFF << (val_shift * 8)) & 0xFFFFFFFF; ++ else if (len == 3) mask = (0xFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; ++ else mask = (0xFFFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; ++ ++ value1 = RTL_R32(ERIDR) & mask; ++ value2 |= (value1 >> val_shift * 8) << shift * 8; ++ ++ if (len <= 4 - val_shift) ++ len = 0; ++ else { ++ len -= (4 - val_shift); ++ shift = 4 - val_shift; ++ addr += 4; ++ } ++ } ++ ++ return value2; ++} ++ ++int rtl8168_eri_write(void __iomem *ioaddr, int addr, int len, u32 value, int type) ++{ ++ ++ int i, val_shift, shift = 0; ++ u32 value1 = 0, mask; ++ ++ if (len > 4 || len <= 0) ++ return -1; ++ ++ while (len > 0) { ++ val_shift = addr % ERIAR_Addr_Align; ++ addr = addr & ~0x3; ++ ++ if (len == 1) mask = (0xFF << (val_shift * 8)) & 0xFFFFFFFF; ++ else if (len == 2) mask = (0xFFFF << (val_shift * 8)) & 0xFFFFFFFF; ++ else if (len == 3) mask = (0xFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; ++ else mask = (0xFFFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; ++ ++ value1 = rtl8168_eri_read(ioaddr, addr, 4, type) & ~mask; ++ value1 |= ((value << val_shift * 8) >> shift * 8); ++ ++ RTL_W32(ERIDR, value1); ++ RTL_W32(ERIAR, ++ ERIAR_Write | ++ type << ERIAR_Type_shift | ++ ERIAR_ByteEn << ERIAR_ByteEn_shift | ++ addr); ++ ++ for (i = 0; i < 10; i++) { ++ udelay(100); ++ ++ /* Check if the RTL8168 has completed ERI write */ ++ if (!(RTL_R32(ERIAR) & ERIAR_Flag)) ++ break; ++ } ++ ++ if (len <= 4 - val_shift) ++ len = 0; ++ else { ++ len -= (4 - val_shift); ++ shift = 4 - val_shift; ++ addr += 4; ++ } ++ } ++ ++ return 0; ++} ++ ++static void ++rtl8168_irq_mask_and_ack(void __iomem *ioaddr) ++{ ++ RTL_W16(IntrMask, 0x0000); ++} ++ ++static void ++rtl8168_asic_down(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ rtl8168_irq_mask_and_ack(ioaddr); ++ rtl8168_nic_reset(dev); ++} ++ ++static void ++rtl8168_nic_reset(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ int i; ++ ++ RTL_W32(RxConfig, RTL_R32(RxConfig) & ++ ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast | ++ AcceptMyPhys | AcceptAllPhys)); ++ ++ switch (tp->mcfg) { ++ case CFG_METHOD_1: ++ case CFG_METHOD_2: ++ case CFG_METHOD_3: ++ break; ++ case CFG_METHOD_4: ++ case CFG_METHOD_5: ++ case CFG_METHOD_6: ++ case CFG_METHOD_7: ++ case CFG_METHOD_8: ++ case CFG_METHOD_9: ++ case CFG_METHOD_10: ++ case CFG_METHOD_14: ++ case CFG_METHOD_15: ++ RTL_W8(ChipCmd, StopReq | CmdRxEnb | CmdTxEnb); ++ udelay(100); ++ break; ++ case CFG_METHOD_11: ++ case CFG_METHOD_12: ++ case CFG_METHOD_13: ++ while (RTL_R8(TxPoll) & NPQ) ++ udelay(20); ++ break; ++ default: ++ RTL_W8(ChipCmd, StopReq | CmdRxEnb | CmdTxEnb); ++ while (!(RTL_R32(TxConfig) & BIT_11)) udelay(100); ++ break; ++ } ++ ++ /* Soft reset the chip. */ ++ RTL_W8(ChipCmd, CmdReset); ++ ++ /* Check that the chip has finished the reset. */ ++ for (i = 100; i > 0; i--) { ++ udelay(100); ++ if ((RTL_R8(ChipCmd) & CmdReset) == 0) ++ break; ++ } ++ ++ if (tp->mcfg == CFG_METHOD_11) ++ { ++ OOB_mutex_lock(tp); ++ OCP_write(tp, 0x3, 0x10, OCP_read(tp, 0xF, 0x010)&~0x00004000); ++ OOB_mutex_unlock(tp); ++ ++ OOB_notify(tp, OOB_CMD_RESET); ++ ++ for (i=0;i<10;i++) ++ { ++ mdelay(10); ++ if (OCP_read(tp, 0xF, 0x010)&0x00004000) ++ break; ++ } ++ ++ for (i=0;i<5;i++) ++ { ++ if ( (OCP_read(tp, 0xF, 0x034) & 0xFFFF) == 0) ++ break; ++ } ++ } ++} ++ ++static unsigned int ++rtl8168_xmii_reset_pending(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ unsigned long flags; ++ unsigned int retval; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1f, 0x0000); ++ retval = mdio_read(tp, MII_BMCR) & BMCR_RESET; ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ return retval; ++} ++ ++static unsigned int ++rtl8168_xmii_link_ok(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ unsigned int retval; ++ ++ retval = RTL_R8(PHYstatus) & LinkStatus; ++ ++ return retval; ++} ++ ++static void ++rtl8168_xmii_reset_enable(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ unsigned long flags; ++ int i, val = 0; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, MII_BMCR, mdio_read(tp, MII_BMCR) | BMCR_RESET); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ for (i = 0; i < 2500; i++) { ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ val = mdio_read(tp, MII_BMSR) & BMCR_RESET; ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ if (!val) ++ return; ++ ++ mdelay(1); ++ } ++} ++ ++static void ++rtl8168dp_10mbps_gphy_para(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ u8 status = RTL_R8(PHYstatus); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ if ((status & LinkStatus) && (status & _10bps)) { ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x10, 0x04EE); ++ } else { ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x10, 0x01EE); ++ } ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++} ++ ++void rtl8168_init_ring_indexes(struct rtl8168_private *tp); ++static void ++rtl8168_check_link_status(struct net_device *dev, ++ struct rtl8168_private *tp, ++ void __iomem *ioaddr) ++{ ++ unsigned long flags; ++ ++ if (tp->mcfg == CFG_METHOD_11) ++ { ++ rtl8168dp_10mbps_gphy_para(dev); ++ } ++ ++ spin_lock_irqsave(&tp->lock, flags); ++ if (tp->link_ok(dev)) { ++ if (tp->mcfg == CFG_METHOD_18 || tp->mcfg == CFG_METHOD_19 || tp->mcfg == CFG_METHOD_20) { ++ if (RTL_R8(PHYstatus) & _1000bpsF) { ++ rtl8168_eri_write(ioaddr, 0x1bc, 4, 0x00000011, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0x1dc, 4, 0x00000005, ERIAR_ExGMAC); ++ } else { ++ rtl8168_eri_write(ioaddr, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0x1dc, 4, 0x0000003f, ERIAR_ExGMAC); ++ } ++ if (netif_running(dev) && (RTL_R8(ChipCmd) & (CmdRxEnb | CmdTxEnb))==0) { ++ int timeout; ++ for (timeout = 0; timeout < 10; timeout++) { ++ if ((rtl8168_eri_read(ioaddr, 0x1AE, 4, ERIAR_ExGMAC) & BIT_13)==0) ++ break; ++ mdelay(1); ++ } ++ rtl8168_init_ring_indexes(tp); ++ RTL_W8(ChipCmd, CmdRxEnb | CmdTxEnb); ++ } ++ } else if ((tp->mcfg == CFG_METHOD_16 || tp->mcfg == CFG_METHOD_17) && netif_running(dev)) { ++ u32 eri_data; ++ if (tp->mcfg == CFG_METHOD_16 && (RTL_R8(PHYstatus) & _10bps)) ++ RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptAllPhys); ++ else if (tp->mcfg == CFG_METHOD_17) { ++ if (RTL_R8(PHYstatus) & _1000bpsF) { ++ rtl8168_eri_write(ioaddr, 0x1bc, 4, 0x00000011, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0x1dc, 4, 0x00000005, ERIAR_ExGMAC); ++ } else if (RTL_R8(PHYstatus) & _100bps) { ++ rtl8168_eri_write(ioaddr, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0x1dc, 4, 0x00000005, ERIAR_ExGMAC); ++ } else { ++ rtl8168_eri_write(ioaddr, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0x1dc, 4, 0x0000003f, ERIAR_ExGMAC); ++ } ++ } ++ ++ eri_data = rtl8168_eri_read(ioaddr, 0xDC, 1, ERIAR_ExGMAC); ++ eri_data &= ~BIT_0; ++ rtl8168_eri_write(ioaddr, 0xDC, 1, eri_data, ERIAR_ExGMAC); ++ eri_data |= BIT_0; ++ rtl8168_eri_write(ioaddr, 0xDC, 1, eri_data, ERIAR_ExGMAC); ++ if ((RTL_R8(ChipCmd) & (CmdRxEnb | CmdTxEnb))==0) { ++ int timeout; ++ for (timeout = 0; timeout < 10; timeout++) { ++ if ((rtl8168_eri_read(ioaddr, 0x1AE, 4, ERIAR_ExGMAC) & BIT_13)==0) ++ break; ++ mdelay(1); ++ } ++ rtl8168_init_ring_indexes(tp); ++ RTL_W8(ChipCmd, CmdRxEnb | CmdTxEnb); ++ } ++ ++ } else if ((tp->mcfg == CFG_METHOD_14 || tp->mcfg == CFG_METHOD_15) && eee_enable ==1){ ++ //Full -Duplex mode ++ if (RTL_R8(PHYstatus)&FullDup){ ++ mdio_write(tp, 0x1F, 0x0006); ++ mdio_write(tp, 0x00, 0x5a30); ++ mdio_write(tp, 0x1F, 0x0000); ++ }else{ ++ mdio_write(tp, 0x1F, 0x0006); ++ mdio_write(tp, 0x00, 0x5a00); ++ mdio_write(tp, 0x1F, 0x0000); ++ } ++ } ++ ++ netif_carrier_on(dev); ++ if (netif_msg_ifup(tp)) ++ printk(KERN_INFO PFX "%s: link up\n", dev->name); ++ } else { ++ if (netif_msg_ifdown(tp)) ++ printk(KERN_INFO PFX "%s: link down\n", dev->name); ++ netif_carrier_off(dev); ++ } ++ spin_unlock_irqrestore(&tp->lock, flags); ++} ++ ++static void ++rtl8168_link_option(int idx, ++ u8 *aut, ++ u16 *spd, ++ u8 *dup) ++{ ++ unsigned char opt_speed; ++ unsigned char opt_duplex; ++ unsigned char opt_autoneg; ++ ++ opt_speed = ((idx < MAX_UNITS) && (idx >= 0)) ? speed[idx] : 0xff; ++ opt_duplex = ((idx < MAX_UNITS) && (idx >= 0)) ? duplex[idx] : 0xff; ++ opt_autoneg = ((idx < MAX_UNITS) && (idx >= 0)) ? autoneg[idx] : 0xff; ++ ++ if ((opt_speed == 0xff) | ++ (opt_duplex == 0xff) | ++ (opt_autoneg == 0xff)) { ++ *spd = SPEED_1000; ++ *dup = DUPLEX_FULL; ++ *aut = AUTONEG_ENABLE; ++ } else { ++ *spd = speed[idx]; ++ *dup = duplex[idx]; ++ *aut = autoneg[idx]; ++ } ++} ++ ++static void ++rtl8168_powerdown_pll(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ unsigned long flags; ++ int auto_nego = 0; ++ int giga_ctrl = 0; ++ ++ if ((tp->mcfg == CFG_METHOD_11 || tp->mcfg == CFG_METHOD_12 || ++ tp->mcfg == CFG_METHOD_13) && rtl8168_check_dash(tp)) ++ return; ++ ++ if (((tp->mcfg == CFG_METHOD_7) || (tp->mcfg == CFG_METHOD_8)) && (RTL_R16(CPlusCmd) & ASF)) ++ return; ++ ++// if (tp->mcfg == CFG_METHOD_17) { ++// void __iomem *ioaddr = tp->mmio_addr; ++// unsigned long flags; ++// u32 data; ++ ++// spin_lock_irqsave(&tp->phy_lock, flags); ++// mdio_write(tp, 0x1f, 0x0000); ++// data = mdio_read(tp, MII_CTRL1000); ++// data &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); ++// mdio_write(tp, MII_CTRL1000, data); ++// mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART); ++// spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++// ssleep(3); ++// RTL_W16(IntrStatus, RTL_R16(IntrStatus)); ++// RTL_W32(MAR0, 0); ++// RTL_W32(MAR0 + 4, 0); ++// RTL_W16(RxMaxSize, 0x05f3); ++// RTL_W8(0xD3, RTL_R8(0xD3) | BIT_7); ++ ++// data = rtl8168_eri_read(ioaddr, 0xDC, 1, ERIAR_ExGMAC); ++// data &= ~BIT_0; ++// rtl8168_eri_write(ioaddr, 0xDC, 1, data, ERIAR_ExGMAC); ++// data |= BIT_0; ++// rtl8168_eri_write(ioaddr, 0xDC, 1, data, ERIAR_ExGMAC); ++ ++// RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); ++// return; ++// } ++ ++ if (tp->wol_enabled == WOL_ENABLED) { ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0000); ++ auto_nego = mdio_read(tp, MII_ADVERTISE); ++ auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL ++ | ADVERTISE_100HALF | ADVERTISE_100FULL); ++ if (config_down_speed_100) ++ auto_nego |= ADVERTISE_100FULL; ++ else ++ auto_nego |= ADVERTISE_10HALF; ++ ++ giga_ctrl = mdio_read(tp, MII_CTRL1000) & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); ++ mdio_write(tp, MII_ADVERTISE, auto_nego); ++ mdio_write(tp, MII_CTRL1000, giga_ctrl); ++ mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); ++ return; ++ } ++ ++ rtl8168_phy_power_down(dev); ++ ++ switch (tp->mcfg) { ++ case CFG_METHOD_9: ++ case CFG_METHOD_10: ++ case CFG_METHOD_11: ++ case CFG_METHOD_12: ++ case CFG_METHOD_13: ++ case CFG_METHOD_14: ++ case CFG_METHOD_15: ++ RTL_W8(PMCH, RTL_R8(PMCH) & ~BIT_7); ++ break; ++ } ++} ++ ++static void rtl8168_powerup_pll(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ switch (tp->mcfg) { ++ case CFG_METHOD_9: ++ case CFG_METHOD_10: ++ case CFG_METHOD_11: ++ case CFG_METHOD_12: ++ case CFG_METHOD_13: ++ case CFG_METHOD_14: ++ case CFG_METHOD_15: ++ RTL_W8(PMCH, RTL_R8(PMCH) | BIT_7); ++ break; ++ } ++ ++ rtl8168_phy_power_up(dev); ++ rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex); ++} ++ ++static void ++rtl8168_get_wol(struct net_device *dev, ++ struct ethtool_wolinfo *wol) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ u8 options; ++ u32 csi_tmp; ++ ++ wol->wolopts = 0; ++ ++#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) ++ if (tp->mcfg == CFG_METHOD_DEFAULT) { ++ wol->supported = 0; ++ return; ++ } else { ++ wol->supported = WAKE_ANY; ++ } ++ ++ spin_lock_irq(&tp->lock); ++ ++ options = RTL_R8(Config1); ++ if (!(options & PMEnable)) ++ goto out_unlock; ++ ++ options = RTL_R8(Config3); ++ if (options & LinkUp) ++ wol->wolopts |= WAKE_PHY; ++ if (tp->mcfg == CFG_METHOD_16 || tp->mcfg == CFG_METHOD_17) { ++ csi_tmp = rtl8168_eri_read(ioaddr, 0xDE, 4, ERIAR_ExGMAC); ++ if (csi_tmp & BIT_0) ++ wol->wolopts |= WAKE_MAGIC; ++ } else { ++ if (options & MagicPacket) ++ wol->wolopts |= WAKE_MAGIC; ++ } ++ ++ options = RTL_R8(Config5); ++ if (options & UWF) ++ wol->wolopts |= WAKE_UCAST; ++ if (options & BWF) ++ wol->wolopts |= WAKE_BCAST; ++ if (options & MWF) ++ wol->wolopts |= WAKE_MCAST; ++ ++out_unlock: ++ spin_unlock_irq(&tp->lock); ++} ++ ++static int ++rtl8168_set_wol(struct net_device *dev, ++ struct ethtool_wolinfo *wol) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ int i,tmp; ++ u32 csi_tmp; ++ static struct { ++ u32 opt; ++ u16 reg; ++ u8 mask; ++ } cfg[] = { ++ { WAKE_ANY, Config1, PMEnable }, ++ { WAKE_PHY, Config3, LinkUp }, ++ { WAKE_UCAST, Config5, UWF }, ++ { WAKE_BCAST, Config5, BWF }, ++ { WAKE_MCAST, Config5, MWF }, ++ { WAKE_ANY, Config5, LanWake }, ++ { WAKE_MAGIC, Config3, MagicPacket }, ++ }; ++ ++ if (tp->mcfg == CFG_METHOD_DEFAULT) ++ return -EOPNOTSUPP; ++ ++ spin_lock_irq(&tp->lock); ++ ++ RTL_W8(Cfg9346, Cfg9346_Unlock); ++ ++ if (tp->mcfg == CFG_METHOD_16 || tp->mcfg == CFG_METHOD_17) { ++ tmp = ARRAY_SIZE(cfg) - 1; ++ ++ csi_tmp = rtl8168_eri_read(ioaddr, 0xDE, 4, ERIAR_ExGMAC); ++ if (wol->wolopts & WAKE_MAGIC) ++ csi_tmp |= BIT_0; ++ else ++ csi_tmp &=~ BIT_0; ++ rtl8168_eri_write(ioaddr, 0xDE, 4, csi_tmp, ERIAR_ExGMAC); ++ } else { ++ tmp = ARRAY_SIZE(cfg); ++ } ++ ++ for (i = 0; i < tmp; i++) { ++ u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask; ++ if (wol->wolopts & cfg[i].opt) ++ options |= cfg[i].mask; ++ RTL_W8(cfg[i].reg, options); ++ } ++ ++ RTL_W8(Cfg9346, Cfg9346_Lock); ++ ++ tp->wol_enabled = (wol->wolopts) ? WOL_ENABLED : WOL_DISABLED; ++ ++ spin_unlock_irq(&tp->lock); ++ ++ return 0; ++} ++ ++static void ++rtl8168_get_drvinfo(struct net_device *dev, ++ struct ethtool_drvinfo *info) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ strcpy(info->driver, MODULENAME); ++ strcpy(info->version, RTL8168_VERSION); ++ strcpy(info->bus_info, pci_name(tp->pci_dev)); ++ info->regdump_len = R8168_REGS_SIZE; ++ info->eedump_len = tp->eeprom_len; ++} ++ ++static int ++rtl8168_get_regs_len(struct net_device *dev) ++{ ++ return R8168_REGS_SIZE; ++} ++ ++static int ++rtl8168_set_speed_xmii(struct net_device *dev, ++ u8 autoneg, ++ u16 speed, ++ u8 duplex) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ int auto_nego = 0; ++ int giga_ctrl = 0; ++ int bmcr_true_force = 0; ++ unsigned long flags; ++ ++ if ((speed != SPEED_1000) && ++ (speed != SPEED_100) && ++ (speed != SPEED_10)) { ++ speed = SPEED_1000; ++ duplex = DUPLEX_FULL; ++ } ++ ++ if ((autoneg == AUTONEG_ENABLE) || (speed == SPEED_1000)) { ++ /*n-way force*/ ++ if ((speed == SPEED_10) && (duplex == DUPLEX_HALF)) { ++ auto_nego |= ADVERTISE_10HALF; ++ } else if ((speed == SPEED_10) && (duplex == DUPLEX_FULL)) { ++ auto_nego |= ADVERTISE_10HALF | ++ ADVERTISE_10FULL; ++ } else if ((speed == SPEED_100) && (duplex == DUPLEX_HALF)) { ++ auto_nego |= ADVERTISE_100HALF | ++ ADVERTISE_10HALF | ++ ADVERTISE_10FULL; ++ } else if ((speed == SPEED_100) && (duplex == DUPLEX_FULL)) { ++ auto_nego |= ADVERTISE_100HALF | ++ ADVERTISE_100FULL | ++ ADVERTISE_10HALF | ++ ADVERTISE_10FULL; ++ } else if (speed == SPEED_1000) { ++ giga_ctrl |= ADVERTISE_1000HALF | ++ ADVERTISE_1000FULL; ++ ++ auto_nego |= ADVERTISE_100HALF | ++ ADVERTISE_100FULL | ++ ADVERTISE_10HALF | ++ ADVERTISE_10FULL; ++ } ++ ++ //flow contorol ++ auto_nego |= ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM; ++ ++ tp->phy_auto_nego_reg = auto_nego; ++ tp->phy_1000_ctrl_reg = giga_ctrl; ++ ++ tp->autoneg = autoneg; ++ tp->speed = speed; ++ tp->duplex = duplex; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, MII_ADVERTISE, auto_nego); ++ mdio_write(tp, MII_CTRL1000, giga_ctrl); ++ mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ mdelay(20); ++ } else { ++ /*true force*/ ++#ifndef BMCR_SPEED100 ++#define BMCR_SPEED100 0x0040 ++#endif ++ ++#ifndef BMCR_SPEED10 ++#define BMCR_SPEED10 0x0000 ++#endif ++ if ((speed == SPEED_10) && (duplex == DUPLEX_HALF)) { ++ bmcr_true_force = BMCR_SPEED10; ++ } else if ((speed == SPEED_10) && (duplex == DUPLEX_FULL)) { ++ bmcr_true_force = BMCR_SPEED10 | BMCR_FULLDPLX; ++ } else if ((speed == SPEED_100) && (duplex == DUPLEX_HALF)) { ++ bmcr_true_force = BMCR_SPEED100; ++ } else if ((speed == SPEED_100) && (duplex == DUPLEX_FULL)) { ++ bmcr_true_force = BMCR_SPEED100 | BMCR_FULLDPLX; ++ } ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, MII_BMCR, bmcr_true_force); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ } ++ ++ if (tp->mcfg == CFG_METHOD_11) ++ rtl8168dp_10mbps_gphy_para(dev); ++ ++ return 0; ++} ++ ++static int ++rtl8168_set_speed(struct net_device *dev, ++ u8 autoneg, ++ u16 speed, ++ u8 duplex) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ int ret; ++ ++ ret = tp->set_speed(dev, autoneg, speed, duplex); ++ ++ return ret; ++} ++ ++static int ++rtl8168_set_settings(struct net_device *dev, ++ struct ethtool_cmd *cmd) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&tp->lock, flags); ++ ret = rtl8168_set_speed(dev, cmd->autoneg, cmd->speed, cmd->duplex); ++ spin_unlock_irqrestore(&tp->lock, flags); ++ ++ return ret; ++} ++ ++static u32 ++rtl8168_get_tx_csum(struct net_device *dev) ++{ ++ return (dev->features & NETIF_F_IP_CSUM) != 0; ++} ++ ++static u32 ++rtl8168_get_rx_csum(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ return tp->cp_cmd & RxChkSum; ++} ++ ++static int ++rtl8168_set_tx_csum(struct net_device *dev, ++ u32 data) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ if (tp->mcfg == CFG_METHOD_DEFAULT) ++ return -EOPNOTSUPP; ++ ++ if (data) ++ dev->features |= NETIF_F_IP_CSUM; ++ else ++ dev->features &= ~NETIF_F_IP_CSUM; ++ ++ return 0; ++} ++ ++static int ++rtl8168_set_rx_csum(struct net_device *dev, ++ u32 data) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ unsigned long flags; ++ ++ if (tp->mcfg == CFG_METHOD_DEFAULT) ++ return -EOPNOTSUPP; ++ ++ spin_lock_irqsave(&tp->lock, flags); ++ ++ if (data) ++ tp->cp_cmd |= RxChkSum; ++ else ++ tp->cp_cmd &= ~RxChkSum; ++ ++ RTL_W16(CPlusCmd, tp->cp_cmd); ++ ++ spin_unlock_irqrestore(&tp->lock, flags); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_R8168_VLAN ++ ++static inline u32 ++rtl8168_tx_vlan_tag(struct rtl8168_private *tp, ++ struct sk_buff *skb) ++{ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) ++ return (tp->vlgrp && vlan_tx_tag_present(skb)) ? ++#else ++ return (vlan_tx_tag_present(skb)) ? ++#endif ++ TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) ++ ++static void ++rtl8168_vlan_rx_register(struct net_device *dev, ++ struct vlan_group *grp) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tp->lock, flags); ++ tp->vlgrp = grp; ++ if (tp->vlgrp) ++ tp->cp_cmd |= RxVlan; ++ else ++ tp->cp_cmd &= ~RxVlan; ++ RTL_W16(CPlusCmd, tp->cp_cmd); ++ RTL_R16(CPlusCmd); ++ spin_unlock_irqrestore(&tp->lock, flags); ++} ++ ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ++static void ++rtl8168_vlan_rx_kill_vid(struct net_device *dev, ++ unsigned short vid) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tp->lock, flags); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) ++ if (tp->vlgrp) ++ tp->vlgrp->vlan_devices[vid] = NULL; ++#else ++ vlan_group_set_device(tp->vlgrp, vid, NULL); ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) ++ spin_unlock_irqrestore(&tp->lock, flags); ++} ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ++ ++static int ++rtl8168_rx_vlan_skb(struct rtl8168_private *tp, ++ struct RxDesc *desc, ++ struct sk_buff *skb) ++{ ++ u32 opts2 = le32_to_cpu(desc->opts2); ++ int ret = -1; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) ++ if (tp->vlgrp && (opts2 & RxVlanTag)) { ++ rtl8168_rx_hwaccel_skb(skb, tp->vlgrp, ++ swab16(opts2 & 0xffff)); ++ ret = 0; ++ } ++#else ++ if (opts2 & RxVlanTag) ++ __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff)); ++#endif ++ ++ desc->opts2 = 0; ++ return ret; ++} ++ ++#else /* !CONFIG_R8168_VLAN */ ++ ++static inline u32 ++rtl8168_tx_vlan_tag(struct rtl8168_private *tp, ++ struct sk_buff *skb) ++{ ++ return 0; ++} ++ ++static int ++rtl8168_rx_vlan_skb(struct rtl8168_private *tp, ++ struct RxDesc *desc, ++ struct sk_buff *skb) ++{ ++ return -1; ++} ++ ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) ++ ++static u32 rtl8168_fix_features(struct net_device *dev, u32 features) ++{ ++ if (dev->mtu > MSSMask) ++ features &= ~NETIF_F_ALL_TSO; ++ ++ return features; ++} ++ ++static int rtl8168_set_features(struct net_device *dev, u32 features) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tp->lock, flags); ++ ++ if (features & NETIF_F_RXCSUM) ++ tp->cp_cmd |= RxChkSum; ++ else ++ tp->cp_cmd &= ~RxChkSum; ++ ++ if (dev->features & NETIF_F_HW_VLAN_RX) ++ tp->cp_cmd |= RxVlan; ++ else ++ tp->cp_cmd &= ~RxVlan; ++ ++ RTL_W16(CPlusCmd, tp->cp_cmd); ++ RTL_R16(CPlusCmd); ++ ++ spin_unlock_irqrestore(&tp->lock, flags); ++ ++ return 0; ++} ++ ++#endif ++ ++static void rtl8168_gset_xmii(struct net_device *dev, ++ struct ethtool_cmd *cmd) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ u8 status; ++ unsigned long flags; ++ ++ cmd->supported = SUPPORTED_10baseT_Half | ++ SUPPORTED_10baseT_Full | ++ SUPPORTED_100baseT_Half | ++ SUPPORTED_100baseT_Full | ++ SUPPORTED_1000baseT_Full | ++ SUPPORTED_Autoneg | ++ SUPPORTED_TP; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ cmd->autoneg = (mdio_read(tp, MII_BMCR) & BMCR_ANENABLE) ? 1 : 0; ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg; ++ ++ if (tp->phy_auto_nego_reg & ADVERTISE_10HALF) ++ cmd->advertising |= ADVERTISED_10baseT_Half; ++ if (tp->phy_auto_nego_reg & ADVERTISE_10FULL) ++ cmd->advertising |= ADVERTISED_10baseT_Full; ++ if (tp->phy_auto_nego_reg & ADVERTISE_100HALF) ++ cmd->advertising |= ADVERTISED_100baseT_Half; ++ if (tp->phy_auto_nego_reg & ADVERTISE_100FULL) ++ cmd->advertising |= ADVERTISED_100baseT_Full; ++ if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL) ++ cmd->advertising |= ADVERTISED_1000baseT_Full; ++ ++ status = RTL_R8(PHYstatus); ++ ++ if (status & _1000bpsF) ++ cmd->speed = SPEED_1000; ++ else if (status & _100bps) ++ cmd->speed = SPEED_100; ++ else if (status & _10bps) ++ cmd->speed = SPEED_10; ++ ++ if (status & TxFlowCtrl) ++ cmd->advertising |= ADVERTISED_Asym_Pause; ++ ++ if (status & RxFlowCtrl) ++ cmd->advertising |= ADVERTISED_Pause; ++ ++ cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ? ++ DUPLEX_FULL : DUPLEX_HALF; ++ ++ ++} ++ ++static int ++rtl8168_get_settings(struct net_device *dev, ++ struct ethtool_cmd *cmd) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tp->lock, flags); ++ ++ tp->get_settings(dev, cmd); ++ ++ spin_unlock_irqrestore(&tp->lock, flags); ++ return 0; ++} ++ ++static void rtl8168_get_regs(struct net_device *dev, struct ethtool_regs *regs, ++ void *p) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ unsigned long flags; ++ ++ if (regs->len > R8168_REGS_SIZE) ++ regs->len = R8168_REGS_SIZE; ++ ++ spin_lock_irqsave(&tp->lock, flags); ++ memcpy_fromio(p, tp->mmio_addr, regs->len); ++ spin_unlock_irqrestore(&tp->lock, flags); ++} ++ ++static u32 ++rtl8168_get_msglevel(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ return tp->msg_enable; ++} ++ ++static void ++rtl8168_set_msglevel(struct net_device *dev, ++ u32 value) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ tp->msg_enable = value; ++} ++ ++static const char rtl8168_gstrings[][ETH_GSTRING_LEN] = { ++ "tx_packets", ++ "rx_packets", ++ "tx_errors", ++ "rx_errors", ++ "rx_missed", ++ "align_errors", ++ "tx_single_collisions", ++ "tx_multi_collisions", ++ "unicast", ++ "broadcast", ++ "multicast", ++ "tx_aborted", ++ "tx_underrun", ++}; ++ ++struct rtl8168_counters { ++ u64 tx_packets; ++ u64 rx_packets; ++ u64 tx_errors; ++ u32 rx_errors; ++ u16 rx_missed; ++ u16 align_errors; ++ u32 tx_one_collision; ++ u32 tx_multi_collision; ++ u64 rx_unicast; ++ u64 rx_broadcast; ++ u32 rx_multicast; ++ u16 tx_aborted; ++ u16 tx_underun; ++}; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) ++static int rtl8168_get_stats_count(struct net_device *dev) ++{ ++ return ARRAY_SIZE(rtl8168_gstrings); ++} ++#else ++static int rtl8168_get_sset_count(struct net_device *dev, int sset) ++{ ++ switch (sset) { ++ case ETH_SS_STATS: ++ return ARRAY_SIZE(rtl8168_gstrings); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++#endif ++static void ++rtl8168_get_ethtool_stats(struct net_device *dev, ++ struct ethtool_stats *stats, ++ u64 *data) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ struct rtl8168_counters *counters; ++ dma_addr_t paddr; ++ u32 cmd; ++ ++ ASSERT_RTNL(); ++ ++ counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr); ++ if (!counters) ++ return; ++ ++ RTL_W32(CounterAddrHigh, (u64)paddr >> 32); ++ cmd = (u64)paddr & DMA_BIT_MASK(32); ++ RTL_W32(CounterAddrLow, cmd); ++ RTL_W32(CounterAddrLow, cmd | CounterDump); ++ ++ while (RTL_R32(CounterAddrLow) & CounterDump) { ++ if (msleep_interruptible(1)) ++ break; ++ } ++ ++ RTL_W32(CounterAddrLow, 0); ++ RTL_W32(CounterAddrHigh, 0); ++ ++ data[0] = le64_to_cpu(counters->tx_packets); ++ data[1] = le64_to_cpu(counters->rx_packets); ++ data[2] = le64_to_cpu(counters->tx_errors); ++ data[3] = le32_to_cpu(counters->rx_errors); ++ data[4] = le16_to_cpu(counters->rx_missed); ++ data[5] = le16_to_cpu(counters->align_errors); ++ data[6] = le32_to_cpu(counters->tx_one_collision); ++ data[7] = le32_to_cpu(counters->tx_multi_collision); ++ data[8] = le64_to_cpu(counters->rx_unicast); ++ data[9] = le64_to_cpu(counters->rx_broadcast); ++ data[10] = le32_to_cpu(counters->rx_multicast); ++ data[11] = le16_to_cpu(counters->tx_aborted); ++ data[12] = le16_to_cpu(counters->tx_underun); ++ pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr); ++} ++ ++static void ++rtl8168_get_strings(struct net_device *dev, ++ u32 stringset, ++ u8 *data) ++{ ++ switch (stringset) { ++ case ETH_SS_STATS: ++ memcpy(data, *rtl8168_gstrings, sizeof(rtl8168_gstrings)); ++ break; ++ } ++} ++static int rtl_get_eeprom_len(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ return tp->eeprom_len; ++} ++ ++static int rtl_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *buf) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ int i,j,ret; ++ int start_w, end_w; ++ int VPD_addr, VPD_data; ++ u32 *eeprom_buff; ++ u16 tmp; ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ if (tp->eeprom_type==EEPROM_TYPE_NONE) ++ { ++ dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Detect none EEPROM\n"); ++ return -EOPNOTSUPP; ++ } ++ else if (eeprom->len == 0 || (eeprom->offset+eeprom->len) > tp->eeprom_len) ++ { ++ dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Invalid parameter\n"); ++ return -EINVAL; ++ } ++ ++ switch (tp->mcfg) ++ { ++ case CFG_METHOD_9: ++ case CFG_METHOD_10: ++ VPD_addr = 0xCE; ++ VPD_data = 0xD0; ++ break; ++ ++ case CFG_METHOD_4: ++ case CFG_METHOD_5: ++ case CFG_METHOD_6: ++ case CFG_METHOD_7: ++ case CFG_METHOD_8: ++ case CFG_METHOD_14: ++ case CFG_METHOD_15: ++ VPD_addr = 0xD2; ++ VPD_data = 0xD4; ++ break; ++ ++ case CFG_METHOD_1: ++ case CFG_METHOD_2: ++ case CFG_METHOD_3: ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ start_w = eeprom->offset >> 2; ++ end_w = (eeprom->offset + eeprom->len - 1) >> 2; ++ ++ eeprom_buff = kmalloc(sizeof(u32)*(end_w - start_w + 1), GFP_KERNEL); ++ if (!eeprom_buff) ++ { ++ return -ENOMEM; ++ } ++ ++ RTL_W8(Cfg9346, Cfg9346_Unlock); ++ ret = -EFAULT; ++ for (i=start_w; i<=end_w; i++) ++ { ++ pci_write_config_word(tp->pci_dev, VPD_addr, (u16)i*4); ++ ret = -EFAULT; ++ for (j=0;j<10;j++) ++ { ++ udelay(400); ++ pci_read_config_word(tp->pci_dev, VPD_addr, &tmp); ++ if (tmp&0x8000) ++ { ++ ret = 0; ++ break; ++ } ++ } ++ ++ if (ret) ++ { ++ break; ++ } ++ ++ pci_read_config_dword(tp->pci_dev, VPD_data, &eeprom_buff[i-start_w]); ++ } ++ RTL_W8(Cfg9346, Cfg9346_Lock); ++ ++ if (!ret) ++ { ++ memcpy(buf, (u8 *)eeprom_buff + (eeprom->offset & 3), eeprom->len); ++ } ++ ++ kfree(eeprom_buff); ++ ++ return ret; ++} ++ ++#undef ethtool_op_get_link ++#define ethtool_op_get_link _kc_ethtool_op_get_link ++u32 _kc_ethtool_op_get_link(struct net_device *dev) ++{ ++ return netif_carrier_ok(dev) ? 1 : 0; ++} ++ ++#undef ethtool_op_get_sg ++#define ethtool_op_get_sg _kc_ethtool_op_get_sg ++u32 _kc_ethtool_op_get_sg(struct net_device *dev) ++{ ++#ifdef NETIF_F_SG ++ return (dev->features & NETIF_F_SG) != 0; ++#else ++ return 0; ++#endif ++} ++ ++#undef ethtool_op_set_sg ++#define ethtool_op_set_sg _kc_ethtool_op_set_sg ++int _kc_ethtool_op_set_sg(struct net_device *dev, u32 data) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ if (tp->mcfg == CFG_METHOD_DEFAULT) ++ return -EOPNOTSUPP; ++ ++#ifdef NETIF_F_SG ++ if (data) ++ dev->features |= NETIF_F_SG; ++ else ++ dev->features &= ~NETIF_F_SG; ++#endif ++ ++ return 0; ++} ++ ++static struct ethtool_ops rtl8168_ethtool_ops = { ++ .get_drvinfo = rtl8168_get_drvinfo, ++ .get_regs_len = rtl8168_get_regs_len, ++ .get_link = ethtool_op_get_link, ++ .get_settings = rtl8168_get_settings, ++ .set_settings = rtl8168_set_settings, ++ .get_msglevel = rtl8168_get_msglevel, ++ .set_msglevel = rtl8168_set_msglevel, ++ .get_rx_csum = rtl8168_get_rx_csum, ++ .set_rx_csum = rtl8168_set_rx_csum, ++ .get_tx_csum = rtl8168_get_tx_csum, ++ .set_tx_csum = rtl8168_set_tx_csum, ++ .get_sg = ethtool_op_get_sg, ++ .set_sg = ethtool_op_set_sg, ++#ifdef NETIF_F_TSO ++ .get_tso = ethtool_op_get_tso, ++ .set_tso = ethtool_op_set_tso, ++#endif ++ .get_regs = rtl8168_get_regs, ++ .get_wol = rtl8168_get_wol, ++ .set_wol = rtl8168_set_wol, ++ .get_strings = rtl8168_get_strings, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) ++ .get_stats_count = rtl8168_get_stats_count, ++#else ++ .get_sset_count = rtl8168_get_sset_count, ++#endif ++ .get_ethtool_stats = rtl8168_get_ethtool_stats, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) ++#ifdef ETHTOOL_GPERMADDR ++ .get_perm_addr = ethtool_op_get_perm_addr, ++#endif ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) ++ .get_eeprom = rtl_get_eeprom, ++ .get_eeprom_len = rtl_get_eeprom_len, ++}; ++ ++ ++static int rtl8168_enable_EEE(struct rtl8168_private *tp) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ int ret; ++ unsigned long flags; ++ __u16 data; ++ ++ ret = 0; ++ switch (tp->mcfg) { ++ case CFG_METHOD_14: ++ case CFG_METHOD_15: ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x0020); ++ data = mdio_read(tp, 0x15) | 0x0100; ++ mdio_write(tp, 0x15, data); ++ mdio_write(tp, 0x1F, 0x0006); ++ mdio_write(tp, 0x00, 0x5A30); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x0D, 0x0007); ++ mdio_write(tp, 0x0E, 0x003C); ++ mdio_write(tp, 0x0D, 0x4007); ++ mdio_write(tp, 0x0E, 0x0006); ++ mdio_write(tp, 0x0D, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ if((RTL_R8(Config4)&0x40) && (RTL_R8(0x6D) & BIT_7)) ++ { ++ data = RTL_R16(CustomLED); ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8AC8); ++ mdio_write(tp, 0x06, data); ++ mdio_write(tp, 0x05, 0x8B82); ++ data = mdio_read(tp, 0x06) | 0x0010; ++ mdio_write(tp, 0x05, 0x8B82); ++ mdio_write(tp, 0x06, data); ++ mdio_write(tp, 0x1F, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ } ++ break; ++ ++ case CFG_METHOD_16: ++ case CFG_METHOD_17: ++ spin_lock_irqsave(&tp->phy_lock,flags); ++ data = rtl8168_eri_read(ioaddr,0x1B0 ,4,ERIAR_ExGMAC) | 0x0003; ++ rtl8168_eri_write(ioaddr, 0x1B0, 4, data, ERIAR_ExGMAC); ++ mdio_write(tp,0x1F , 0x0004); ++ mdio_write(tp,0x1F , 0x0007); ++ mdio_write(tp,0x1E , 0x0020); ++ data = mdio_read(tp, 0x15)|0x0100; ++ mdio_write(tp,0x15 , data); ++ mdio_write(tp,0x1F , 0x0002); ++ mdio_write(tp,0x1F , 0x0005); ++ mdio_write(tp,0x05 , 0x8B85); ++ data = mdio_read(tp, 0x06)|0x2000; ++ mdio_write(tp,0x06 , data); ++ mdio_write(tp,0x1F , 0x0000); ++ mdio_write(tp,0x0D , 0x0007); ++ mdio_write(tp,0x0E , 0x003C); ++ mdio_write(tp,0x0D , 0x4007); ++ mdio_write(tp,0x0E , 0x0006); ++ mdio_write(tp,0x1D , 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock,flags); ++ break; ++ ++ case CFG_METHOD_18: ++ case CFG_METHOD_19: ++ case CFG_METHOD_20: ++ spin_lock_irqsave(&tp->phy_lock,flags); ++ data = rtl8168_eri_read(ioaddr,0x1B0 ,4,ERIAR_ExGMAC); ++ data |= BIT_1 | BIT_0; ++ rtl8168_eri_write(ioaddr, 0x1B0, 4, data, ERIAR_ExGMAC); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1e, 0x0020); ++ data = mdio_read(tp, 0x15); ++ data |= BIT_8; ++ mdio_write(tp, 0x15, data); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B85); ++ data = mdio_read(tp, 0x06); ++ data |= BIT_13; ++ mdio_write(tp, 0x06, data); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x0D, 0x0007); ++ mdio_write(tp, 0x0E, 0x003C); ++ mdio_write(tp, 0x0D, 0x4007); ++ mdio_write(tp, 0x0E, 0x0006); ++ mdio_write(tp, 0x0D, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock,flags); ++ break; ++ ++ default: ++// dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Not Support EEE\n"); ++ ret = -EOPNOTSUPP; ++ } ++ ++ return ret; ++} ++ ++static int rtl8168_disable_EEE(struct rtl8168_private *tp) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ int ret; ++ unsigned long flags; ++ __u16 data; ++ ++ ret = 0; ++ switch (tp->mcfg) { ++ case CFG_METHOD_14: ++ case CFG_METHOD_15: ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x0020); ++ data = mdio_read(tp, 0x15) & ~0x0100; ++ mdio_write(tp, 0x15, data); ++ mdio_write(tp, 0x1F, 0x0006); ++ mdio_write(tp, 0x00, 0x5A00); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x0D, 0x0007); ++ mdio_write(tp, 0x0E, 0x003C); ++ mdio_write(tp, 0x0D, 0x4007); ++ mdio_write(tp, 0x0E, 0x0000); ++ mdio_write(tp, 0x0D, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ if (RTL_R8(Config4) & 0x40) ++ { ++ data = RTL_R16(CustomLED); ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B82); ++ data = mdio_read(tp, 0x06) & ~0x0010; ++ mdio_write(tp, 0x05, 0x8B82); ++ mdio_write(tp, 0x06, data); ++ mdio_write(tp, 0x1F, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ } ++ break; ++ ++ case CFG_METHOD_16: ++ case CFG_METHOD_17: ++ spin_lock_irqsave(&tp->phy_lock,flags); ++ data = rtl8168_eri_read(ioaddr,0x1B0 ,4,ERIAR_ExGMAC)& ~0x0003; ++ rtl8168_eri_write(ioaddr, 0x1B0, 4, data, ERIAR_ExGMAC); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B85); ++ data = mdio_read(tp, 0x06) & ~0x2000; ++ mdio_write(tp, 0x06, data); ++ mdio_write(tp, 0x1F, 0x0004); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x0020); ++ data = mdio_read(tp, 0x15) & ~0x0100; ++ mdio_write(tp,0x15 , data); ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x0D, 0x0007); ++ mdio_write(tp, 0x0E, 0x003C); ++ mdio_write(tp, 0x0D, 0x4007); ++ mdio_write(tp, 0x0E, 0x0000); ++ mdio_write(tp, 0x0D, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ break; ++ ++ case CFG_METHOD_18: ++ case CFG_METHOD_19: ++ case CFG_METHOD_20: ++ spin_lock_irqsave(&tp->phy_lock,flags); ++ data = rtl8168_eri_read(ioaddr,0x1B0 ,4,ERIAR_ExGMAC); ++ data &= ~(BIT_1 | BIT_0); ++ rtl8168_eri_write(ioaddr, 0x1B0, 4, data, ERIAR_ExGMAC); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B85); ++ data = mdio_read(tp, 0x06); ++ data &= ~BIT_13; ++ mdio_write(tp, 0x06, data); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1e, 0x0020); ++ data = mdio_read(tp, 0x15); ++ data &= ~BIT_8; ++ mdio_write(tp, 0x15, data); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x0D, 0x0007); ++ mdio_write(tp, 0x0E, 0x003C); ++ mdio_write(tp, 0x0D, 0x4007); ++ mdio_write(tp, 0x0E, 0x0000); ++ mdio_write(tp, 0x0D, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock,flags); ++ break; ++ ++ default: ++// dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Not Support EEE\n"); ++ ret = -EOPNOTSUPP; ++ break; ++ } ++ ++ return ret; ++} ++ ++static int rtl8168_green_table(struct rtl8168_private *tp) ++{ ++ struct pci_dev *pdev = tp->pci_dev; ++ unsigned long flags; ++ u16 gphy_val; ++ int i; ++ static const u16 evl_phy_value[] = { ++ 0x8B56, 0x8B5F, 0x8B68, 0x8B71, ++ 0x8B7A, 0x8A7B, 0x8A7E, 0x8A81, ++ 0x8A84, 0x8A87 ++ }; ++ ++ switch (tp->mcfg) { ++ case CFG_METHOD_16: ++ case CFG_METHOD_17: ++ if (pdev->subsystem_vendor == 0x1043 && ++ pdev->subsystem_device == 0x13F7) { ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0005); ++ for (i=0; i < ARRAY_SIZE(evl_phy_value); i++) { ++ mdio_write(tp, 0x05, evl_phy_value[i]); ++ gphy_val = (0xAA << 8) | (mdio_read(tp, 0x06) & 0xFF); ++ mdio_write(tp, 0x06, gphy_val); ++ } ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x0078); ++ mdio_write(tp, 0x17, 0x51AA); ++ mdio_write(tp, 0x1F, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ } ++ break; ++ default: ++ break; ++ } ++ ++ switch (tp->mcfg) { ++ case CFG_METHOD_16: ++ case CFG_METHOD_17: ++ case CFG_METHOD_18: ++ case CFG_METHOD_19: ++ case CFG_METHOD_20: ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0x8B54); ++ mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_11); ++ mdio_write(tp, 0x05, 0x8B5D); ++ mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_11); ++ mdio_write(tp, 0x05, 0x8A7C); ++ mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_8); ++ mdio_write(tp, 0x05, 0x8A7F); ++ mdio_write(tp, 0x06, mdio_read(tp, 0x06) | BIT_8); ++ mdio_write(tp, 0x05, 0x8A82); ++ mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_8); ++ mdio_write(tp, 0x05, 0x8A85); ++ mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_8); ++ mdio_write(tp, 0x05, 0x8A88); ++ mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_8); ++ mdio_write(tp, 0x1f, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++#if 0 ++ ++static int rtl8168_enable_green_feature(struct rtl8168_private *tp) ++{ ++ unsigned long flags; ++ u16 gphy_val; ++ ++ switch (tp->mcfg) { ++ case CFG_METHOD_14: ++ case CFG_METHOD_15: ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0003); ++ gphy_val = mdio_read(tp, 0x10) | 0x0400; ++ mdio_write(tp, 0x10, gphy_val); ++ gphy_val = mdio_read(tp, 0x19) | 0x0001; ++ mdio_write(tp, 0x19, gphy_val); ++ mdio_write(tp, 0x1F, 0x0005); ++ gphy_val = mdio_read(tp, 0x01) & ~0x0100; ++ mdio_write(tp, 0x01, gphy_val); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x00, 0x9200); ++ mdelay(20); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ break; ++ ++ case CFG_METHOD_17: ++ case CFG_METHOD_18: ++ case CFG_METHOD_19: ++ case CFG_METHOD_20: ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1f, 0x0003); ++ gphy_val = mdio_read(tp, 0x10); ++ gphy_val |= BIT_10; ++ mdio_write(tp, 0x10, gphy_val); ++ gphy_val = mdio_read(tp, 0x19); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x19, gphy_val); ++ mdio_write(tp, 0x1F, 0x0005); ++ gphy_val = mdio_read(tp, 0x01); ++ gphy_val |= BIT_8; ++ mdio_write(tp, 0x01, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x9200); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ break; ++ ++ default: ++ dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Not Support Green Feature\n"); ++ break; ++ } ++ ++ return 0; ++} ++ ++static int rtl8168_disable_green_feature(struct rtl8168_private *tp) ++{ ++ unsigned long flags; ++ u16 gphy_val; ++ ++ switch (tp->mcfg) { ++ case CFG_METHOD_14: ++ case CFG_METHOD_15: ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0005); ++ gphy_val = mdio_read(tp, 0x01) | 0x0100; ++ mdio_write(tp, 0x01, gphy_val); ++ mdio_write(tp, 0x1F, 0x0003); ++ gphy_val = mdio_read(tp, 0x10) & ~0x0400; ++ mdio_write(tp, 0x10, gphy_val); ++ gphy_val = mdio_read(tp, 0x19) & ~0x0001; ++ mdio_write(tp, 0x19, gphy_val); ++ mdio_write(tp, 0x1F, 0x0002); ++ gphy_val = mdio_read(tp, 0x06) & ~0x7000; ++ gphy_val |= 0x3000; ++ mdio_write(tp, 0x06, gphy_val); ++ gphy_val = mdio_read(tp, 0x0D) & 0x0700; ++ gphy_val |= 0x0500; ++ mdio_write(tp, 0x0D, gphy_val); ++ mdio_write(tp, 0x1F, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ break; ++ ++ case CFG_METHOD_17: ++ case CFG_METHOD_18: ++ case CFG_METHOD_19: ++ case CFG_METHOD_20: ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1f, 0x0003); ++ gphy_val = mdio_read(tp, 0x19); ++ gphy_val &= ~BIT_0; ++ mdio_write(tp, 0x19, gphy_val); ++ gphy_val = mdio_read(tp, 0x10); ++ gphy_val &= ~BIT_10; ++ mdio_write(tp, 0x10, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ break; ++ ++ default: ++ dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Not Support Green Feature\n"); ++ break; ++ } ++ ++ return 0; ++} ++ ++#endif ++ ++static void rtl8168_get_mac_version(struct rtl8168_private *tp, void __iomem *ioaddr) ++{ ++ u32 reg,val32; ++ u32 ICVerID; ++ ++ val32 = RTL_R32(TxConfig) ; ++ reg = val32 & 0x7c800000; ++ ICVerID = val32 & 0x00700000; ++ ++ switch (reg) { ++ case 0x30000000: ++ tp->mcfg = CFG_METHOD_1; ++ tp->efuse = EFUSE_NOT_SUPPORT; ++ break; ++ case 0x38000000: ++ if (ICVerID == 0x00000000) { ++ tp->mcfg = CFG_METHOD_2; ++ } else if (ICVerID == 0x00500000) { ++ tp->mcfg = CFG_METHOD_3; ++ } else { ++ tp->mcfg = CFG_METHOD_3; ++ } ++ tp->efuse = EFUSE_NOT_SUPPORT; ++ break; ++ case 0x3C000000: ++ if (ICVerID == 0x00000000) { ++ tp->mcfg = CFG_METHOD_4; ++ } else if (ICVerID == 0x00200000) { ++ tp->mcfg = CFG_METHOD_5; ++ } else if (ICVerID == 0x00400000) { ++ tp->mcfg = CFG_METHOD_6; ++ } else { ++ tp->mcfg = CFG_METHOD_6; ++ } ++ tp->efuse = EFUSE_NOT_SUPPORT; ++ break; ++ case 0x3C800000: ++ if (ICVerID == 0x00100000){ ++ tp->mcfg = CFG_METHOD_7; ++ } else if (ICVerID == 0x00300000){ ++ tp->mcfg = CFG_METHOD_8; ++ } else { ++ tp->mcfg = CFG_METHOD_8; ++ } ++ tp->efuse = EFUSE_NOT_SUPPORT; ++ break; ++ case 0x28000000: ++ if (ICVerID == 0x00100000) { ++ tp->mcfg = CFG_METHOD_9; ++ } else if (ICVerID == 0x00300000) { ++ tp->mcfg = CFG_METHOD_10; ++ } else { ++ tp->mcfg = CFG_METHOD_10; ++ } ++ tp->efuse = EFUSE_SUPPORT; ++ break; ++ case 0x28800000: ++ if (ICVerID == 0x00000000) ++ tp->mcfg = CFG_METHOD_11; ++ else if (ICVerID == 0x00200000) { ++ tp->mcfg = CFG_METHOD_12; ++ RTL_W32(0xD0, RTL_R32(0xD0) | 0x00020000); ++ } else// if (ICVerID == 0x00300000) ++ tp->mcfg = CFG_METHOD_13; ++ tp->efuse = EFUSE_SUPPORT; ++ break; ++ case 0x2C000000: ++ if (ICVerID == 0x00100000) ++ tp->mcfg = CFG_METHOD_14; ++ else if (ICVerID == 0x00200000) ++ tp->mcfg = CFG_METHOD_15; ++ tp->efuse = EFUSE_SUPPORT; ++ break; ++ case 0x2C800000: ++ if (ICVerID == 0x00000000) ++ tp->mcfg = CFG_METHOD_16; ++ else if (ICVerID == 0x00100000) ++ tp->mcfg = CFG_METHOD_17; ++ tp->efuse = EFUSE_SUPPORT; ++ break; ++ case 0x48000000: ++ if (ICVerID == 0x00000000) ++ tp->mcfg = CFG_METHOD_18; ++ else if (ICVerID == 0x00100000) ++ tp->mcfg = CFG_METHOD_19; ++ tp->efuse = EFUSE_SUPPORT; ++ break; ++ case 0x48800000: ++ tp->mcfg = CFG_METHOD_20; ++ tp->efuse = EFUSE_SUPPORT; ++ break; ++ default: ++ printk("unknown chip version (%x)\n",reg); ++ tp->mcfg = CFG_METHOD_DEFAULT; ++ tp->efuse = EFUSE_NOT_SUPPORT; ++ break; ++ } ++} ++ ++static void ++rtl8168_print_mac_version(struct rtl8168_private *tp) ++{ ++ int i; ++ for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) { ++ if (tp->mcfg == rtl_chip_info[i].mcfg){ ++ dprintk("mcfg == %s (%04d)\n", rtl_chip_info[i].name, ++ rtl_chip_info[i].mcfg); ++ return; ++ } ++ } ++ ++ dprintk("mac_version == Unknown\n"); ++} ++ ++static u8 rtl8168_efuse_read(struct rtl8168_private *tp, u16 reg) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ u8 efuse_data; ++ u32 temp; ++ int cnt; ++ ++ if (tp->efuse == EFUSE_NOT_SUPPORT) ++ return EFUSE_READ_FAIL; ++ ++ temp = EFUSE_READ | ((reg & EFUSE_Reg_Mask) << EFUSE_Reg_Shift); ++ RTL_W32(EFUSEAR, temp); ++ ++ do { ++ udelay(100); ++ temp = RTL_R32(EFUSEAR); ++ cnt++; ++ } while (!(temp & EFUSE_READ_OK) && (temp < EFUSE_Check_Cnt)); ++ ++ if (temp == EFUSE_Check_Cnt) ++ efuse_data = EFUSE_READ_FAIL; ++ else ++ efuse_data = (u8)(RTL_R32(EFUSEAR) & EFUSE_Data_Mask); ++ ++ return efuse_data; ++} ++ ++static void ++rtl8168_hw_phy_config(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ unsigned long flags; ++ unsigned int gphy_val,i; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ ++ if (tp->mcfg == CFG_METHOD_1) { ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x0B, 0x94B0); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x12, 0x6096); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x0D, 0xF8A0); ++ } else if (tp->mcfg == CFG_METHOD_2) { ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x0B, 0x94B0); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x12, 0x6096); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ } else if (tp->mcfg == CFG_METHOD_3) { ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x0B, 0x94B0); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x12, 0x6096); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ } else if (tp->mcfg == CFG_METHOD_4) { ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x12, 0x2300); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x16, 0x000A); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x12, 0xC096); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x00, 0x88DE); ++ mdio_write(tp, 0x01, 0x82B1); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x08, 0x9E30); ++ mdio_write(tp, 0x09, 0x01F0); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x0A, 0x5500); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x03, 0x7002); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x0C, 0x00C8); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x14, mdio_read(tp, 0x14) | (1 << 5)); ++ mdio_write(tp, 0x0D, mdio_read(tp, 0x0D) & ~(1 << 5)); ++ } else if (tp->mcfg == CFG_METHOD_5) { ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x12, 0x2300); ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x16, 0x0F0A); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x00, 0x88DE); ++ mdio_write(tp, 0x01, 0x82B1); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x0C, 0x7EB8); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x06, 0x0761); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x03, 0x802F); ++ mdio_write(tp, 0x02, 0x4F02); ++ mdio_write(tp, 0x01, 0x0409); ++ mdio_write(tp, 0x00, 0xF099); ++ mdio_write(tp, 0x04, 0x9800); ++ mdio_write(tp, 0x04, 0x9000); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x16, mdio_read(tp, 0x16) | (1 << 0)); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x14, mdio_read(tp, 0x14) | (1 << 5)); ++ mdio_write(tp, 0x0D, mdio_read(tp, 0x0D) & ~(1 << 5)); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x1D, 0x3D98); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x17, 0x0CC0); ++ mdio_write(tp, 0x1F, 0x0000); ++ } else if (tp->mcfg == CFG_METHOD_6) { ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x12, 0x2300); ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x16, 0x0F0A); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x00, 0x88DE); ++ mdio_write(tp, 0x01, 0x82B1); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x0C, 0x7EB8); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x06, 0x5461); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x06, 0x5461); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x16, mdio_read(tp, 0x16) | (1 << 0)); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x14, mdio_read(tp, 0x14) | (1 << 5)); ++ mdio_write(tp, 0x0D, mdio_read(tp, 0x0D) & ~(1 << 5)); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x1D, 0x3D98); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1f, 0x0001); ++ mdio_write(tp, 0x17, 0x0CC0); ++ mdio_write(tp, 0x1F, 0x0000); ++ } else if (tp->mcfg == CFG_METHOD_7) { ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x14, mdio_read(tp, 0x14) | (1 << 5)); ++ mdio_write(tp, 0x0D, mdio_read(tp, 0x0D) & ~(1 << 5)); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x1D, 0x3D98); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x14, 0xCAA3); ++ mdio_write(tp, 0x1C, 0x000A); ++ mdio_write(tp, 0x18, 0x65D0); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x17, 0xB580); ++ mdio_write(tp, 0x18, 0xFF54); ++ mdio_write(tp, 0x19, 0x3954); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x0D, 0x310C); ++ mdio_write(tp, 0x0E, 0x310C); ++ mdio_write(tp, 0x0F, 0x311C); ++ mdio_write(tp, 0x06, 0x0761); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x18, 0xFF55); ++ mdio_write(tp, 0x19, 0x3955); ++ mdio_write(tp, 0x18, 0xFF54); ++ mdio_write(tp, 0x19, 0x3954); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x17, 0x0CC0); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ } else if (tp->mcfg == CFG_METHOD_8) { ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x14, mdio_read(tp, 0x14) | (1 << 5)); ++ mdio_write(tp, 0x0D, mdio_read(tp, 0x0D) & ~(1 << 5)); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x14, 0xCAA3); ++ mdio_write(tp, 0x1C, 0x000A); ++ mdio_write(tp, 0x18, 0x65D0); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x17, 0xB580); ++ mdio_write(tp, 0x18, 0xFF54); ++ mdio_write(tp, 0x19, 0x3954); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x0D, 0x310C); ++ mdio_write(tp, 0x0E, 0x310C); ++ mdio_write(tp, 0x0F, 0x311C); ++ mdio_write(tp, 0x06, 0x0761); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x18, 0xFF55); ++ mdio_write(tp, 0x19, 0x3955); ++ mdio_write(tp, 0x18, 0xFF54); ++ mdio_write(tp, 0x19, 0x3954); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x17, 0x0CC0); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x16, mdio_read(tp, 0x16) | (1 << 0)); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ } else if (tp->mcfg == CFG_METHOD_9) { ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x06, 0x4064); ++ mdio_write(tp, 0x07, 0x2863); ++ mdio_write(tp, 0x08, 0x059C); ++ mdio_write(tp, 0x09, 0x26B4); ++ mdio_write(tp, 0x0A, 0x6A19); ++ mdio_write(tp, 0x0B, 0xDCC8); ++ mdio_write(tp, 0x10, 0xF06D); ++ mdio_write(tp, 0x14, 0x7F68); ++ mdio_write(tp, 0x18, 0x7FD9); ++ mdio_write(tp, 0x1C, 0xF0FF); ++ mdio_write(tp, 0x1D, 0x3D9C); ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x12, 0xF49F); ++ mdio_write(tp, 0x13, 0x070B); ++ mdio_write(tp, 0x1A, 0x05AD); ++ mdio_write(tp, 0x14, 0x94C0); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ gphy_val = mdio_read(tp, 0x0B) & 0xFF00; ++ gphy_val |= 0x10; ++ mdio_write(tp, 0x0B, gphy_val); ++ gphy_val = mdio_read(tp, 0x0C) & 0x00FF; ++ gphy_val |= 0xA200; ++ mdio_write(tp, 0x0C, gphy_val); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x06, 0x5561); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8332); ++ mdio_write(tp, 0x06, 0x5561); ++ ++ if (rtl8168_efuse_read(tp, 0x01) == 0xb1) { ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x05, 0x669A); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8330); ++ mdio_write(tp, 0x06, 0x669A); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ gphy_val = mdio_read(tp, 0x0D); ++ if ((gphy_val & 0x00FF) != 0x006C) { ++ gphy_val &= 0xFF00; ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x0D, gphy_val | 0x0065); ++ mdio_write(tp, 0x0D, gphy_val | 0x0066); ++ mdio_write(tp, 0x0D, gphy_val | 0x0067); ++ mdio_write(tp, 0x0D, gphy_val | 0x0068); ++ mdio_write(tp, 0x0D, gphy_val | 0x0069); ++ mdio_write(tp, 0x0D, gphy_val | 0x006A); ++ mdio_write(tp, 0x0D, gphy_val | 0x006B); ++ mdio_write(tp, 0x0D, gphy_val | 0x006C); ++ } ++ } else { ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x05, 0x6662); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8330); ++ mdio_write(tp, 0x06, 0x6662); ++ } ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ gphy_val = mdio_read(tp, 0x0D); ++ gphy_val |= BIT_9; ++ gphy_val |= BIT_8; ++ mdio_write(tp, 0x0D, gphy_val); ++ gphy_val = mdio_read(tp, 0x0F); ++ gphy_val |= BIT_4; ++ mdio_write(tp, 0x0F, gphy_val); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ gphy_val = mdio_read(tp, 0x02); ++ gphy_val &= ~BIT_10; ++ gphy_val &= ~BIT_9; ++ gphy_val |= BIT_8; ++ mdio_write(tp, 0x02, gphy_val); ++ gphy_val = mdio_read(tp, 0x03); ++ gphy_val &= ~BIT_15; ++ gphy_val &= ~BIT_14; ++ gphy_val &= ~BIT_13; ++ mdio_write(tp, 0x03, gphy_val); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x17, 0x0CC0); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x001B); ++ if (mdio_read(tp, 0x06) == 0xBF00) { ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x05, 0x8000); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x59ee); ++ mdio_write(tp, 0x06, 0xf8ea); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0xf8eb); ++ mdio_write(tp, 0x06, 0x00e0); ++ mdio_write(tp, 0x06, 0xf87c); ++ mdio_write(tp, 0x06, 0xe1f8); ++ mdio_write(tp, 0x06, 0x7d59); ++ mdio_write(tp, 0x06, 0x0fef); ++ mdio_write(tp, 0x06, 0x0139); ++ mdio_write(tp, 0x06, 0x029e); ++ mdio_write(tp, 0x06, 0x06ef); ++ mdio_write(tp, 0x06, 0x1039); ++ mdio_write(tp, 0x06, 0x089f); ++ mdio_write(tp, 0x06, 0x2aee); ++ mdio_write(tp, 0x06, 0xf8ea); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0xf8eb); ++ mdio_write(tp, 0x06, 0x01e0); ++ mdio_write(tp, 0x06, 0xf87c); ++ mdio_write(tp, 0x06, 0xe1f8); ++ mdio_write(tp, 0x06, 0x7d58); ++ mdio_write(tp, 0x06, 0x409e); ++ mdio_write(tp, 0x06, 0x0f39); ++ mdio_write(tp, 0x06, 0x46aa); ++ mdio_write(tp, 0x06, 0x0bbf); ++ mdio_write(tp, 0x06, 0x8290); ++ mdio_write(tp, 0x06, 0xd682); ++ mdio_write(tp, 0x06, 0x9802); ++ mdio_write(tp, 0x06, 0x014f); ++ mdio_write(tp, 0x06, 0xae09); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0x98d6); ++ mdio_write(tp, 0x06, 0x82a0); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x4fef); ++ mdio_write(tp, 0x06, 0x95fe); ++ mdio_write(tp, 0x06, 0xfdfc); ++ mdio_write(tp, 0x06, 0x05f8); ++ mdio_write(tp, 0x06, 0xf9fa); ++ mdio_write(tp, 0x06, 0xeef8); ++ mdio_write(tp, 0x06, 0xea00); ++ mdio_write(tp, 0x06, 0xeef8); ++ mdio_write(tp, 0x06, 0xeb00); ++ mdio_write(tp, 0x06, 0xe2f8); ++ mdio_write(tp, 0x06, 0x7ce3); ++ mdio_write(tp, 0x06, 0xf87d); ++ mdio_write(tp, 0x06, 0xa511); ++ mdio_write(tp, 0x06, 0x1112); ++ mdio_write(tp, 0x06, 0xd240); ++ mdio_write(tp, 0x06, 0xd644); ++ mdio_write(tp, 0x06, 0x4402); ++ mdio_write(tp, 0x06, 0x8217); ++ mdio_write(tp, 0x06, 0xd2a0); ++ mdio_write(tp, 0x06, 0xd6aa); ++ mdio_write(tp, 0x06, 0xaa02); ++ mdio_write(tp, 0x06, 0x8217); ++ mdio_write(tp, 0x06, 0xae0f); ++ mdio_write(tp, 0x06, 0xa544); ++ mdio_write(tp, 0x06, 0x4402); ++ mdio_write(tp, 0x06, 0xae4d); ++ mdio_write(tp, 0x06, 0xa5aa); ++ mdio_write(tp, 0x06, 0xaa02); ++ mdio_write(tp, 0x06, 0xae47); ++ mdio_write(tp, 0x06, 0xaf82); ++ mdio_write(tp, 0x06, 0x13ee); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x834d); ++ mdio_write(tp, 0x06, 0x0fee); ++ mdio_write(tp, 0x06, 0x834c); ++ mdio_write(tp, 0x06, 0x0fee); ++ mdio_write(tp, 0x06, 0x834f); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8351); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x834a); ++ mdio_write(tp, 0x06, 0xffee); ++ mdio_write(tp, 0x06, 0x834b); ++ mdio_write(tp, 0x06, 0xffe0); ++ mdio_write(tp, 0x06, 0x8330); ++ mdio_write(tp, 0x06, 0xe183); ++ mdio_write(tp, 0x06, 0x3158); ++ mdio_write(tp, 0x06, 0xfee4); ++ mdio_write(tp, 0x06, 0xf88a); ++ mdio_write(tp, 0x06, 0xe5f8); ++ mdio_write(tp, 0x06, 0x8be0); ++ mdio_write(tp, 0x06, 0x8332); ++ mdio_write(tp, 0x06, 0xe183); ++ mdio_write(tp, 0x06, 0x3359); ++ mdio_write(tp, 0x06, 0x0fe2); ++ mdio_write(tp, 0x06, 0x834d); ++ mdio_write(tp, 0x06, 0x0c24); ++ mdio_write(tp, 0x06, 0x5af0); ++ mdio_write(tp, 0x06, 0x1e12); ++ mdio_write(tp, 0x06, 0xe4f8); ++ mdio_write(tp, 0x06, 0x8ce5); ++ mdio_write(tp, 0x06, 0xf88d); ++ mdio_write(tp, 0x06, 0xaf82); ++ mdio_write(tp, 0x06, 0x13e0); ++ mdio_write(tp, 0x06, 0x834f); ++ mdio_write(tp, 0x06, 0x10e4); ++ mdio_write(tp, 0x06, 0x834f); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4e78); ++ mdio_write(tp, 0x06, 0x009f); ++ mdio_write(tp, 0x06, 0x0ae0); ++ mdio_write(tp, 0x06, 0x834f); ++ mdio_write(tp, 0x06, 0xa010); ++ mdio_write(tp, 0x06, 0xa5ee); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x01e0); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x7805); ++ mdio_write(tp, 0x06, 0x9e9a); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4e78); ++ mdio_write(tp, 0x06, 0x049e); ++ mdio_write(tp, 0x06, 0x10e0); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x7803); ++ mdio_write(tp, 0x06, 0x9e0f); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4e78); ++ mdio_write(tp, 0x06, 0x019e); ++ mdio_write(tp, 0x06, 0x05ae); ++ mdio_write(tp, 0x06, 0x0caf); ++ mdio_write(tp, 0x06, 0x81f8); ++ mdio_write(tp, 0x06, 0xaf81); ++ mdio_write(tp, 0x06, 0xa3af); ++ mdio_write(tp, 0x06, 0x81dc); ++ mdio_write(tp, 0x06, 0xaf82); ++ mdio_write(tp, 0x06, 0x13ee); ++ mdio_write(tp, 0x06, 0x8348); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8349); ++ mdio_write(tp, 0x06, 0x00e0); ++ mdio_write(tp, 0x06, 0x8351); ++ mdio_write(tp, 0x06, 0x10e4); ++ mdio_write(tp, 0x06, 0x8351); ++ mdio_write(tp, 0x06, 0x5801); ++ mdio_write(tp, 0x06, 0x9fea); ++ mdio_write(tp, 0x06, 0xd000); ++ mdio_write(tp, 0x06, 0xd180); ++ mdio_write(tp, 0x06, 0x1f66); ++ mdio_write(tp, 0x06, 0xe2f8); ++ mdio_write(tp, 0x06, 0xeae3); ++ mdio_write(tp, 0x06, 0xf8eb); ++ mdio_write(tp, 0x06, 0x5af8); ++ mdio_write(tp, 0x06, 0x1e20); ++ mdio_write(tp, 0x06, 0xe6f8); ++ mdio_write(tp, 0x06, 0xeae5); ++ mdio_write(tp, 0x06, 0xf8eb); ++ mdio_write(tp, 0x06, 0xd302); ++ mdio_write(tp, 0x06, 0xb3fe); ++ mdio_write(tp, 0x06, 0xe2f8); ++ mdio_write(tp, 0x06, 0x7cef); ++ mdio_write(tp, 0x06, 0x325b); ++ mdio_write(tp, 0x06, 0x80e3); ++ mdio_write(tp, 0x06, 0xf87d); ++ mdio_write(tp, 0x06, 0x9e03); ++ mdio_write(tp, 0x06, 0x7dff); ++ mdio_write(tp, 0x06, 0xff0d); ++ mdio_write(tp, 0x06, 0x581c); ++ mdio_write(tp, 0x06, 0x551a); ++ mdio_write(tp, 0x06, 0x6511); ++ mdio_write(tp, 0x06, 0xa190); ++ mdio_write(tp, 0x06, 0xd3e2); ++ mdio_write(tp, 0x06, 0x8348); ++ mdio_write(tp, 0x06, 0xe383); ++ mdio_write(tp, 0x06, 0x491b); ++ mdio_write(tp, 0x06, 0x56ab); ++ mdio_write(tp, 0x06, 0x08ef); ++ mdio_write(tp, 0x06, 0x56e6); ++ mdio_write(tp, 0x06, 0x8348); ++ mdio_write(tp, 0x06, 0xe783); ++ mdio_write(tp, 0x06, 0x4910); ++ mdio_write(tp, 0x06, 0xd180); ++ mdio_write(tp, 0x06, 0x1f66); ++ mdio_write(tp, 0x06, 0xa004); ++ mdio_write(tp, 0x06, 0xb9e2); ++ mdio_write(tp, 0x06, 0x8348); ++ mdio_write(tp, 0x06, 0xe383); ++ mdio_write(tp, 0x06, 0x49ef); ++ mdio_write(tp, 0x06, 0x65e2); ++ mdio_write(tp, 0x06, 0x834a); ++ mdio_write(tp, 0x06, 0xe383); ++ mdio_write(tp, 0x06, 0x4b1b); ++ mdio_write(tp, 0x06, 0x56aa); ++ mdio_write(tp, 0x06, 0x0eef); ++ mdio_write(tp, 0x06, 0x56e6); ++ mdio_write(tp, 0x06, 0x834a); ++ mdio_write(tp, 0x06, 0xe783); ++ mdio_write(tp, 0x06, 0x4be2); ++ mdio_write(tp, 0x06, 0x834d); ++ mdio_write(tp, 0x06, 0xe683); ++ mdio_write(tp, 0x06, 0x4ce0); ++ mdio_write(tp, 0x06, 0x834d); ++ mdio_write(tp, 0x06, 0xa000); ++ mdio_write(tp, 0x06, 0x0caf); ++ mdio_write(tp, 0x06, 0x81dc); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4d10); ++ mdio_write(tp, 0x06, 0xe483); ++ mdio_write(tp, 0x06, 0x4dae); ++ mdio_write(tp, 0x06, 0x0480); ++ mdio_write(tp, 0x06, 0xe483); ++ mdio_write(tp, 0x06, 0x4de0); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x7803); ++ mdio_write(tp, 0x06, 0x9e0b); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4e78); ++ mdio_write(tp, 0x06, 0x049e); ++ mdio_write(tp, 0x06, 0x04ee); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x02e0); ++ mdio_write(tp, 0x06, 0x8332); ++ mdio_write(tp, 0x06, 0xe183); ++ mdio_write(tp, 0x06, 0x3359); ++ mdio_write(tp, 0x06, 0x0fe2); ++ mdio_write(tp, 0x06, 0x834d); ++ mdio_write(tp, 0x06, 0x0c24); ++ mdio_write(tp, 0x06, 0x5af0); ++ mdio_write(tp, 0x06, 0x1e12); ++ mdio_write(tp, 0x06, 0xe4f8); ++ mdio_write(tp, 0x06, 0x8ce5); ++ mdio_write(tp, 0x06, 0xf88d); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x30e1); ++ mdio_write(tp, 0x06, 0x8331); ++ mdio_write(tp, 0x06, 0x6801); ++ mdio_write(tp, 0x06, 0xe4f8); ++ mdio_write(tp, 0x06, 0x8ae5); ++ mdio_write(tp, 0x06, 0xf88b); ++ mdio_write(tp, 0x06, 0xae37); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4e03); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4ce1); ++ mdio_write(tp, 0x06, 0x834d); ++ mdio_write(tp, 0x06, 0x1b01); ++ mdio_write(tp, 0x06, 0x9e04); ++ mdio_write(tp, 0x06, 0xaaa1); ++ mdio_write(tp, 0x06, 0xaea8); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4e04); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4f00); ++ mdio_write(tp, 0x06, 0xaeab); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4f78); ++ mdio_write(tp, 0x06, 0x039f); ++ mdio_write(tp, 0x06, 0x14ee); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x05d2); ++ mdio_write(tp, 0x06, 0x40d6); ++ mdio_write(tp, 0x06, 0x5554); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0x17d2); ++ mdio_write(tp, 0x06, 0xa0d6); ++ mdio_write(tp, 0x06, 0xba00); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0x17fe); ++ mdio_write(tp, 0x06, 0xfdfc); ++ mdio_write(tp, 0x06, 0x05f8); ++ mdio_write(tp, 0x06, 0xe0f8); ++ mdio_write(tp, 0x06, 0x60e1); ++ mdio_write(tp, 0x06, 0xf861); ++ mdio_write(tp, 0x06, 0x6802); ++ mdio_write(tp, 0x06, 0xe4f8); ++ mdio_write(tp, 0x06, 0x60e5); ++ mdio_write(tp, 0x06, 0xf861); ++ mdio_write(tp, 0x06, 0xe0f8); ++ mdio_write(tp, 0x06, 0x48e1); ++ mdio_write(tp, 0x06, 0xf849); ++ mdio_write(tp, 0x06, 0x580f); ++ mdio_write(tp, 0x06, 0x1e02); ++ mdio_write(tp, 0x06, 0xe4f8); ++ mdio_write(tp, 0x06, 0x48e5); ++ mdio_write(tp, 0x06, 0xf849); ++ mdio_write(tp, 0x06, 0xd000); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0x5bbf); ++ mdio_write(tp, 0x06, 0x8350); ++ mdio_write(tp, 0x06, 0xef46); ++ mdio_write(tp, 0x06, 0xdc19); ++ mdio_write(tp, 0x06, 0xddd0); ++ mdio_write(tp, 0x06, 0x0102); ++ mdio_write(tp, 0x06, 0x825b); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0x77e0); ++ mdio_write(tp, 0x06, 0xf860); ++ mdio_write(tp, 0x06, 0xe1f8); ++ mdio_write(tp, 0x06, 0x6158); ++ mdio_write(tp, 0x06, 0xfde4); ++ mdio_write(tp, 0x06, 0xf860); ++ mdio_write(tp, 0x06, 0xe5f8); ++ mdio_write(tp, 0x06, 0x61fc); ++ mdio_write(tp, 0x06, 0x04f9); ++ mdio_write(tp, 0x06, 0xfafb); ++ mdio_write(tp, 0x06, 0xc6bf); ++ mdio_write(tp, 0x06, 0xf840); ++ mdio_write(tp, 0x06, 0xbe83); ++ mdio_write(tp, 0x06, 0x50a0); ++ mdio_write(tp, 0x06, 0x0101); ++ mdio_write(tp, 0x06, 0x071b); ++ mdio_write(tp, 0x06, 0x89cf); ++ mdio_write(tp, 0x06, 0xd208); ++ mdio_write(tp, 0x06, 0xebdb); ++ mdio_write(tp, 0x06, 0x19b2); ++ mdio_write(tp, 0x06, 0xfbff); ++ mdio_write(tp, 0x06, 0xfefd); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe0f8); ++ mdio_write(tp, 0x06, 0x48e1); ++ mdio_write(tp, 0x06, 0xf849); ++ mdio_write(tp, 0x06, 0x6808); ++ mdio_write(tp, 0x06, 0xe4f8); ++ mdio_write(tp, 0x06, 0x48e5); ++ mdio_write(tp, 0x06, 0xf849); ++ mdio_write(tp, 0x06, 0x58f7); ++ mdio_write(tp, 0x06, 0xe4f8); ++ mdio_write(tp, 0x06, 0x48e5); ++ mdio_write(tp, 0x06, 0xf849); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0x4d20); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x4e22); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x4ddf); ++ mdio_write(tp, 0x06, 0xff01); ++ mdio_write(tp, 0x06, 0x4edd); ++ mdio_write(tp, 0x06, 0xff01); ++ mdio_write(tp, 0x06, 0xf8fa); ++ mdio_write(tp, 0x06, 0xfbef); ++ mdio_write(tp, 0x06, 0x79bf); ++ mdio_write(tp, 0x06, 0xf822); ++ mdio_write(tp, 0x06, 0xd819); ++ mdio_write(tp, 0x06, 0xd958); ++ mdio_write(tp, 0x06, 0x849f); ++ mdio_write(tp, 0x06, 0x09bf); ++ mdio_write(tp, 0x06, 0x82be); ++ mdio_write(tp, 0x06, 0xd682); ++ mdio_write(tp, 0x06, 0xc602); ++ mdio_write(tp, 0x06, 0x014f); ++ mdio_write(tp, 0x06, 0xef97); ++ mdio_write(tp, 0x06, 0xfffe); ++ mdio_write(tp, 0x06, 0xfc05); ++ mdio_write(tp, 0x06, 0x17ff); ++ mdio_write(tp, 0x06, 0xfe01); ++ mdio_write(tp, 0x06, 0x1700); ++ mdio_write(tp, 0x06, 0x0102); ++ mdio_write(tp, 0x05, 0x83d8); ++ mdio_write(tp, 0x06, 0x8051); ++ mdio_write(tp, 0x05, 0x83d6); ++ mdio_write(tp, 0x06, 0x82a0); ++ mdio_write(tp, 0x05, 0x83d4); ++ mdio_write(tp, 0x06, 0x8000); ++ mdio_write(tp, 0x02, 0x2010); ++ mdio_write(tp, 0x03, 0xdc00); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x0b, 0x0600); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x00fc); ++ mdio_write(tp, 0x1f, 0x0000); ++ } ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x0D, 0xF880); ++ mdio_write(tp, 0x1F, 0x0000); ++ } else if (tp->mcfg == CFG_METHOD_10) { ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x06, 0x4064); ++ mdio_write(tp, 0x07, 0x2863); ++ mdio_write(tp, 0x08, 0x059C); ++ mdio_write(tp, 0x09, 0x26B4); ++ mdio_write(tp, 0x0A, 0x6A19); ++ mdio_write(tp, 0x0B, 0xDCC8); ++ mdio_write(tp, 0x10, 0xF06D); ++ mdio_write(tp, 0x14, 0x7F68); ++ mdio_write(tp, 0x18, 0x7FD9); ++ mdio_write(tp, 0x1C, 0xF0FF); ++ mdio_write(tp, 0x1D, 0x3D9C); ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x12, 0xF49F); ++ mdio_write(tp, 0x13, 0x070B); ++ mdio_write(tp, 0x1A, 0x05AD); ++ mdio_write(tp, 0x14, 0x94C0); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x06, 0x5561); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8332); ++ mdio_write(tp, 0x06, 0x5561); ++ ++ if (rtl8168_efuse_read(tp, 0x01) == 0xb1) { ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x05, 0x669A); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8330); ++ mdio_write(tp, 0x06, 0x669A); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ gphy_val = mdio_read(tp, 0x0D); ++ if ((gphy_val & 0x00FF) != 0x006C) { ++ gphy_val &= 0xFF00; ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x0D, gphy_val | 0x0065); ++ mdio_write(tp, 0x0D, gphy_val | 0x0066); ++ mdio_write(tp, 0x0D, gphy_val | 0x0067); ++ mdio_write(tp, 0x0D, gphy_val | 0x0068); ++ mdio_write(tp, 0x0D, gphy_val | 0x0069); ++ mdio_write(tp, 0x0D, gphy_val | 0x006A); ++ mdio_write(tp, 0x0D, gphy_val | 0x006B); ++ mdio_write(tp, 0x0D, gphy_val | 0x006C); ++ } ++ } else { ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x05, 0x2642); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8330); ++ mdio_write(tp, 0x06, 0x2642); ++ } ++ ++ if (rtl8168_efuse_read(tp, 0x30) == 0x98) { ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x11, mdio_read(tp, 0x11) & ~BIT_1); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x01, mdio_read(tp, 0x01) | BIT_9); ++ } else if (rtl8168_efuse_read(tp, 0x30) == 0x90) { ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x01, mdio_read(tp, 0x01) & ~BIT_9); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x16, 0x5101); ++ } ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ gphy_val = mdio_read(tp, 0x02); ++ gphy_val &= ~BIT_10; ++ gphy_val &= ~BIT_9; ++ gphy_val |= BIT_8; ++ mdio_write(tp, 0x02, gphy_val); ++ gphy_val = mdio_read(tp, 0x03); ++ gphy_val &= ~BIT_15; ++ gphy_val &= ~BIT_14; ++ gphy_val &= ~BIT_13; ++ mdio_write(tp, 0x03, gphy_val); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x17, 0x0CC0); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ gphy_val = mdio_read(tp, 0x0F); ++ gphy_val |= BIT_4; ++ gphy_val |= BIT_2; ++ gphy_val |= BIT_1; ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x0F, gphy_val); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x001B); ++ if (mdio_read(tp, 0x06) == 0xB300) { ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x05, 0x8000); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xfaee); ++ mdio_write(tp, 0x06, 0xf8ea); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0xf8eb); ++ mdio_write(tp, 0x06, 0x00e2); ++ mdio_write(tp, 0x06, 0xf87c); ++ mdio_write(tp, 0x06, 0xe3f8); ++ mdio_write(tp, 0x06, 0x7da5); ++ mdio_write(tp, 0x06, 0x1111); ++ mdio_write(tp, 0x06, 0x12d2); ++ mdio_write(tp, 0x06, 0x40d6); ++ mdio_write(tp, 0x06, 0x4444); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0xc6d2); ++ mdio_write(tp, 0x06, 0xa0d6); ++ mdio_write(tp, 0x06, 0xaaaa); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0xc6ae); ++ mdio_write(tp, 0x06, 0x0fa5); ++ mdio_write(tp, 0x06, 0x4444); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x4da5); ++ mdio_write(tp, 0x06, 0xaaaa); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x47af); ++ mdio_write(tp, 0x06, 0x81c2); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4e00); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4d0f); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4c0f); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4f00); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x5100); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4aff); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4bff); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x30e1); ++ mdio_write(tp, 0x06, 0x8331); ++ mdio_write(tp, 0x06, 0x58fe); ++ mdio_write(tp, 0x06, 0xe4f8); ++ mdio_write(tp, 0x06, 0x8ae5); ++ mdio_write(tp, 0x06, 0xf88b); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x32e1); ++ mdio_write(tp, 0x06, 0x8333); ++ mdio_write(tp, 0x06, 0x590f); ++ mdio_write(tp, 0x06, 0xe283); ++ mdio_write(tp, 0x06, 0x4d0c); ++ mdio_write(tp, 0x06, 0x245a); ++ mdio_write(tp, 0x06, 0xf01e); ++ mdio_write(tp, 0x06, 0x12e4); ++ mdio_write(tp, 0x06, 0xf88c); ++ mdio_write(tp, 0x06, 0xe5f8); ++ mdio_write(tp, 0x06, 0x8daf); ++ mdio_write(tp, 0x06, 0x81c2); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4f10); ++ mdio_write(tp, 0x06, 0xe483); ++ mdio_write(tp, 0x06, 0x4fe0); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x7800); ++ mdio_write(tp, 0x06, 0x9f0a); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4fa0); ++ mdio_write(tp, 0x06, 0x10a5); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4e01); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4e78); ++ mdio_write(tp, 0x06, 0x059e); ++ mdio_write(tp, 0x06, 0x9ae0); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x7804); ++ mdio_write(tp, 0x06, 0x9e10); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4e78); ++ mdio_write(tp, 0x06, 0x039e); ++ mdio_write(tp, 0x06, 0x0fe0); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x7801); ++ mdio_write(tp, 0x06, 0x9e05); ++ mdio_write(tp, 0x06, 0xae0c); ++ mdio_write(tp, 0x06, 0xaf81); ++ mdio_write(tp, 0x06, 0xa7af); ++ mdio_write(tp, 0x06, 0x8152); ++ mdio_write(tp, 0x06, 0xaf81); ++ mdio_write(tp, 0x06, 0x8baf); ++ mdio_write(tp, 0x06, 0x81c2); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4800); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4900); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x5110); ++ mdio_write(tp, 0x06, 0xe483); ++ mdio_write(tp, 0x06, 0x5158); ++ mdio_write(tp, 0x06, 0x019f); ++ mdio_write(tp, 0x06, 0xead0); ++ mdio_write(tp, 0x06, 0x00d1); ++ mdio_write(tp, 0x06, 0x801f); ++ mdio_write(tp, 0x06, 0x66e2); ++ mdio_write(tp, 0x06, 0xf8ea); ++ mdio_write(tp, 0x06, 0xe3f8); ++ mdio_write(tp, 0x06, 0xeb5a); ++ mdio_write(tp, 0x06, 0xf81e); ++ mdio_write(tp, 0x06, 0x20e6); ++ mdio_write(tp, 0x06, 0xf8ea); ++ mdio_write(tp, 0x06, 0xe5f8); ++ mdio_write(tp, 0x06, 0xebd3); ++ mdio_write(tp, 0x06, 0x02b3); ++ mdio_write(tp, 0x06, 0xfee2); ++ mdio_write(tp, 0x06, 0xf87c); ++ mdio_write(tp, 0x06, 0xef32); ++ mdio_write(tp, 0x06, 0x5b80); ++ mdio_write(tp, 0x06, 0xe3f8); ++ mdio_write(tp, 0x06, 0x7d9e); ++ mdio_write(tp, 0x06, 0x037d); ++ mdio_write(tp, 0x06, 0xffff); ++ mdio_write(tp, 0x06, 0x0d58); ++ mdio_write(tp, 0x06, 0x1c55); ++ mdio_write(tp, 0x06, 0x1a65); ++ mdio_write(tp, 0x06, 0x11a1); ++ mdio_write(tp, 0x06, 0x90d3); ++ mdio_write(tp, 0x06, 0xe283); ++ mdio_write(tp, 0x06, 0x48e3); ++ mdio_write(tp, 0x06, 0x8349); ++ mdio_write(tp, 0x06, 0x1b56); ++ mdio_write(tp, 0x06, 0xab08); ++ mdio_write(tp, 0x06, 0xef56); ++ mdio_write(tp, 0x06, 0xe683); ++ mdio_write(tp, 0x06, 0x48e7); ++ mdio_write(tp, 0x06, 0x8349); ++ mdio_write(tp, 0x06, 0x10d1); ++ mdio_write(tp, 0x06, 0x801f); ++ mdio_write(tp, 0x06, 0x66a0); ++ mdio_write(tp, 0x06, 0x04b9); ++ mdio_write(tp, 0x06, 0xe283); ++ mdio_write(tp, 0x06, 0x48e3); ++ mdio_write(tp, 0x06, 0x8349); ++ mdio_write(tp, 0x06, 0xef65); ++ mdio_write(tp, 0x06, 0xe283); ++ mdio_write(tp, 0x06, 0x4ae3); ++ mdio_write(tp, 0x06, 0x834b); ++ mdio_write(tp, 0x06, 0x1b56); ++ mdio_write(tp, 0x06, 0xaa0e); ++ mdio_write(tp, 0x06, 0xef56); ++ mdio_write(tp, 0x06, 0xe683); ++ mdio_write(tp, 0x06, 0x4ae7); ++ mdio_write(tp, 0x06, 0x834b); ++ mdio_write(tp, 0x06, 0xe283); ++ mdio_write(tp, 0x06, 0x4de6); ++ mdio_write(tp, 0x06, 0x834c); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4da0); ++ mdio_write(tp, 0x06, 0x000c); ++ mdio_write(tp, 0x06, 0xaf81); ++ mdio_write(tp, 0x06, 0x8be0); ++ mdio_write(tp, 0x06, 0x834d); ++ mdio_write(tp, 0x06, 0x10e4); ++ mdio_write(tp, 0x06, 0x834d); ++ mdio_write(tp, 0x06, 0xae04); ++ mdio_write(tp, 0x06, 0x80e4); ++ mdio_write(tp, 0x06, 0x834d); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x4e78); ++ mdio_write(tp, 0x06, 0x039e); ++ mdio_write(tp, 0x06, 0x0be0); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x7804); ++ mdio_write(tp, 0x06, 0x9e04); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4e02); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0x32e1); ++ mdio_write(tp, 0x06, 0x8333); ++ mdio_write(tp, 0x06, 0x590f); ++ mdio_write(tp, 0x06, 0xe283); ++ mdio_write(tp, 0x06, 0x4d0c); ++ mdio_write(tp, 0x06, 0x245a); ++ mdio_write(tp, 0x06, 0xf01e); ++ mdio_write(tp, 0x06, 0x12e4); ++ mdio_write(tp, 0x06, 0xf88c); ++ mdio_write(tp, 0x06, 0xe5f8); ++ mdio_write(tp, 0x06, 0x8de0); ++ mdio_write(tp, 0x06, 0x8330); ++ mdio_write(tp, 0x06, 0xe183); ++ mdio_write(tp, 0x06, 0x3168); ++ mdio_write(tp, 0x06, 0x01e4); ++ mdio_write(tp, 0x06, 0xf88a); ++ mdio_write(tp, 0x06, 0xe5f8); ++ mdio_write(tp, 0x06, 0x8bae); ++ mdio_write(tp, 0x06, 0x37ee); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x03e0); ++ mdio_write(tp, 0x06, 0x834c); ++ mdio_write(tp, 0x06, 0xe183); ++ mdio_write(tp, 0x06, 0x4d1b); ++ mdio_write(tp, 0x06, 0x019e); ++ mdio_write(tp, 0x06, 0x04aa); ++ mdio_write(tp, 0x06, 0xa1ae); ++ mdio_write(tp, 0x06, 0xa8ee); ++ mdio_write(tp, 0x06, 0x834e); ++ mdio_write(tp, 0x06, 0x04ee); ++ mdio_write(tp, 0x06, 0x834f); ++ mdio_write(tp, 0x06, 0x00ae); ++ mdio_write(tp, 0x06, 0xabe0); ++ mdio_write(tp, 0x06, 0x834f); ++ mdio_write(tp, 0x06, 0x7803); ++ mdio_write(tp, 0x06, 0x9f14); ++ mdio_write(tp, 0x06, 0xee83); ++ mdio_write(tp, 0x06, 0x4e05); ++ mdio_write(tp, 0x06, 0xd240); ++ mdio_write(tp, 0x06, 0xd655); ++ mdio_write(tp, 0x06, 0x5402); ++ mdio_write(tp, 0x06, 0x81c6); ++ mdio_write(tp, 0x06, 0xd2a0); ++ mdio_write(tp, 0x06, 0xd6ba); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x81c6); ++ mdio_write(tp, 0x06, 0xfefd); ++ mdio_write(tp, 0x06, 0xfc05); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0xf860); ++ mdio_write(tp, 0x06, 0xe1f8); ++ mdio_write(tp, 0x06, 0x6168); ++ mdio_write(tp, 0x06, 0x02e4); ++ mdio_write(tp, 0x06, 0xf860); ++ mdio_write(tp, 0x06, 0xe5f8); ++ mdio_write(tp, 0x06, 0x61e0); ++ mdio_write(tp, 0x06, 0xf848); ++ mdio_write(tp, 0x06, 0xe1f8); ++ mdio_write(tp, 0x06, 0x4958); ++ mdio_write(tp, 0x06, 0x0f1e); ++ mdio_write(tp, 0x06, 0x02e4); ++ mdio_write(tp, 0x06, 0xf848); ++ mdio_write(tp, 0x06, 0xe5f8); ++ mdio_write(tp, 0x06, 0x49d0); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x820a); ++ mdio_write(tp, 0x06, 0xbf83); ++ mdio_write(tp, 0x06, 0x50ef); ++ mdio_write(tp, 0x06, 0x46dc); ++ mdio_write(tp, 0x06, 0x19dd); ++ mdio_write(tp, 0x06, 0xd001); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0x0a02); ++ mdio_write(tp, 0x06, 0x8226); ++ mdio_write(tp, 0x06, 0xe0f8); ++ mdio_write(tp, 0x06, 0x60e1); ++ mdio_write(tp, 0x06, 0xf861); ++ mdio_write(tp, 0x06, 0x58fd); ++ mdio_write(tp, 0x06, 0xe4f8); ++ mdio_write(tp, 0x06, 0x60e5); ++ mdio_write(tp, 0x06, 0xf861); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf9fa); ++ mdio_write(tp, 0x06, 0xfbc6); ++ mdio_write(tp, 0x06, 0xbff8); ++ mdio_write(tp, 0x06, 0x40be); ++ mdio_write(tp, 0x06, 0x8350); ++ mdio_write(tp, 0x06, 0xa001); ++ mdio_write(tp, 0x06, 0x0107); ++ mdio_write(tp, 0x06, 0x1b89); ++ mdio_write(tp, 0x06, 0xcfd2); ++ mdio_write(tp, 0x06, 0x08eb); ++ mdio_write(tp, 0x06, 0xdb19); ++ mdio_write(tp, 0x06, 0xb2fb); ++ mdio_write(tp, 0x06, 0xfffe); ++ mdio_write(tp, 0x06, 0xfd04); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0xf848); ++ mdio_write(tp, 0x06, 0xe1f8); ++ mdio_write(tp, 0x06, 0x4968); ++ mdio_write(tp, 0x06, 0x08e4); ++ mdio_write(tp, 0x06, 0xf848); ++ mdio_write(tp, 0x06, 0xe5f8); ++ mdio_write(tp, 0x06, 0x4958); ++ mdio_write(tp, 0x06, 0xf7e4); ++ mdio_write(tp, 0x06, 0xf848); ++ mdio_write(tp, 0x06, 0xe5f8); ++ mdio_write(tp, 0x06, 0x49fc); ++ mdio_write(tp, 0x06, 0x044d); ++ mdio_write(tp, 0x06, 0x2000); ++ mdio_write(tp, 0x06, 0x024e); ++ mdio_write(tp, 0x06, 0x2200); ++ mdio_write(tp, 0x06, 0x024d); ++ mdio_write(tp, 0x06, 0xdfff); ++ mdio_write(tp, 0x06, 0x014e); ++ mdio_write(tp, 0x06, 0xddff); ++ mdio_write(tp, 0x06, 0x01f8); ++ mdio_write(tp, 0x06, 0xfafb); ++ mdio_write(tp, 0x06, 0xef79); ++ mdio_write(tp, 0x06, 0xbff8); ++ mdio_write(tp, 0x06, 0x22d8); ++ mdio_write(tp, 0x06, 0x19d9); ++ mdio_write(tp, 0x06, 0x5884); ++ mdio_write(tp, 0x06, 0x9f09); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0x6dd6); ++ mdio_write(tp, 0x06, 0x8275); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x4fef); ++ mdio_write(tp, 0x06, 0x97ff); ++ mdio_write(tp, 0x06, 0xfefc); ++ mdio_write(tp, 0x06, 0x0517); ++ mdio_write(tp, 0x06, 0xfffe); ++ mdio_write(tp, 0x06, 0x0117); ++ mdio_write(tp, 0x06, 0x0001); ++ mdio_write(tp, 0x06, 0x0200); ++ mdio_write(tp, 0x05, 0x83d8); ++ mdio_write(tp, 0x06, 0x8000); ++ mdio_write(tp, 0x05, 0x83d6); ++ mdio_write(tp, 0x06, 0x824f); ++ mdio_write(tp, 0x02, 0x2010); ++ mdio_write(tp, 0x03, 0xdc00); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x0b, 0x0600); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x00fc); ++ mdio_write(tp, 0x1f, 0x0000); ++ } ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x0D, 0xF880); ++ mdio_write(tp, 0x1F, 0x0000); ++ } else if (tp->mcfg == CFG_METHOD_11) { ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x10, 0x0008); ++ mdio_write(tp, 0x0D, 0x006C); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x17, 0x0CC0); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x0B, 0xA4D8); ++ mdio_write(tp, 0x09, 0x281C); ++ mdio_write(tp, 0x07, 0x2883); ++ mdio_write(tp, 0x0A, 0x6B35); ++ mdio_write(tp, 0x1D, 0x3DA4); ++ mdio_write(tp, 0x1C, 0xEFFD); ++ mdio_write(tp, 0x14, 0x7F52); ++ mdio_write(tp, 0x18, 0x7FC6); ++ mdio_write(tp, 0x08, 0x0601); ++ mdio_write(tp, 0x06, 0x4063); ++ mdio_write(tp, 0x10, 0xF074); ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x13, 0x0789); ++ mdio_write(tp, 0x12, 0xF4BD); ++ mdio_write(tp, 0x1A, 0x04FD); ++ mdio_write(tp, 0x14, 0x84B0); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x00, 0x9200); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x01, 0x0340); ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x04, 0x4000); ++ mdio_write(tp, 0x03, 0x1D21); ++ mdio_write(tp, 0x02, 0x0C32); ++ mdio_write(tp, 0x01, 0x0200); ++ mdio_write(tp, 0x00, 0x5554); ++ mdio_write(tp, 0x04, 0x4800); ++ mdio_write(tp, 0x04, 0x4000); ++ mdio_write(tp, 0x04, 0xF000); ++ mdio_write(tp, 0x03, 0xDF01); ++ mdio_write(tp, 0x02, 0xDF20); ++ mdio_write(tp, 0x01, 0x101A); ++ mdio_write(tp, 0x00, 0xA0FF); ++ mdio_write(tp, 0x04, 0xF800); ++ mdio_write(tp, 0x04, 0xF000); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x0023); ++ mdio_write(tp, 0x16, 0x0000); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ gphy_val = mdio_read(tp, 0x0D); ++ gphy_val |= BIT_5; ++ mdio_write(tp, 0x0D, gphy_val); ++ } else if (tp->mcfg == CFG_METHOD_12 || tp->mcfg == CFG_METHOD_13) { ++ // TO DO: ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x17, 0x0CC0); ++ ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x002D); ++ mdio_write(tp, 0x18, 0x0040); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ gphy_val = mdio_read(tp, 0x0D); ++ gphy_val |= BIT_5; ++ mdio_write(tp, 0x0D, gphy_val); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ gphy_val = mdio_read(tp, 0x0C); ++ gphy_val |= BIT_10; ++ mdio_write(tp, 0x0C, gphy_val); ++ } else if (tp->mcfg == CFG_METHOD_14 || tp->mcfg == CFG_METHOD_15) { ++ struct pci_dev *pdev = tp->pci_dev; ++ ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ RTL_W8(0xF3, RTL_R8(0xF3) | BIT_2); ++ ++ if (tp->mcfg == CFG_METHOD_14) { ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x1800); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ mdio_write(tp, 0x17, 0x0117); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1E, 0x002C); ++ mdio_write(tp, 0x1B, 0x5000); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x16, 0x4104); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x1E); ++ gphy_val &= 0x03FF; ++ if (gphy_val == 0x000C) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0005); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x07); ++ if ((gphy_val & BIT_5) == 0) ++ break; ++ } ++ gphy_val = mdio_read(tp, 0x07); ++ if (gphy_val & BIT_5) { ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x00a1); ++ mdio_write(tp, 0x17, 0x1000); ++ mdio_write(tp, 0x17, 0x0000); ++ mdio_write(tp, 0x17, 0x2000); ++ mdio_write(tp, 0x1e, 0x002f); ++ mdio_write(tp, 0x18, 0x9bfb); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x07, 0x0000); ++ mdio_write(tp, 0x1f, 0x0000); ++ } ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ gphy_val = mdio_read(tp, 0x00); ++ gphy_val &= ~(BIT_7); ++ mdio_write(tp, 0x00, gphy_val); ++ mdio_write(tp, 0x1f, 0x0002); ++ gphy_val = mdio_read(tp, 0x08); ++ gphy_val &= ~(BIT_7); ++ mdio_write(tp, 0x08, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0307); ++ mdio_write(tp, 0x15, 0x000e); ++ mdio_write(tp, 0x19, 0x000a); ++ mdio_write(tp, 0x15, 0x0010); ++ mdio_write(tp, 0x19, 0x0008); ++ mdio_write(tp, 0x15, 0x0018); ++ mdio_write(tp, 0x19, 0x4801); ++ mdio_write(tp, 0x15, 0x0019); ++ mdio_write(tp, 0x19, 0x6801); ++ mdio_write(tp, 0x15, 0x001a); ++ mdio_write(tp, 0x19, 0x66a1); ++ mdio_write(tp, 0x15, 0x001f); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0020); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0021); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0022); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0023); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0024); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0025); ++ mdio_write(tp, 0x19, 0x64a1); ++ mdio_write(tp, 0x15, 0x0026); ++ mdio_write(tp, 0x19, 0x40ea); ++ mdio_write(tp, 0x15, 0x0027); ++ mdio_write(tp, 0x19, 0x4503); ++ mdio_write(tp, 0x15, 0x0028); ++ mdio_write(tp, 0x19, 0x9f00); ++ mdio_write(tp, 0x15, 0x0029); ++ mdio_write(tp, 0x19, 0xa631); ++ mdio_write(tp, 0x15, 0x002a); ++ mdio_write(tp, 0x19, 0x9717); ++ mdio_write(tp, 0x15, 0x002b); ++ mdio_write(tp, 0x19, 0x302c); ++ mdio_write(tp, 0x15, 0x002c); ++ mdio_write(tp, 0x19, 0x4802); ++ mdio_write(tp, 0x15, 0x002d); ++ mdio_write(tp, 0x19, 0x58da); ++ mdio_write(tp, 0x15, 0x002e); ++ mdio_write(tp, 0x19, 0x400d); ++ mdio_write(tp, 0x15, 0x002f); ++ mdio_write(tp, 0x19, 0x4488); ++ mdio_write(tp, 0x15, 0x0030); ++ mdio_write(tp, 0x19, 0x9e00); ++ mdio_write(tp, 0x15, 0x0031); ++ mdio_write(tp, 0x19, 0x63c8); ++ mdio_write(tp, 0x15, 0x0032); ++ mdio_write(tp, 0x19, 0x6481); ++ mdio_write(tp, 0x15, 0x0033); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0034); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0035); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0036); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0037); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0038); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0039); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x003a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x003b); ++ mdio_write(tp, 0x19, 0x63e8); ++ mdio_write(tp, 0x15, 0x003c); ++ mdio_write(tp, 0x19, 0x7d00); ++ mdio_write(tp, 0x15, 0x003d); ++ mdio_write(tp, 0x19, 0x59d4); ++ mdio_write(tp, 0x15, 0x003e); ++ mdio_write(tp, 0x19, 0x63f8); ++ mdio_write(tp, 0x15, 0x0040); ++ mdio_write(tp, 0x19, 0x64a1); ++ mdio_write(tp, 0x15, 0x0041); ++ mdio_write(tp, 0x19, 0x30de); ++ mdio_write(tp, 0x15, 0x0044); ++ mdio_write(tp, 0x19, 0x480f); ++ mdio_write(tp, 0x15, 0x0045); ++ mdio_write(tp, 0x19, 0x6800); ++ mdio_write(tp, 0x15, 0x0046); ++ mdio_write(tp, 0x19, 0x6680); ++ mdio_write(tp, 0x15, 0x0047); ++ mdio_write(tp, 0x19, 0x7c10); ++ mdio_write(tp, 0x15, 0x0048); ++ mdio_write(tp, 0x19, 0x63c8); ++ mdio_write(tp, 0x15, 0x0049); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004b); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004c); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004d); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004e); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004f); ++ mdio_write(tp, 0x19, 0x40ea); ++ mdio_write(tp, 0x15, 0x0050); ++ mdio_write(tp, 0x19, 0x4503); ++ mdio_write(tp, 0x15, 0x0051); ++ mdio_write(tp, 0x19, 0x58ca); ++ mdio_write(tp, 0x15, 0x0052); ++ mdio_write(tp, 0x19, 0x63c8); ++ mdio_write(tp, 0x15, 0x0053); ++ mdio_write(tp, 0x19, 0x63d8); ++ mdio_write(tp, 0x15, 0x0054); ++ mdio_write(tp, 0x19, 0x66a0); ++ mdio_write(tp, 0x15, 0x0055); ++ mdio_write(tp, 0x19, 0x9f00); ++ mdio_write(tp, 0x15, 0x0056); ++ mdio_write(tp, 0x19, 0x3000); ++ mdio_write(tp, 0x15, 0x006E); ++ mdio_write(tp, 0x19, 0x9afa); ++ mdio_write(tp, 0x15, 0x00a1); ++ mdio_write(tp, 0x19, 0x3044); ++ mdio_write(tp, 0x15, 0x00ab); ++ mdio_write(tp, 0x19, 0x5820); ++ mdio_write(tp, 0x15, 0x00ac); ++ mdio_write(tp, 0x19, 0x5e04); ++ mdio_write(tp, 0x15, 0x00ad); ++ mdio_write(tp, 0x19, 0xb60c); ++ mdio_write(tp, 0x15, 0x00af); ++ mdio_write(tp, 0x19, 0x000a); ++ mdio_write(tp, 0x15, 0x00b2); ++ mdio_write(tp, 0x19, 0x30b9); ++ mdio_write(tp, 0x15, 0x00b9); ++ mdio_write(tp, 0x19, 0x4408); ++ mdio_write(tp, 0x15, 0x00ba); ++ mdio_write(tp, 0x19, 0x480b); ++ mdio_write(tp, 0x15, 0x00bb); ++ mdio_write(tp, 0x19, 0x5e00); ++ mdio_write(tp, 0x15, 0x00bc); ++ mdio_write(tp, 0x19, 0x405f); ++ mdio_write(tp, 0x15, 0x00bd); ++ mdio_write(tp, 0x19, 0x4448); ++ mdio_write(tp, 0x15, 0x00be); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x00bf); ++ mdio_write(tp, 0x19, 0x4468); ++ mdio_write(tp, 0x15, 0x00c0); ++ mdio_write(tp, 0x19, 0x9c02); ++ mdio_write(tp, 0x15, 0x00c1); ++ mdio_write(tp, 0x19, 0x58a0); ++ mdio_write(tp, 0x15, 0x00c2); ++ mdio_write(tp, 0x19, 0xb605); ++ mdio_write(tp, 0x15, 0x00c3); ++ mdio_write(tp, 0x19, 0xc0d3); ++ mdio_write(tp, 0x15, 0x00c4); ++ mdio_write(tp, 0x19, 0x00e6); ++ mdio_write(tp, 0x15, 0x00c5); ++ mdio_write(tp, 0x19, 0xdaec); ++ mdio_write(tp, 0x15, 0x00c6); ++ mdio_write(tp, 0x19, 0x00fa); ++ mdio_write(tp, 0x15, 0x00c7); ++ mdio_write(tp, 0x19, 0x9df9); ++ mdio_write(tp, 0x15, 0x00c8); ++ mdio_write(tp, 0x19, 0x307a); ++ mdio_write(tp, 0x15, 0x0112); ++ mdio_write(tp, 0x19, 0x6421); ++ mdio_write(tp, 0x15, 0x0113); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x0114); ++ mdio_write(tp, 0x19, 0x63f0); ++ mdio_write(tp, 0x15, 0x0115); ++ mdio_write(tp, 0x19, 0x4003); ++ mdio_write(tp, 0x15, 0x0116); ++ mdio_write(tp, 0x19, 0x4418); ++ mdio_write(tp, 0x15, 0x0117); ++ mdio_write(tp, 0x19, 0x9b00); ++ mdio_write(tp, 0x15, 0x0118); ++ mdio_write(tp, 0x19, 0x6461); ++ mdio_write(tp, 0x15, 0x0119); ++ mdio_write(tp, 0x19, 0x64e1); ++ mdio_write(tp, 0x15, 0x011a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0150); ++ mdio_write(tp, 0x19, 0x7c80); ++ mdio_write(tp, 0x15, 0x0151); ++ mdio_write(tp, 0x19, 0x6461); ++ mdio_write(tp, 0x15, 0x0152); ++ mdio_write(tp, 0x19, 0x4003); ++ mdio_write(tp, 0x15, 0x0153); ++ mdio_write(tp, 0x19, 0x4540); ++ mdio_write(tp, 0x15, 0x0154); ++ mdio_write(tp, 0x19, 0x9f00); ++ mdio_write(tp, 0x15, 0x0155); ++ mdio_write(tp, 0x19, 0x9d00); ++ mdio_write(tp, 0x15, 0x0156); ++ mdio_write(tp, 0x19, 0x7c40); ++ mdio_write(tp, 0x15, 0x0157); ++ mdio_write(tp, 0x19, 0x6421); ++ mdio_write(tp, 0x15, 0x0158); ++ mdio_write(tp, 0x19, 0x7c80); ++ mdio_write(tp, 0x15, 0x0159); ++ mdio_write(tp, 0x19, 0x64a1); ++ mdio_write(tp, 0x15, 0x015a); ++ mdio_write(tp, 0x19, 0x30fe); ++ mdio_write(tp, 0x15, 0x021e); ++ mdio_write(tp, 0x19, 0x5410); ++ mdio_write(tp, 0x15, 0x0225); ++ mdio_write(tp, 0x19, 0x5400); ++ mdio_write(tp, 0x15, 0x023D); ++ mdio_write(tp, 0x19, 0x4050); ++ mdio_write(tp, 0x15, 0x0295); ++ mdio_write(tp, 0x19, 0x6c08); ++ mdio_write(tp, 0x15, 0x02bd); ++ mdio_write(tp, 0x19, 0xa523); ++ mdio_write(tp, 0x15, 0x02be); ++ mdio_write(tp, 0x19, 0x32ca); ++ mdio_write(tp, 0x15, 0x02ca); ++ mdio_write(tp, 0x19, 0x48b3); ++ mdio_write(tp, 0x15, 0x02cb); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x02cc); ++ mdio_write(tp, 0x19, 0x4823); ++ mdio_write(tp, 0x15, 0x02cd); ++ mdio_write(tp, 0x19, 0x4510); ++ mdio_write(tp, 0x15, 0x02ce); ++ mdio_write(tp, 0x19, 0xb63a); ++ mdio_write(tp, 0x15, 0x02cf); ++ mdio_write(tp, 0x19, 0x7dc8); ++ mdio_write(tp, 0x15, 0x02d6); ++ mdio_write(tp, 0x19, 0x9bf8); ++ mdio_write(tp, 0x15, 0x02d8); ++ mdio_write(tp, 0x19, 0x85f6); ++ mdio_write(tp, 0x15, 0x02d9); ++ mdio_write(tp, 0x19, 0x32e0); ++ mdio_write(tp, 0x15, 0x02e0); ++ mdio_write(tp, 0x19, 0x4834); ++ mdio_write(tp, 0x15, 0x02e1); ++ mdio_write(tp, 0x19, 0x6c08); ++ mdio_write(tp, 0x15, 0x02e2); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x02e3); ++ mdio_write(tp, 0x19, 0x4824); ++ mdio_write(tp, 0x15, 0x02e4); ++ mdio_write(tp, 0x19, 0x4520); ++ mdio_write(tp, 0x15, 0x02e5); ++ mdio_write(tp, 0x19, 0x4008); ++ mdio_write(tp, 0x15, 0x02e6); ++ mdio_write(tp, 0x19, 0x4560); ++ mdio_write(tp, 0x15, 0x02e7); ++ mdio_write(tp, 0x19, 0x9d04); ++ mdio_write(tp, 0x15, 0x02e8); ++ mdio_write(tp, 0x19, 0x48c4); ++ mdio_write(tp, 0x15, 0x02e9); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02ea); ++ mdio_write(tp, 0x19, 0x4844); ++ mdio_write(tp, 0x15, 0x02eb); ++ mdio_write(tp, 0x19, 0x7dc8); ++ mdio_write(tp, 0x15, 0x02f0); ++ mdio_write(tp, 0x19, 0x9cf7); ++ mdio_write(tp, 0x15, 0x02f1); ++ mdio_write(tp, 0x19, 0xdf94); ++ mdio_write(tp, 0x15, 0x02f2); ++ mdio_write(tp, 0x19, 0x0002); ++ mdio_write(tp, 0x15, 0x02f3); ++ mdio_write(tp, 0x19, 0x6810); ++ mdio_write(tp, 0x15, 0x02f4); ++ mdio_write(tp, 0x19, 0xb614); ++ mdio_write(tp, 0x15, 0x02f5); ++ mdio_write(tp, 0x19, 0xc42b); ++ mdio_write(tp, 0x15, 0x02f6); ++ mdio_write(tp, 0x19, 0x00d4); ++ mdio_write(tp, 0x15, 0x02f7); ++ mdio_write(tp, 0x19, 0xc455); ++ mdio_write(tp, 0x15, 0x02f8); ++ mdio_write(tp, 0x19, 0x0093); ++ mdio_write(tp, 0x15, 0x02f9); ++ mdio_write(tp, 0x19, 0x92ee); ++ mdio_write(tp, 0x15, 0x02fa); ++ mdio_write(tp, 0x19, 0xefed); ++ mdio_write(tp, 0x15, 0x02fb); ++ mdio_write(tp, 0x19, 0x3312); ++ mdio_write(tp, 0x15, 0x0312); ++ mdio_write(tp, 0x19, 0x49b5); ++ mdio_write(tp, 0x15, 0x0313); ++ mdio_write(tp, 0x19, 0x7d00); ++ mdio_write(tp, 0x15, 0x0314); ++ mdio_write(tp, 0x19, 0x4d00); ++ mdio_write(tp, 0x15, 0x0315); ++ mdio_write(tp, 0x19, 0x6810); ++ mdio_write(tp, 0x15, 0x031e); ++ mdio_write(tp, 0x19, 0x404f); ++ mdio_write(tp, 0x15, 0x031f); ++ mdio_write(tp, 0x19, 0x44c8); ++ mdio_write(tp, 0x15, 0x0320); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x0321); ++ mdio_write(tp, 0x19, 0x00e7); ++ mdio_write(tp, 0x15, 0x0322); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x0323); ++ mdio_write(tp, 0x19, 0x8203); ++ mdio_write(tp, 0x15, 0x0324); ++ mdio_write(tp, 0x19, 0x4d48); ++ mdio_write(tp, 0x15, 0x0325); ++ mdio_write(tp, 0x19, 0x3327); ++ mdio_write(tp, 0x15, 0x0326); ++ mdio_write(tp, 0x19, 0x4d40); ++ mdio_write(tp, 0x15, 0x0327); ++ mdio_write(tp, 0x19, 0xc8d7); ++ mdio_write(tp, 0x15, 0x0328); ++ mdio_write(tp, 0x19, 0x0003); ++ mdio_write(tp, 0x15, 0x0329); ++ mdio_write(tp, 0x19, 0x7c20); ++ mdio_write(tp, 0x15, 0x032a); ++ mdio_write(tp, 0x19, 0x4c20); ++ mdio_write(tp, 0x15, 0x032b); ++ mdio_write(tp, 0x19, 0xc8ed); ++ mdio_write(tp, 0x15, 0x032c); ++ mdio_write(tp, 0x19, 0x00f4); ++ mdio_write(tp, 0x15, 0x032d); ++ mdio_write(tp, 0x19, 0x82b3); ++ mdio_write(tp, 0x15, 0x032e); ++ mdio_write(tp, 0x19, 0xd11d); ++ mdio_write(tp, 0x15, 0x032f); ++ mdio_write(tp, 0x19, 0x00b1); ++ mdio_write(tp, 0x15, 0x0330); ++ mdio_write(tp, 0x19, 0xde18); ++ mdio_write(tp, 0x15, 0x0331); ++ mdio_write(tp, 0x19, 0x0008); ++ mdio_write(tp, 0x15, 0x0332); ++ mdio_write(tp, 0x19, 0x91ee); ++ mdio_write(tp, 0x15, 0x0333); ++ mdio_write(tp, 0x19, 0x3339); ++ mdio_write(tp, 0x15, 0x033a); ++ mdio_write(tp, 0x19, 0x4064); ++ mdio_write(tp, 0x15, 0x0340); ++ mdio_write(tp, 0x19, 0x9e06); ++ mdio_write(tp, 0x15, 0x0341); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x0342); ++ mdio_write(tp, 0x19, 0x8203); ++ mdio_write(tp, 0x15, 0x0343); ++ mdio_write(tp, 0x19, 0x4d48); ++ mdio_write(tp, 0x15, 0x0344); ++ mdio_write(tp, 0x19, 0x3346); ++ mdio_write(tp, 0x15, 0x0345); ++ mdio_write(tp, 0x19, 0x4d40); ++ mdio_write(tp, 0x15, 0x0346); ++ mdio_write(tp, 0x19, 0xd11d); ++ mdio_write(tp, 0x15, 0x0347); ++ mdio_write(tp, 0x19, 0x0099); ++ mdio_write(tp, 0x15, 0x0348); ++ mdio_write(tp, 0x19, 0xbb17); ++ mdio_write(tp, 0x15, 0x0349); ++ mdio_write(tp, 0x19, 0x8102); ++ mdio_write(tp, 0x15, 0x034a); ++ mdio_write(tp, 0x19, 0x334d); ++ mdio_write(tp, 0x15, 0x034b); ++ mdio_write(tp, 0x19, 0xa22c); ++ mdio_write(tp, 0x15, 0x034c); ++ mdio_write(tp, 0x19, 0x3397); ++ mdio_write(tp, 0x15, 0x034d); ++ mdio_write(tp, 0x19, 0x91f2); ++ mdio_write(tp, 0x15, 0x034e); ++ mdio_write(tp, 0x19, 0xc218); ++ mdio_write(tp, 0x15, 0x034f); ++ mdio_write(tp, 0x19, 0x00f0); ++ mdio_write(tp, 0x15, 0x0350); ++ mdio_write(tp, 0x19, 0x3397); ++ mdio_write(tp, 0x15, 0x0351); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0364); ++ mdio_write(tp, 0x19, 0xbc05); ++ mdio_write(tp, 0x15, 0x0367); ++ mdio_write(tp, 0x19, 0xa1fc); ++ mdio_write(tp, 0x15, 0x0368); ++ mdio_write(tp, 0x19, 0x3377); ++ mdio_write(tp, 0x15, 0x0369); ++ mdio_write(tp, 0x19, 0x328b); ++ mdio_write(tp, 0x15, 0x036a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0377); ++ mdio_write(tp, 0x19, 0x4b97); ++ mdio_write(tp, 0x15, 0x0378); ++ mdio_write(tp, 0x19, 0x6818); ++ mdio_write(tp, 0x15, 0x0379); ++ mdio_write(tp, 0x19, 0x4b07); ++ mdio_write(tp, 0x15, 0x037a); ++ mdio_write(tp, 0x19, 0x40ac); ++ mdio_write(tp, 0x15, 0x037b); ++ mdio_write(tp, 0x19, 0x4445); ++ mdio_write(tp, 0x15, 0x037c); ++ mdio_write(tp, 0x19, 0x404e); ++ mdio_write(tp, 0x15, 0x037d); ++ mdio_write(tp, 0x19, 0x4461); ++ mdio_write(tp, 0x15, 0x037e); ++ mdio_write(tp, 0x19, 0x9c09); ++ mdio_write(tp, 0x15, 0x037f); ++ mdio_write(tp, 0x19, 0x63da); ++ mdio_write(tp, 0x15, 0x0380); ++ mdio_write(tp, 0x19, 0x5440); ++ mdio_write(tp, 0x15, 0x0381); ++ mdio_write(tp, 0x19, 0x4b98); ++ mdio_write(tp, 0x15, 0x0382); ++ mdio_write(tp, 0x19, 0x7c60); ++ mdio_write(tp, 0x15, 0x0383); ++ mdio_write(tp, 0x19, 0x4c00); ++ mdio_write(tp, 0x15, 0x0384); ++ mdio_write(tp, 0x19, 0x4b08); ++ mdio_write(tp, 0x15, 0x0385); ++ mdio_write(tp, 0x19, 0x63d8); ++ mdio_write(tp, 0x15, 0x0386); ++ mdio_write(tp, 0x19, 0x338d); ++ mdio_write(tp, 0x15, 0x0387); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x0388); ++ mdio_write(tp, 0x19, 0x0080); ++ mdio_write(tp, 0x15, 0x0389); ++ mdio_write(tp, 0x19, 0x820c); ++ mdio_write(tp, 0x15, 0x038a); ++ mdio_write(tp, 0x19, 0xa10b); ++ mdio_write(tp, 0x15, 0x038b); ++ mdio_write(tp, 0x19, 0x9df3); ++ mdio_write(tp, 0x15, 0x038c); ++ mdio_write(tp, 0x19, 0x3395); ++ mdio_write(tp, 0x15, 0x038d); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x038e); ++ mdio_write(tp, 0x19, 0x00f9); ++ mdio_write(tp, 0x15, 0x038f); ++ mdio_write(tp, 0x19, 0xc017); ++ mdio_write(tp, 0x15, 0x0390); ++ mdio_write(tp, 0x19, 0x0005); ++ mdio_write(tp, 0x15, 0x0391); ++ mdio_write(tp, 0x19, 0x6c0b); ++ mdio_write(tp, 0x15, 0x0392); ++ mdio_write(tp, 0x19, 0xa103); ++ mdio_write(tp, 0x15, 0x0393); ++ mdio_write(tp, 0x19, 0x6c08); ++ mdio_write(tp, 0x15, 0x0394); ++ mdio_write(tp, 0x19, 0x9df9); ++ mdio_write(tp, 0x15, 0x0395); ++ mdio_write(tp, 0x19, 0x6c08); ++ mdio_write(tp, 0x15, 0x0396); ++ mdio_write(tp, 0x19, 0x3397); ++ mdio_write(tp, 0x15, 0x0399); ++ mdio_write(tp, 0x19, 0x6810); ++ mdio_write(tp, 0x15, 0x03a4); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x03a5); ++ mdio_write(tp, 0x19, 0x8203); ++ mdio_write(tp, 0x15, 0x03a6); ++ mdio_write(tp, 0x19, 0x4d08); ++ mdio_write(tp, 0x15, 0x03a7); ++ mdio_write(tp, 0x19, 0x33a9); ++ mdio_write(tp, 0x15, 0x03a8); ++ mdio_write(tp, 0x19, 0x4d00); ++ mdio_write(tp, 0x15, 0x03a9); ++ mdio_write(tp, 0x19, 0x9bfa); ++ mdio_write(tp, 0x15, 0x03aa); ++ mdio_write(tp, 0x19, 0x33b6); ++ mdio_write(tp, 0x15, 0x03bb); ++ mdio_write(tp, 0x19, 0x4056); ++ mdio_write(tp, 0x15, 0x03bc); ++ mdio_write(tp, 0x19, 0x44e9); ++ mdio_write(tp, 0x15, 0x03bd); ++ mdio_write(tp, 0x19, 0x405e); ++ mdio_write(tp, 0x15, 0x03be); ++ mdio_write(tp, 0x19, 0x44f8); ++ mdio_write(tp, 0x15, 0x03bf); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x03c0); ++ mdio_write(tp, 0x19, 0x0037); ++ mdio_write(tp, 0x15, 0x03c1); ++ mdio_write(tp, 0x19, 0xbd37); ++ mdio_write(tp, 0x15, 0x03c2); ++ mdio_write(tp, 0x19, 0x9cfd); ++ mdio_write(tp, 0x15, 0x03c3); ++ mdio_write(tp, 0x19, 0xc639); ++ mdio_write(tp, 0x15, 0x03c4); ++ mdio_write(tp, 0x19, 0x0011); ++ mdio_write(tp, 0x15, 0x03c5); ++ mdio_write(tp, 0x19, 0x9b03); ++ mdio_write(tp, 0x15, 0x03c6); ++ mdio_write(tp, 0x19, 0x7c01); ++ mdio_write(tp, 0x15, 0x03c7); ++ mdio_write(tp, 0x19, 0x4c01); ++ mdio_write(tp, 0x15, 0x03c8); ++ mdio_write(tp, 0x19, 0x9e03); ++ mdio_write(tp, 0x15, 0x03c9); ++ mdio_write(tp, 0x19, 0x7c20); ++ mdio_write(tp, 0x15, 0x03ca); ++ mdio_write(tp, 0x19, 0x4c20); ++ mdio_write(tp, 0x15, 0x03cb); ++ mdio_write(tp, 0x19, 0x9af4); ++ mdio_write(tp, 0x15, 0x03cc); ++ mdio_write(tp, 0x19, 0x7c12); ++ mdio_write(tp, 0x15, 0x03cd); ++ mdio_write(tp, 0x19, 0x4c52); ++ mdio_write(tp, 0x15, 0x03ce); ++ mdio_write(tp, 0x19, 0x4470); ++ mdio_write(tp, 0x15, 0x03cf); ++ mdio_write(tp, 0x19, 0x7c12); ++ mdio_write(tp, 0x15, 0x03d0); ++ mdio_write(tp, 0x19, 0x4c40); ++ mdio_write(tp, 0x15, 0x03d1); ++ mdio_write(tp, 0x19, 0x33bf); ++ mdio_write(tp, 0x15, 0x03d6); ++ mdio_write(tp, 0x19, 0x4047); ++ mdio_write(tp, 0x15, 0x03d7); ++ mdio_write(tp, 0x19, 0x4469); ++ mdio_write(tp, 0x15, 0x03d8); ++ mdio_write(tp, 0x19, 0x492b); ++ mdio_write(tp, 0x15, 0x03d9); ++ mdio_write(tp, 0x19, 0x4479); ++ mdio_write(tp, 0x15, 0x03da); ++ mdio_write(tp, 0x19, 0x7c09); ++ mdio_write(tp, 0x15, 0x03db); ++ mdio_write(tp, 0x19, 0x8203); ++ mdio_write(tp, 0x15, 0x03dc); ++ mdio_write(tp, 0x19, 0x4d48); ++ mdio_write(tp, 0x15, 0x03dd); ++ mdio_write(tp, 0x19, 0x33df); ++ mdio_write(tp, 0x15, 0x03de); ++ mdio_write(tp, 0x19, 0x4d40); ++ mdio_write(tp, 0x15, 0x03df); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x03e0); ++ mdio_write(tp, 0x19, 0x0017); ++ mdio_write(tp, 0x15, 0x03e1); ++ mdio_write(tp, 0x19, 0xbd17); ++ mdio_write(tp, 0x15, 0x03e2); ++ mdio_write(tp, 0x19, 0x9b03); ++ mdio_write(tp, 0x15, 0x03e3); ++ mdio_write(tp, 0x19, 0x7c20); ++ mdio_write(tp, 0x15, 0x03e4); ++ mdio_write(tp, 0x19, 0x4c20); ++ mdio_write(tp, 0x15, 0x03e5); ++ mdio_write(tp, 0x19, 0x88f5); ++ mdio_write(tp, 0x15, 0x03e6); ++ mdio_write(tp, 0x19, 0xc428); ++ mdio_write(tp, 0x15, 0x03e7); ++ mdio_write(tp, 0x19, 0x0008); ++ mdio_write(tp, 0x15, 0x03e8); ++ mdio_write(tp, 0x19, 0x9af2); ++ mdio_write(tp, 0x15, 0x03e9); ++ mdio_write(tp, 0x19, 0x7c12); ++ mdio_write(tp, 0x15, 0x03ea); ++ mdio_write(tp, 0x19, 0x4c52); ++ mdio_write(tp, 0x15, 0x03eb); ++ mdio_write(tp, 0x19, 0x4470); ++ mdio_write(tp, 0x15, 0x03ec); ++ mdio_write(tp, 0x19, 0x7c12); ++ mdio_write(tp, 0x15, 0x03ed); ++ mdio_write(tp, 0x19, 0x4c40); ++ mdio_write(tp, 0x15, 0x03ee); ++ mdio_write(tp, 0x19, 0x33da); ++ mdio_write(tp, 0x15, 0x03ef); ++ mdio_write(tp, 0x19, 0x3312); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0300); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x17, 0x2179); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0040); ++ mdio_write(tp, 0x18, 0x0645); ++ mdio_write(tp, 0x19, 0xe200); ++ mdio_write(tp, 0x18, 0x0655); ++ mdio_write(tp, 0x19, 0x9000); ++ mdio_write(tp, 0x18, 0x0d05); ++ mdio_write(tp, 0x19, 0xbe00); ++ mdio_write(tp, 0x18, 0x0d15); ++ mdio_write(tp, 0x19, 0xd300); ++ mdio_write(tp, 0x18, 0x0d25); ++ mdio_write(tp, 0x19, 0xfe00); ++ mdio_write(tp, 0x18, 0x0d35); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x0d45); ++ mdio_write(tp, 0x19, 0x7f00); ++ mdio_write(tp, 0x18, 0x0d55); ++ mdio_write(tp, 0x19, 0x1000); ++ mdio_write(tp, 0x18, 0x0d65); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x0d75); ++ mdio_write(tp, 0x19, 0x8200); ++ mdio_write(tp, 0x18, 0x0d85); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x0d95); ++ mdio_write(tp, 0x19, 0x7000); ++ mdio_write(tp, 0x18, 0x0da5); ++ mdio_write(tp, 0x19, 0x0f00); ++ mdio_write(tp, 0x18, 0x0db5); ++ mdio_write(tp, 0x19, 0x0100); ++ mdio_write(tp, 0x18, 0x0dc5); ++ mdio_write(tp, 0x19, 0x9b00); ++ mdio_write(tp, 0x18, 0x0dd5); ++ mdio_write(tp, 0x19, 0x7f00); ++ mdio_write(tp, 0x18, 0x0de5); ++ mdio_write(tp, 0x19, 0xe000); ++ mdio_write(tp, 0x18, 0x0df5); ++ mdio_write(tp, 0x19, 0xef00); ++ mdio_write(tp, 0x18, 0x16d5); ++ mdio_write(tp, 0x19, 0xe200); ++ mdio_write(tp, 0x18, 0x16e5); ++ mdio_write(tp, 0x19, 0xab00); ++ mdio_write(tp, 0x18, 0x2904); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x2914); ++ mdio_write(tp, 0x19, 0x7f00); ++ mdio_write(tp, 0x18, 0x2924); ++ mdio_write(tp, 0x19, 0x0100); ++ mdio_write(tp, 0x18, 0x2934); ++ mdio_write(tp, 0x19, 0x2000); ++ mdio_write(tp, 0x18, 0x2944); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x2954); ++ mdio_write(tp, 0x19, 0x4600); ++ mdio_write(tp, 0x18, 0x2964); ++ mdio_write(tp, 0x19, 0xfc00); ++ mdio_write(tp, 0x18, 0x2974); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x2984); ++ mdio_write(tp, 0x19, 0x5000); ++ mdio_write(tp, 0x18, 0x2994); ++ mdio_write(tp, 0x19, 0x9d00); ++ mdio_write(tp, 0x18, 0x29a4); ++ mdio_write(tp, 0x19, 0xff00); ++ mdio_write(tp, 0x18, 0x29b4); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x29c4); ++ mdio_write(tp, 0x19, 0x7f00); ++ mdio_write(tp, 0x18, 0x29d4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x29e4); ++ mdio_write(tp, 0x19, 0x2000); ++ mdio_write(tp, 0x18, 0x29f4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x2a04); ++ mdio_write(tp, 0x19, 0xe600); ++ mdio_write(tp, 0x18, 0x2a14); ++ mdio_write(tp, 0x19, 0xff00); ++ mdio_write(tp, 0x18, 0x2a24); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x2a34); ++ mdio_write(tp, 0x19, 0x5000); ++ mdio_write(tp, 0x18, 0x2a44); ++ mdio_write(tp, 0x19, 0x8500); ++ mdio_write(tp, 0x18, 0x2a54); ++ mdio_write(tp, 0x19, 0x7f00); ++ mdio_write(tp, 0x18, 0x2a64); ++ mdio_write(tp, 0x19, 0xac00); ++ mdio_write(tp, 0x18, 0x2a74); ++ mdio_write(tp, 0x19, 0x0800); ++ mdio_write(tp, 0x18, 0x2a84); ++ mdio_write(tp, 0x19, 0xfc00); ++ mdio_write(tp, 0x18, 0x2a94); ++ mdio_write(tp, 0x19, 0xe000); ++ mdio_write(tp, 0x18, 0x2aa4); ++ mdio_write(tp, 0x19, 0x7400); ++ mdio_write(tp, 0x18, 0x2ab4); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x2ac4); ++ mdio_write(tp, 0x19, 0x7f00); ++ mdio_write(tp, 0x18, 0x2ad4); ++ mdio_write(tp, 0x19, 0x0100); ++ mdio_write(tp, 0x18, 0x2ae4); ++ mdio_write(tp, 0x19, 0xff00); ++ mdio_write(tp, 0x18, 0x2af4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x2b04); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x18, 0x2b14); ++ mdio_write(tp, 0x19, 0xfc00); ++ mdio_write(tp, 0x18, 0x2b24); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x2b34); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x2b44); ++ mdio_write(tp, 0x19, 0x9d00); ++ mdio_write(tp, 0x18, 0x2b54); ++ mdio_write(tp, 0x19, 0xff00); ++ mdio_write(tp, 0x18, 0x2b64); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x2b74); ++ mdio_write(tp, 0x19, 0x7f00); ++ mdio_write(tp, 0x18, 0x2b84); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x2b94); ++ mdio_write(tp, 0x19, 0xff00); ++ mdio_write(tp, 0x18, 0x2ba4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x2bb4); ++ mdio_write(tp, 0x19, 0xfc00); ++ mdio_write(tp, 0x18, 0x2bc4); ++ mdio_write(tp, 0x19, 0xff00); ++ mdio_write(tp, 0x18, 0x2bd4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x2be4); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x2bf4); ++ mdio_write(tp, 0x19, 0x8900); ++ mdio_write(tp, 0x18, 0x2c04); ++ mdio_write(tp, 0x19, 0x8300); ++ mdio_write(tp, 0x18, 0x2c14); ++ mdio_write(tp, 0x19, 0xe000); ++ mdio_write(tp, 0x18, 0x2c24); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x18, 0x2c34); ++ mdio_write(tp, 0x19, 0xac00); ++ mdio_write(tp, 0x18, 0x2c44); ++ mdio_write(tp, 0x19, 0x0800); ++ mdio_write(tp, 0x18, 0x2c54); ++ mdio_write(tp, 0x19, 0xfa00); ++ mdio_write(tp, 0x18, 0x2c64); ++ mdio_write(tp, 0x19, 0xe100); ++ mdio_write(tp, 0x18, 0x2c74); ++ mdio_write(tp, 0x19, 0x7f00); ++ mdio_write(tp, 0x18, 0x0001); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x17, 0x2100); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x05, 0x8b88); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x05, 0x8000); ++ mdio_write(tp, 0x06, 0xd480); ++ mdio_write(tp, 0x06, 0xc1e4); ++ mdio_write(tp, 0x06, 0x8b9a); ++ mdio_write(tp, 0x06, 0xe58b); ++ mdio_write(tp, 0x06, 0x9bee); ++ mdio_write(tp, 0x06, 0x8b83); ++ mdio_write(tp, 0x06, 0x41bf); ++ mdio_write(tp, 0x06, 0x8b88); ++ mdio_write(tp, 0x06, 0xec00); ++ mdio_write(tp, 0x06, 0x19a9); ++ mdio_write(tp, 0x06, 0x8b90); ++ mdio_write(tp, 0x06, 0xf9ee); ++ mdio_write(tp, 0x06, 0xfff6); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0xffe0); ++ mdio_write(tp, 0x06, 0xe140); ++ mdio_write(tp, 0x06, 0xe1e1); ++ mdio_write(tp, 0x06, 0x41f7); ++ mdio_write(tp, 0x06, 0x2ff6); ++ mdio_write(tp, 0x06, 0x28e4); ++ mdio_write(tp, 0x06, 0xe140); ++ mdio_write(tp, 0x06, 0xe5e1); ++ mdio_write(tp, 0x06, 0x41f7); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x020c); ++ mdio_write(tp, 0x06, 0x0202); ++ mdio_write(tp, 0x06, 0x1d02); ++ mdio_write(tp, 0x06, 0x0230); ++ mdio_write(tp, 0x06, 0x0202); ++ mdio_write(tp, 0x06, 0x4002); ++ mdio_write(tp, 0x06, 0x028b); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0x6c02); ++ mdio_write(tp, 0x06, 0x8085); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x88e1); ++ mdio_write(tp, 0x06, 0x8b89); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8a1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8b); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8c1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8e1e); ++ mdio_write(tp, 0x06, 0x01a0); ++ mdio_write(tp, 0x06, 0x00c7); ++ mdio_write(tp, 0x06, 0xaec3); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x10ee); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x1310); ++ mdio_write(tp, 0x06, 0x021f); ++ mdio_write(tp, 0x06, 0x9d02); ++ mdio_write(tp, 0x06, 0x1f0c); ++ mdio_write(tp, 0x06, 0x0227); ++ mdio_write(tp, 0x06, 0x49fc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x200b); ++ mdio_write(tp, 0x06, 0xf620); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x830e); ++ mdio_write(tp, 0x06, 0x021b); ++ mdio_write(tp, 0x06, 0x67ad); ++ mdio_write(tp, 0x06, 0x2211); ++ mdio_write(tp, 0x06, 0xf622); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x2ba5); ++ mdio_write(tp, 0x06, 0x022a); ++ mdio_write(tp, 0x06, 0x2402); ++ mdio_write(tp, 0x06, 0x80c6); ++ mdio_write(tp, 0x06, 0x022a); ++ mdio_write(tp, 0x06, 0xf0ad); ++ mdio_write(tp, 0x06, 0x2511); ++ mdio_write(tp, 0x06, 0xf625); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x8226); ++ mdio_write(tp, 0x06, 0x0204); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x19cc); ++ mdio_write(tp, 0x06, 0x022b); ++ mdio_write(tp, 0x06, 0x5bfc); ++ mdio_write(tp, 0x06, 0x04ee); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0x0105); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b83); ++ mdio_write(tp, 0x06, 0xad24); ++ mdio_write(tp, 0x06, 0x44e0); ++ mdio_write(tp, 0x06, 0xe022); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x23ad); ++ mdio_write(tp, 0x06, 0x223b); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xbea0); ++ mdio_write(tp, 0x06, 0x0005); ++ mdio_write(tp, 0x06, 0x0228); ++ mdio_write(tp, 0x06, 0xdeae); ++ mdio_write(tp, 0x06, 0x42a0); ++ mdio_write(tp, 0x06, 0x0105); ++ mdio_write(tp, 0x06, 0x0228); ++ mdio_write(tp, 0x06, 0xf1ae); ++ mdio_write(tp, 0x06, 0x3aa0); ++ mdio_write(tp, 0x06, 0x0205); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0x25ae); ++ mdio_write(tp, 0x06, 0x32a0); ++ mdio_write(tp, 0x06, 0x0305); ++ mdio_write(tp, 0x06, 0x0229); ++ mdio_write(tp, 0x06, 0x9aae); ++ mdio_write(tp, 0x06, 0x2aa0); ++ mdio_write(tp, 0x06, 0x0405); ++ mdio_write(tp, 0x06, 0x0229); ++ mdio_write(tp, 0x06, 0xaeae); ++ mdio_write(tp, 0x06, 0x22a0); ++ mdio_write(tp, 0x06, 0x0505); ++ mdio_write(tp, 0x06, 0x0229); ++ mdio_write(tp, 0x06, 0xd7ae); ++ mdio_write(tp, 0x06, 0x1aa0); ++ mdio_write(tp, 0x06, 0x0605); ++ mdio_write(tp, 0x06, 0x0229); ++ mdio_write(tp, 0x06, 0xfeae); ++ mdio_write(tp, 0x06, 0x12ee); ++ mdio_write(tp, 0x06, 0x8ac0); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8ac1); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8ac6); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8abe); ++ mdio_write(tp, 0x06, 0x00ae); ++ mdio_write(tp, 0x06, 0x00fc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0x022a); ++ mdio_write(tp, 0x06, 0x67e0); ++ mdio_write(tp, 0x06, 0xe022); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x230d); ++ mdio_write(tp, 0x06, 0x0658); ++ mdio_write(tp, 0x06, 0x03a0); ++ mdio_write(tp, 0x06, 0x0202); ++ mdio_write(tp, 0x06, 0xae2d); ++ mdio_write(tp, 0x06, 0xa001); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x2da0); ++ mdio_write(tp, 0x06, 0x004d); ++ mdio_write(tp, 0x06, 0xe0e2); ++ mdio_write(tp, 0x06, 0x00e1); ++ mdio_write(tp, 0x06, 0xe201); ++ mdio_write(tp, 0x06, 0xad24); ++ mdio_write(tp, 0x06, 0x44e0); ++ mdio_write(tp, 0x06, 0x8ac2); ++ mdio_write(tp, 0x06, 0xe48a); ++ mdio_write(tp, 0x06, 0xc4e0); ++ mdio_write(tp, 0x06, 0x8ac3); ++ mdio_write(tp, 0x06, 0xe48a); ++ mdio_write(tp, 0x06, 0xc5ee); ++ mdio_write(tp, 0x06, 0x8abe); ++ mdio_write(tp, 0x06, 0x03e0); ++ mdio_write(tp, 0x06, 0x8b83); ++ mdio_write(tp, 0x06, 0xad25); ++ mdio_write(tp, 0x06, 0x3aee); ++ mdio_write(tp, 0x06, 0x8abe); ++ mdio_write(tp, 0x06, 0x05ae); ++ mdio_write(tp, 0x06, 0x34e0); ++ mdio_write(tp, 0x06, 0x8ace); ++ mdio_write(tp, 0x06, 0xae03); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xcfe1); ++ mdio_write(tp, 0x06, 0x8ac2); ++ mdio_write(tp, 0x06, 0x4905); ++ mdio_write(tp, 0x06, 0xe58a); ++ mdio_write(tp, 0x06, 0xc4e1); ++ mdio_write(tp, 0x06, 0x8ac3); ++ mdio_write(tp, 0x06, 0x4905); ++ mdio_write(tp, 0x06, 0xe58a); ++ mdio_write(tp, 0x06, 0xc5ee); ++ mdio_write(tp, 0x06, 0x8abe); ++ mdio_write(tp, 0x06, 0x0502); ++ mdio_write(tp, 0x06, 0x2ab6); ++ mdio_write(tp, 0x06, 0xac20); ++ mdio_write(tp, 0x06, 0x1202); ++ mdio_write(tp, 0x06, 0x819b); ++ mdio_write(tp, 0x06, 0xac20); ++ mdio_write(tp, 0x06, 0x0cee); ++ mdio_write(tp, 0x06, 0x8ac1); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8ac6); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8abe); ++ mdio_write(tp, 0x06, 0x02fc); ++ mdio_write(tp, 0x06, 0x04d0); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x590f); ++ mdio_write(tp, 0x06, 0x3902); ++ mdio_write(tp, 0x06, 0xaa04); ++ mdio_write(tp, 0x06, 0xd001); ++ mdio_write(tp, 0x06, 0xae02); ++ mdio_write(tp, 0x06, 0xd000); ++ mdio_write(tp, 0x06, 0x04f9); ++ mdio_write(tp, 0x06, 0xfae2); ++ mdio_write(tp, 0x06, 0xe2d2); ++ mdio_write(tp, 0x06, 0xe3e2); ++ mdio_write(tp, 0x06, 0xd3f9); ++ mdio_write(tp, 0x06, 0x5af7); ++ mdio_write(tp, 0x06, 0xe6e2); ++ mdio_write(tp, 0x06, 0xd2e7); ++ mdio_write(tp, 0x06, 0xe2d3); ++ mdio_write(tp, 0x06, 0xe2e0); ++ mdio_write(tp, 0x06, 0x2ce3); ++ mdio_write(tp, 0x06, 0xe02d); ++ mdio_write(tp, 0x06, 0xf95b); ++ mdio_write(tp, 0x06, 0xe01e); ++ mdio_write(tp, 0x06, 0x30e6); ++ mdio_write(tp, 0x06, 0xe02c); ++ mdio_write(tp, 0x06, 0xe7e0); ++ mdio_write(tp, 0x06, 0x2de2); ++ mdio_write(tp, 0x06, 0xe2cc); ++ mdio_write(tp, 0x06, 0xe3e2); ++ mdio_write(tp, 0x06, 0xcdf9); ++ mdio_write(tp, 0x06, 0x5a0f); ++ mdio_write(tp, 0x06, 0x6a50); ++ mdio_write(tp, 0x06, 0xe6e2); ++ mdio_write(tp, 0x06, 0xcce7); ++ mdio_write(tp, 0x06, 0xe2cd); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x3ce1); ++ mdio_write(tp, 0x06, 0xe03d); ++ mdio_write(tp, 0x06, 0xef64); ++ mdio_write(tp, 0x06, 0xfde0); ++ mdio_write(tp, 0x06, 0xe2cc); ++ mdio_write(tp, 0x06, 0xe1e2); ++ mdio_write(tp, 0x06, 0xcd58); ++ mdio_write(tp, 0x06, 0x0f5a); ++ mdio_write(tp, 0x06, 0xf01e); ++ mdio_write(tp, 0x06, 0x02e4); ++ mdio_write(tp, 0x06, 0xe2cc); ++ mdio_write(tp, 0x06, 0xe5e2); ++ mdio_write(tp, 0x06, 0xcdfd); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x2ce1); ++ mdio_write(tp, 0x06, 0xe02d); ++ mdio_write(tp, 0x06, 0x59e0); ++ mdio_write(tp, 0x06, 0x5b1f); ++ mdio_write(tp, 0x06, 0x1e13); ++ mdio_write(tp, 0x06, 0xe4e0); ++ mdio_write(tp, 0x06, 0x2ce5); ++ mdio_write(tp, 0x06, 0xe02d); ++ mdio_write(tp, 0x06, 0xfde0); ++ mdio_write(tp, 0x06, 0xe2d2); ++ mdio_write(tp, 0x06, 0xe1e2); ++ mdio_write(tp, 0x06, 0xd358); ++ mdio_write(tp, 0x06, 0xf75a); ++ mdio_write(tp, 0x06, 0x081e); ++ mdio_write(tp, 0x06, 0x02e4); ++ mdio_write(tp, 0x06, 0xe2d2); ++ mdio_write(tp, 0x06, 0xe5e2); ++ mdio_write(tp, 0x06, 0xd3ef); ++ mdio_write(tp, 0x06, 0x46fe); ++ mdio_write(tp, 0x06, 0xfd04); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69e0); ++ mdio_write(tp, 0x06, 0xe022); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x2358); ++ mdio_write(tp, 0x06, 0xc4e1); ++ mdio_write(tp, 0x06, 0x8b6e); ++ mdio_write(tp, 0x06, 0x1f10); ++ mdio_write(tp, 0x06, 0x9e58); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x6ead); ++ mdio_write(tp, 0x06, 0x2222); ++ mdio_write(tp, 0x06, 0xac27); ++ mdio_write(tp, 0x06, 0x55ac); ++ mdio_write(tp, 0x06, 0x2602); ++ mdio_write(tp, 0x06, 0xae1a); ++ mdio_write(tp, 0x06, 0xd106); ++ mdio_write(tp, 0x06, 0xbf3b); ++ mdio_write(tp, 0x06, 0xba02); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xd107); ++ mdio_write(tp, 0x06, 0xbf3b); ++ mdio_write(tp, 0x06, 0xbd02); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xd107); ++ mdio_write(tp, 0x06, 0xbf3b); ++ mdio_write(tp, 0x06, 0xc002); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xae30); ++ mdio_write(tp, 0x06, 0xd103); ++ mdio_write(tp, 0x06, 0xbf3b); ++ mdio_write(tp, 0x06, 0xc302); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf3b); ++ mdio_write(tp, 0x06, 0xc602); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xca02); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xd10f); ++ mdio_write(tp, 0x06, 0xbf3b); ++ mdio_write(tp, 0x06, 0xba02); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xbf3b); ++ mdio_write(tp, 0x06, 0xbd02); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xbf3b); ++ mdio_write(tp, 0x06, 0xc002); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfefd); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf3b); ++ mdio_write(tp, 0x06, 0xc302); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xd011); ++ mdio_write(tp, 0x06, 0x022b); ++ mdio_write(tp, 0x06, 0xfb59); ++ mdio_write(tp, 0x06, 0x03ef); ++ mdio_write(tp, 0x06, 0x01d1); ++ mdio_write(tp, 0x06, 0x00a0); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xbf3b); ++ mdio_write(tp, 0x06, 0xc602); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xd111); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x020c); ++ mdio_write(tp, 0x06, 0x11ad); ++ mdio_write(tp, 0x06, 0x2102); ++ mdio_write(tp, 0x06, 0x0c12); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xca02); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xaec8); ++ mdio_write(tp, 0x06, 0x70e4); ++ mdio_write(tp, 0x06, 0x2602); ++ mdio_write(tp, 0x06, 0x82d1); ++ mdio_write(tp, 0x06, 0x05f8); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69e0); ++ mdio_write(tp, 0x06, 0xe2fe); ++ mdio_write(tp, 0x06, 0xe1e2); ++ mdio_write(tp, 0x06, 0xffad); ++ mdio_write(tp, 0x06, 0x2d1a); ++ mdio_write(tp, 0x06, 0xe0e1); ++ mdio_write(tp, 0x06, 0x4ee1); ++ mdio_write(tp, 0x06, 0xe14f); ++ mdio_write(tp, 0x06, 0xac2d); ++ mdio_write(tp, 0x06, 0x22f6); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x033b); ++ mdio_write(tp, 0x06, 0xf703); ++ mdio_write(tp, 0x06, 0xf706); ++ mdio_write(tp, 0x06, 0xbf84); ++ mdio_write(tp, 0x06, 0x4402); ++ mdio_write(tp, 0x06, 0x2d21); ++ mdio_write(tp, 0x06, 0xae11); ++ mdio_write(tp, 0x06, 0xe0e1); ++ mdio_write(tp, 0x06, 0x4ee1); ++ mdio_write(tp, 0x06, 0xe14f); ++ mdio_write(tp, 0x06, 0xad2d); ++ mdio_write(tp, 0x06, 0x08bf); ++ mdio_write(tp, 0x06, 0x844f); ++ mdio_write(tp, 0x06, 0x022d); ++ mdio_write(tp, 0x06, 0x21f6); ++ mdio_write(tp, 0x06, 0x06ef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0x0283); ++ mdio_write(tp, 0x06, 0x4502); ++ mdio_write(tp, 0x06, 0x83a2); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x00e1); ++ mdio_write(tp, 0x06, 0xe001); ++ mdio_write(tp, 0x06, 0xad27); ++ mdio_write(tp, 0x06, 0x1fd1); ++ mdio_write(tp, 0x06, 0x01bf); ++ mdio_write(tp, 0x06, 0x843b); ++ mdio_write(tp, 0x06, 0x022d); ++ mdio_write(tp, 0x06, 0xc1e0); ++ mdio_write(tp, 0x06, 0xe020); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x21ad); ++ mdio_write(tp, 0x06, 0x200e); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf84); ++ mdio_write(tp, 0x06, 0x3b02); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xbf3b); ++ mdio_write(tp, 0x06, 0x9602); ++ mdio_write(tp, 0x06, 0x2d21); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfefc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xf9fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x87ad); ++ mdio_write(tp, 0x06, 0x204c); ++ mdio_write(tp, 0x06, 0xd200); ++ mdio_write(tp, 0x06, 0xe0e2); ++ mdio_write(tp, 0x06, 0x0058); ++ mdio_write(tp, 0x06, 0x010c); ++ mdio_write(tp, 0x06, 0x021e); ++ mdio_write(tp, 0x06, 0x20e0); ++ mdio_write(tp, 0x06, 0xe000); ++ mdio_write(tp, 0x06, 0x5810); ++ mdio_write(tp, 0x06, 0x1e20); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x3658); ++ mdio_write(tp, 0x06, 0x031e); ++ mdio_write(tp, 0x06, 0x20e0); ++ mdio_write(tp, 0x06, 0xe022); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x2358); ++ mdio_write(tp, 0x06, 0xe01e); ++ mdio_write(tp, 0x06, 0x20e0); ++ mdio_write(tp, 0x06, 0x8b64); ++ mdio_write(tp, 0x06, 0x1f02); ++ mdio_write(tp, 0x06, 0x9e22); ++ mdio_write(tp, 0x06, 0xe68b); ++ mdio_write(tp, 0x06, 0x64ad); ++ mdio_write(tp, 0x06, 0x3214); ++ mdio_write(tp, 0x06, 0xad34); ++ mdio_write(tp, 0x06, 0x11ef); ++ mdio_write(tp, 0x06, 0x0258); ++ mdio_write(tp, 0x06, 0x039e); ++ mdio_write(tp, 0x06, 0x07ad); ++ mdio_write(tp, 0x06, 0x3508); ++ mdio_write(tp, 0x06, 0x5ac0); ++ mdio_write(tp, 0x06, 0x9f04); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xae02); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf84); ++ mdio_write(tp, 0x06, 0x3e02); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfefd); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xfbe0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xad25); ++ mdio_write(tp, 0x06, 0x22e0); ++ mdio_write(tp, 0x06, 0xe022); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x23e2); ++ mdio_write(tp, 0x06, 0xe036); ++ mdio_write(tp, 0x06, 0xe3e0); ++ mdio_write(tp, 0x06, 0x375a); ++ mdio_write(tp, 0x06, 0xc40d); ++ mdio_write(tp, 0x06, 0x0158); ++ mdio_write(tp, 0x06, 0x021e); ++ mdio_write(tp, 0x06, 0x20e3); ++ mdio_write(tp, 0x06, 0x8ae7); ++ mdio_write(tp, 0x06, 0xac31); ++ mdio_write(tp, 0x06, 0x60ac); ++ mdio_write(tp, 0x06, 0x3a08); ++ mdio_write(tp, 0x06, 0xac3e); ++ mdio_write(tp, 0x06, 0x26ae); ++ mdio_write(tp, 0x06, 0x67af); ++ mdio_write(tp, 0x06, 0x8437); ++ mdio_write(tp, 0x06, 0xad37); ++ mdio_write(tp, 0x06, 0x61e0); ++ mdio_write(tp, 0x06, 0x8ae8); ++ mdio_write(tp, 0x06, 0x10e4); ++ mdio_write(tp, 0x06, 0x8ae8); ++ mdio_write(tp, 0x06, 0xe18a); ++ mdio_write(tp, 0x06, 0xe91b); ++ mdio_write(tp, 0x06, 0x109e); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x51d1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x8441); ++ mdio_write(tp, 0x06, 0x022d); ++ mdio_write(tp, 0x06, 0xc1ee); ++ mdio_write(tp, 0x06, 0x8ae8); ++ mdio_write(tp, 0x06, 0x00ae); ++ mdio_write(tp, 0x06, 0x43ad); ++ mdio_write(tp, 0x06, 0x3627); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xeee1); ++ mdio_write(tp, 0x06, 0x8aef); ++ mdio_write(tp, 0x06, 0xef74); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xeae1); ++ mdio_write(tp, 0x06, 0x8aeb); ++ mdio_write(tp, 0x06, 0x1b74); ++ mdio_write(tp, 0x06, 0x9e2e); ++ mdio_write(tp, 0x06, 0x14e4); ++ mdio_write(tp, 0x06, 0x8aea); ++ mdio_write(tp, 0x06, 0xe58a); ++ mdio_write(tp, 0x06, 0xebef); ++ mdio_write(tp, 0x06, 0x74e0); ++ mdio_write(tp, 0x06, 0x8aee); ++ mdio_write(tp, 0x06, 0xe18a); ++ mdio_write(tp, 0x06, 0xef1b); ++ mdio_write(tp, 0x06, 0x479e); ++ mdio_write(tp, 0x06, 0x0fae); ++ mdio_write(tp, 0x06, 0x19ee); ++ mdio_write(tp, 0x06, 0x8aea); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8aeb); ++ mdio_write(tp, 0x06, 0x00ae); ++ mdio_write(tp, 0x06, 0x0fac); ++ mdio_write(tp, 0x06, 0x390c); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xbf84); ++ mdio_write(tp, 0x06, 0x4102); ++ mdio_write(tp, 0x06, 0x2dc1); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0xe800); ++ mdio_write(tp, 0x06, 0xe68a); ++ mdio_write(tp, 0x06, 0xe7ff); ++ mdio_write(tp, 0x06, 0xfdfc); ++ mdio_write(tp, 0x06, 0x0400); ++ mdio_write(tp, 0x06, 0xe234); ++ mdio_write(tp, 0x06, 0xcce2); ++ mdio_write(tp, 0x06, 0x0088); ++ mdio_write(tp, 0x06, 0xe200); ++ mdio_write(tp, 0x06, 0xa725); ++ mdio_write(tp, 0x06, 0xe50a); ++ mdio_write(tp, 0x06, 0x1de5); ++ mdio_write(tp, 0x06, 0x0a2c); ++ mdio_write(tp, 0x06, 0xe50a); ++ mdio_write(tp, 0x06, 0x6de5); ++ mdio_write(tp, 0x06, 0x0a1d); ++ mdio_write(tp, 0x06, 0xe50a); ++ mdio_write(tp, 0x06, 0x1ce5); ++ mdio_write(tp, 0x06, 0x0a2d); ++ mdio_write(tp, 0x06, 0xa755); ++ mdio_write(tp, 0x05, 0x8b64); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x05, 0x8b94); ++ mdio_write(tp, 0x06, 0x82cd); ++ mdio_write(tp, 0x05, 0x8b85); ++ mdio_write(tp, 0x06, 0x2000); ++ mdio_write(tp, 0x05, 0x8aee); ++ mdio_write(tp, 0x06, 0x03b8); ++ mdio_write(tp, 0x05, 0x8ae8); ++ mdio_write(tp, 0x06, 0x0002); ++ gphy_val = mdio_read(tp, 0x01); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x01, gphy_val); ++ gphy_val = mdio_read(tp, 0x00); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x00, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0005); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x00); ++ if (gphy_val & BIT_7) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ gphy_val = mdio_read(tp, 0x17); ++ gphy_val &= ~(BIT_0); ++ if ((pdev->subsystem_vendor == 0x144d && ++ pdev->subsystem_device == 0xc098) || ++ (pdev->subsystem_vendor == 0x144d && ++ pdev->subsystem_device == 0xc0b1)) { ++ gphy_val &= ~(BIT_2); ++ } ++ mdio_write(tp, 0x17, gphy_val); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0028); ++ mdio_write(tp, 0x15, 0x0010); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0041); ++ mdio_write(tp, 0x15, 0x0802); ++ mdio_write(tp, 0x16, 0x2185); ++ mdio_write(tp, 0x1f, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ } else { ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x1800); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ mdio_write(tp, 0x17, 0x0117); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1E, 0x002C); ++ mdio_write(tp, 0x1B, 0x5000); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x16, 0x4104); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x1E); ++ gphy_val &= 0x03FF; ++ if (gphy_val==0x000C) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0005); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x07); ++ if ((gphy_val & BIT_5) == 0) ++ break; ++ } ++ gphy_val = mdio_read(tp, 0x07); ++ if (gphy_val & BIT_5) { ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x00a1); ++ mdio_write(tp, 0x17, 0x1000); ++ mdio_write(tp, 0x17, 0x0000); ++ mdio_write(tp, 0x17, 0x2000); ++ mdio_write(tp, 0x1e, 0x002f); ++ mdio_write(tp, 0x18, 0x9bfb); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x07, 0x0000); ++ mdio_write(tp, 0x1f, 0x0000); ++ } ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ gphy_val = mdio_read(tp, 0x00); ++ gphy_val &= ~(BIT_7); ++ mdio_write(tp, 0x00, gphy_val); ++ mdio_write(tp, 0x1f, 0x0002); ++ gphy_val = mdio_read(tp, 0x08); ++ gphy_val &= ~(BIT_7); ++ mdio_write(tp, 0x08, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0307); ++ mdio_write(tp, 0x15, 0x000e); ++ mdio_write(tp, 0x19, 0x000a); ++ mdio_write(tp, 0x15, 0x0010); ++ mdio_write(tp, 0x19, 0x0008); ++ mdio_write(tp, 0x15, 0x0018); ++ mdio_write(tp, 0x19, 0x4801); ++ mdio_write(tp, 0x15, 0x0019); ++ mdio_write(tp, 0x19, 0x6801); ++ mdio_write(tp, 0x15, 0x001a); ++ mdio_write(tp, 0x19, 0x66a1); ++ mdio_write(tp, 0x15, 0x001f); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0020); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0021); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0022); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0023); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0024); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0025); ++ mdio_write(tp, 0x19, 0x64a1); ++ mdio_write(tp, 0x15, 0x0026); ++ mdio_write(tp, 0x19, 0x40ea); ++ mdio_write(tp, 0x15, 0x0027); ++ mdio_write(tp, 0x19, 0x4503); ++ mdio_write(tp, 0x15, 0x0028); ++ mdio_write(tp, 0x19, 0x9f00); ++ mdio_write(tp, 0x15, 0x0029); ++ mdio_write(tp, 0x19, 0xa631); ++ mdio_write(tp, 0x15, 0x002a); ++ mdio_write(tp, 0x19, 0x9717); ++ mdio_write(tp, 0x15, 0x002b); ++ mdio_write(tp, 0x19, 0x302c); ++ mdio_write(tp, 0x15, 0x002c); ++ mdio_write(tp, 0x19, 0x4802); ++ mdio_write(tp, 0x15, 0x002d); ++ mdio_write(tp, 0x19, 0x58da); ++ mdio_write(tp, 0x15, 0x002e); ++ mdio_write(tp, 0x19, 0x400d); ++ mdio_write(tp, 0x15, 0x002f); ++ mdio_write(tp, 0x19, 0x4488); ++ mdio_write(tp, 0x15, 0x0030); ++ mdio_write(tp, 0x19, 0x9e00); ++ mdio_write(tp, 0x15, 0x0031); ++ mdio_write(tp, 0x19, 0x63c8); ++ mdio_write(tp, 0x15, 0x0032); ++ mdio_write(tp, 0x19, 0x6481); ++ mdio_write(tp, 0x15, 0x0033); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0034); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0035); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0036); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0037); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0038); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0039); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x003a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x003b); ++ mdio_write(tp, 0x19, 0x63e8); ++ mdio_write(tp, 0x15, 0x003c); ++ mdio_write(tp, 0x19, 0x7d00); ++ mdio_write(tp, 0x15, 0x003d); ++ mdio_write(tp, 0x19, 0x59d4); ++ mdio_write(tp, 0x15, 0x003e); ++ mdio_write(tp, 0x19, 0x63f8); ++ mdio_write(tp, 0x15, 0x0040); ++ mdio_write(tp, 0x19, 0x64a1); ++ mdio_write(tp, 0x15, 0x0041); ++ mdio_write(tp, 0x19, 0x30de); ++ mdio_write(tp, 0x15, 0x0044); ++ mdio_write(tp, 0x19, 0x480f); ++ mdio_write(tp, 0x15, 0x0045); ++ mdio_write(tp, 0x19, 0x6800); ++ mdio_write(tp, 0x15, 0x0046); ++ mdio_write(tp, 0x19, 0x6680); ++ mdio_write(tp, 0x15, 0x0047); ++ mdio_write(tp, 0x19, 0x7c10); ++ mdio_write(tp, 0x15, 0x0048); ++ mdio_write(tp, 0x19, 0x63c8); ++ mdio_write(tp, 0x15, 0x0049); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004b); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004c); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004d); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004e); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004f); ++ mdio_write(tp, 0x19, 0x40ea); ++ mdio_write(tp, 0x15, 0x0050); ++ mdio_write(tp, 0x19, 0x4503); ++ mdio_write(tp, 0x15, 0x0051); ++ mdio_write(tp, 0x19, 0x58ca); ++ mdio_write(tp, 0x15, 0x0052); ++ mdio_write(tp, 0x19, 0x63c8); ++ mdio_write(tp, 0x15, 0x0053); ++ mdio_write(tp, 0x19, 0x63d8); ++ mdio_write(tp, 0x15, 0x0054); ++ mdio_write(tp, 0x19, 0x66a0); ++ mdio_write(tp, 0x15, 0x0055); ++ mdio_write(tp, 0x19, 0x9f00); ++ mdio_write(tp, 0x15, 0x0056); ++ mdio_write(tp, 0x19, 0x3000); ++ mdio_write(tp, 0x15, 0x00a1); ++ mdio_write(tp, 0x19, 0x3044); ++ mdio_write(tp, 0x15, 0x00ab); ++ mdio_write(tp, 0x19, 0x5820); ++ mdio_write(tp, 0x15, 0x00ac); ++ mdio_write(tp, 0x19, 0x5e04); ++ mdio_write(tp, 0x15, 0x00ad); ++ mdio_write(tp, 0x19, 0xb60c); ++ mdio_write(tp, 0x15, 0x00af); ++ mdio_write(tp, 0x19, 0x000a); ++ mdio_write(tp, 0x15, 0x00b2); ++ mdio_write(tp, 0x19, 0x30b9); ++ mdio_write(tp, 0x15, 0x00b9); ++ mdio_write(tp, 0x19, 0x4408); ++ mdio_write(tp, 0x15, 0x00ba); ++ mdio_write(tp, 0x19, 0x480b); ++ mdio_write(tp, 0x15, 0x00bb); ++ mdio_write(tp, 0x19, 0x5e00); ++ mdio_write(tp, 0x15, 0x00bc); ++ mdio_write(tp, 0x19, 0x405f); ++ mdio_write(tp, 0x15, 0x00bd); ++ mdio_write(tp, 0x19, 0x4448); ++ mdio_write(tp, 0x15, 0x00be); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x00bf); ++ mdio_write(tp, 0x19, 0x4468); ++ mdio_write(tp, 0x15, 0x00c0); ++ mdio_write(tp, 0x19, 0x9c02); ++ mdio_write(tp, 0x15, 0x00c1); ++ mdio_write(tp, 0x19, 0x58a0); ++ mdio_write(tp, 0x15, 0x00c2); ++ mdio_write(tp, 0x19, 0xb605); ++ mdio_write(tp, 0x15, 0x00c3); ++ mdio_write(tp, 0x19, 0xc0d3); ++ mdio_write(tp, 0x15, 0x00c4); ++ mdio_write(tp, 0x19, 0x00e6); ++ mdio_write(tp, 0x15, 0x00c5); ++ mdio_write(tp, 0x19, 0xdaec); ++ mdio_write(tp, 0x15, 0x00c6); ++ mdio_write(tp, 0x19, 0x00fa); ++ mdio_write(tp, 0x15, 0x00c7); ++ mdio_write(tp, 0x19, 0x9df9); ++ mdio_write(tp, 0x15, 0x0112); ++ mdio_write(tp, 0x19, 0x6421); ++ mdio_write(tp, 0x15, 0x0113); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x0114); ++ mdio_write(tp, 0x19, 0x63f0); ++ mdio_write(tp, 0x15, 0x0115); ++ mdio_write(tp, 0x19, 0x4003); ++ mdio_write(tp, 0x15, 0x0116); ++ mdio_write(tp, 0x19, 0x4418); ++ mdio_write(tp, 0x15, 0x0117); ++ mdio_write(tp, 0x19, 0x9b00); ++ mdio_write(tp, 0x15, 0x0118); ++ mdio_write(tp, 0x19, 0x6461); ++ mdio_write(tp, 0x15, 0x0119); ++ mdio_write(tp, 0x19, 0x64e1); ++ mdio_write(tp, 0x15, 0x011a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0150); ++ mdio_write(tp, 0x19, 0x7c80); ++ mdio_write(tp, 0x15, 0x0151); ++ mdio_write(tp, 0x19, 0x6461); ++ mdio_write(tp, 0x15, 0x0152); ++ mdio_write(tp, 0x19, 0x4003); ++ mdio_write(tp, 0x15, 0x0153); ++ mdio_write(tp, 0x19, 0x4540); ++ mdio_write(tp, 0x15, 0x0154); ++ mdio_write(tp, 0x19, 0x9f00); ++ mdio_write(tp, 0x15, 0x0155); ++ mdio_write(tp, 0x19, 0x9d00); ++ mdio_write(tp, 0x15, 0x0156); ++ mdio_write(tp, 0x19, 0x7c40); ++ mdio_write(tp, 0x15, 0x0157); ++ mdio_write(tp, 0x19, 0x6421); ++ mdio_write(tp, 0x15, 0x0158); ++ mdio_write(tp, 0x19, 0x7c80); ++ mdio_write(tp, 0x15, 0x0159); ++ mdio_write(tp, 0x19, 0x64a1); ++ mdio_write(tp, 0x15, 0x015a); ++ mdio_write(tp, 0x19, 0x30fe); ++ mdio_write(tp, 0x15, 0x02e7); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0329); ++ mdio_write(tp, 0x19, 0x7c00); ++ mdio_write(tp, 0x15, 0x0382); ++ mdio_write(tp, 0x19, 0x7c40); ++ mdio_write(tp, 0x15, 0x03bd); ++ mdio_write(tp, 0x19, 0x405e); ++ mdio_write(tp, 0x15, 0x03c9); ++ mdio_write(tp, 0x19, 0x7c00); ++ mdio_write(tp, 0x15, 0x03e3); ++ mdio_write(tp, 0x19, 0x7c00); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0300); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x05, 0x8000); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0x48f7); ++ mdio_write(tp, 0x06, 0x00e0); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0xa080); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0xf602); ++ mdio_write(tp, 0x06, 0x0200); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0x8c02); ++ mdio_write(tp, 0x06, 0x0224); ++ mdio_write(tp, 0x06, 0x0202); ++ mdio_write(tp, 0x06, 0x3402); ++ mdio_write(tp, 0x06, 0x027f); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0xa202); ++ mdio_write(tp, 0x06, 0x80bb); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x88e1); ++ mdio_write(tp, 0x06, 0x8b89); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8a1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8b); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8c1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8e1e); ++ mdio_write(tp, 0x06, 0x01a0); ++ mdio_write(tp, 0x06, 0x00c7); ++ mdio_write(tp, 0x06, 0xaebb); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0xe600); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0xee03); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0xefb8); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0xe902); ++ mdio_write(tp, 0x06, 0xee8b); ++ mdio_write(tp, 0x06, 0x8520); ++ mdio_write(tp, 0x06, 0xee8b); ++ mdio_write(tp, 0x06, 0x8701); ++ mdio_write(tp, 0x06, 0xd481); ++ mdio_write(tp, 0x06, 0x31e4); ++ mdio_write(tp, 0x06, 0x8b94); ++ mdio_write(tp, 0x06, 0xe58b); ++ mdio_write(tp, 0x06, 0x95bf); ++ mdio_write(tp, 0x06, 0x8b88); ++ mdio_write(tp, 0x06, 0xec00); ++ mdio_write(tp, 0x06, 0x19a9); ++ mdio_write(tp, 0x06, 0x8b90); ++ mdio_write(tp, 0x06, 0xf9ee); ++ mdio_write(tp, 0x06, 0xfff6); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0xffe0); ++ mdio_write(tp, 0x06, 0xe140); ++ mdio_write(tp, 0x06, 0xe1e1); ++ mdio_write(tp, 0x06, 0x41f7); ++ mdio_write(tp, 0x06, 0x2ff6); ++ mdio_write(tp, 0x06, 0x28e4); ++ mdio_write(tp, 0x06, 0xe140); ++ mdio_write(tp, 0x06, 0xe5e1); ++ mdio_write(tp, 0x06, 0x4104); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b89); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x0dee); ++ mdio_write(tp, 0x06, 0x8b89); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x82ed); ++ mdio_write(tp, 0x06, 0x021f); ++ mdio_write(tp, 0x06, 0x4102); ++ mdio_write(tp, 0x06, 0x2812); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x10ee); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x139d); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0xcf02); ++ mdio_write(tp, 0x06, 0x1f99); ++ mdio_write(tp, 0x06, 0x0227); ++ mdio_write(tp, 0x06, 0xeafc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2014); ++ mdio_write(tp, 0x06, 0xf620); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x8100); ++ mdio_write(tp, 0x06, 0x021b); ++ mdio_write(tp, 0x06, 0xf402); ++ mdio_write(tp, 0x06, 0x2c9c); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0x7202); ++ mdio_write(tp, 0x06, 0x843c); ++ mdio_write(tp, 0x06, 0xad22); ++ mdio_write(tp, 0x06, 0x11f6); ++ mdio_write(tp, 0x06, 0x22e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x022c); ++ mdio_write(tp, 0x06, 0x4602); ++ mdio_write(tp, 0x06, 0x2ac5); ++ mdio_write(tp, 0x06, 0x0229); ++ mdio_write(tp, 0x06, 0x2002); ++ mdio_write(tp, 0x06, 0x2b91); ++ mdio_write(tp, 0x06, 0xad25); ++ mdio_write(tp, 0x06, 0x11f6); ++ mdio_write(tp, 0x06, 0x25e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x0203); ++ mdio_write(tp, 0x06, 0x5a02); ++ mdio_write(tp, 0x06, 0x043a); ++ mdio_write(tp, 0x06, 0x021a); ++ mdio_write(tp, 0x06, 0x5902); ++ mdio_write(tp, 0x06, 0x2bfc); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x00e1); ++ mdio_write(tp, 0x06, 0xe001); ++ mdio_write(tp, 0x06, 0xad27); ++ mdio_write(tp, 0x06, 0x1fd1); ++ mdio_write(tp, 0x06, 0x01bf); ++ mdio_write(tp, 0x06, 0x84eb); ++ mdio_write(tp, 0x06, 0x022f); ++ mdio_write(tp, 0x06, 0x50e0); ++ mdio_write(tp, 0x06, 0xe020); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x21ad); ++ mdio_write(tp, 0x06, 0x200e); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf84); ++ mdio_write(tp, 0x06, 0xeb02); ++ mdio_write(tp, 0x06, 0x2f50); ++ mdio_write(tp, 0x06, 0xbf3d); ++ mdio_write(tp, 0x06, 0x3902); ++ mdio_write(tp, 0x06, 0x2eb0); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfefc); ++ mdio_write(tp, 0x06, 0x0402); ++ mdio_write(tp, 0x06, 0x8135); ++ mdio_write(tp, 0x06, 0x05f8); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69e0); ++ mdio_write(tp, 0x06, 0xe2fe); ++ mdio_write(tp, 0x06, 0xe1e2); ++ mdio_write(tp, 0x06, 0xffad); ++ mdio_write(tp, 0x06, 0x2d1a); ++ mdio_write(tp, 0x06, 0xe0e1); ++ mdio_write(tp, 0x06, 0x4ee1); ++ mdio_write(tp, 0x06, 0xe14f); ++ mdio_write(tp, 0x06, 0xac2d); ++ mdio_write(tp, 0x06, 0x22f6); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x0336); ++ mdio_write(tp, 0x06, 0xf703); ++ mdio_write(tp, 0x06, 0xf706); ++ mdio_write(tp, 0x06, 0xbf84); ++ mdio_write(tp, 0x06, 0xd502); ++ mdio_write(tp, 0x06, 0x2eb0); ++ mdio_write(tp, 0x06, 0xae11); ++ mdio_write(tp, 0x06, 0xe0e1); ++ mdio_write(tp, 0x06, 0x4ee1); ++ mdio_write(tp, 0x06, 0xe14f); ++ mdio_write(tp, 0x06, 0xad2d); ++ mdio_write(tp, 0x06, 0x08bf); ++ mdio_write(tp, 0x06, 0x84e0); ++ mdio_write(tp, 0x06, 0x022e); ++ mdio_write(tp, 0x06, 0xb0f6); ++ mdio_write(tp, 0x06, 0x06ef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69e0); ++ mdio_write(tp, 0x06, 0x8b87); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x4cd2); ++ mdio_write(tp, 0x06, 0x00e0); ++ mdio_write(tp, 0x06, 0xe200); ++ mdio_write(tp, 0x06, 0x5801); ++ mdio_write(tp, 0x06, 0x0c02); ++ mdio_write(tp, 0x06, 0x1e20); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x0058); ++ mdio_write(tp, 0x06, 0x101e); ++ mdio_write(tp, 0x06, 0x20e0); ++ mdio_write(tp, 0x06, 0xe036); ++ mdio_write(tp, 0x06, 0x5803); ++ mdio_write(tp, 0x06, 0x1e20); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x22e1); ++ mdio_write(tp, 0x06, 0xe023); ++ mdio_write(tp, 0x06, 0x58e0); ++ mdio_write(tp, 0x06, 0x1e20); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xe61f); ++ mdio_write(tp, 0x06, 0x029e); ++ mdio_write(tp, 0x06, 0x22e6); ++ mdio_write(tp, 0x06, 0x8ae6); ++ mdio_write(tp, 0x06, 0xad32); ++ mdio_write(tp, 0x06, 0x14ad); ++ mdio_write(tp, 0x06, 0x3411); ++ mdio_write(tp, 0x06, 0xef02); ++ mdio_write(tp, 0x06, 0x5803); ++ mdio_write(tp, 0x06, 0x9e07); ++ mdio_write(tp, 0x06, 0xad35); ++ mdio_write(tp, 0x06, 0x085a); ++ mdio_write(tp, 0x06, 0xc09f); ++ mdio_write(tp, 0x06, 0x04d1); ++ mdio_write(tp, 0x06, 0x01ae); ++ mdio_write(tp, 0x06, 0x02d1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x84f1); ++ mdio_write(tp, 0x06, 0x022f); ++ mdio_write(tp, 0x06, 0x50ef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfdfc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xf9fa); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ac); ++ mdio_write(tp, 0x06, 0x260e); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ac); ++ mdio_write(tp, 0x06, 0x2108); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x87ac); ++ mdio_write(tp, 0x06, 0x2402); ++ mdio_write(tp, 0x06, 0xae6b); ++ mdio_write(tp, 0x06, 0xeee0); ++ mdio_write(tp, 0x06, 0xea00); ++ mdio_write(tp, 0x06, 0xeee0); ++ mdio_write(tp, 0x06, 0xeb00); ++ mdio_write(tp, 0x06, 0xe2e0); ++ mdio_write(tp, 0x06, 0x7ce3); ++ mdio_write(tp, 0x06, 0xe07d); ++ mdio_write(tp, 0x06, 0xa511); ++ mdio_write(tp, 0x06, 0x1115); ++ mdio_write(tp, 0x06, 0xd260); ++ mdio_write(tp, 0x06, 0xd666); ++ mdio_write(tp, 0x06, 0x6602); ++ mdio_write(tp, 0x06, 0x07f9); ++ mdio_write(tp, 0x06, 0xd2a0); ++ mdio_write(tp, 0x06, 0xd6aa); ++ mdio_write(tp, 0x06, 0xaa02); ++ mdio_write(tp, 0x06, 0x07f9); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0x55ae); ++ mdio_write(tp, 0x06, 0x44a5); ++ mdio_write(tp, 0x06, 0x6666); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x38a5); ++ mdio_write(tp, 0x06, 0xaaaa); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x32ee); ++ mdio_write(tp, 0x06, 0xe0ea); ++ mdio_write(tp, 0x06, 0x04ee); ++ mdio_write(tp, 0x06, 0xe0eb); ++ mdio_write(tp, 0x06, 0x06e2); ++ mdio_write(tp, 0x06, 0xe07c); ++ mdio_write(tp, 0x06, 0xe3e0); ++ mdio_write(tp, 0x06, 0x7de0); ++ mdio_write(tp, 0x06, 0xe038); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x39ad); ++ mdio_write(tp, 0x06, 0x2e21); ++ mdio_write(tp, 0x06, 0xad3f); ++ mdio_write(tp, 0x06, 0x13e0); ++ mdio_write(tp, 0x06, 0xe414); ++ mdio_write(tp, 0x06, 0xe1e4); ++ mdio_write(tp, 0x06, 0x1568); ++ mdio_write(tp, 0x06, 0x80e4); ++ mdio_write(tp, 0x06, 0xe414); ++ mdio_write(tp, 0x06, 0xe5e4); ++ mdio_write(tp, 0x06, 0x1502); ++ mdio_write(tp, 0x06, 0x8255); ++ mdio_write(tp, 0x06, 0xae0b); ++ mdio_write(tp, 0x06, 0xac3e); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x0602); ++ mdio_write(tp, 0x06, 0x827f); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0xa9fe); ++ mdio_write(tp, 0x06, 0xfdfc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x2ee0); ++ mdio_write(tp, 0x06, 0x8b81); ++ mdio_write(tp, 0x06, 0xad26); ++ mdio_write(tp, 0x06, 0x0502); ++ mdio_write(tp, 0x06, 0x21f3); ++ mdio_write(tp, 0x06, 0xf728); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x2105); ++ mdio_write(tp, 0x06, 0x0222); ++ mdio_write(tp, 0x06, 0xf8f7); ++ mdio_write(tp, 0x06, 0x29e0); ++ mdio_write(tp, 0x06, 0x8b87); ++ mdio_write(tp, 0x06, 0xad24); ++ mdio_write(tp, 0x06, 0x0502); ++ mdio_write(tp, 0x06, 0x82e4); ++ mdio_write(tp, 0x06, 0xf72a); ++ mdio_write(tp, 0x06, 0xe58b); ++ mdio_write(tp, 0x06, 0x2efc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x2603); ++ mdio_write(tp, 0x06, 0x0221); ++ mdio_write(tp, 0x06, 0x34e0); ++ mdio_write(tp, 0x06, 0x8b81); ++ mdio_write(tp, 0x06, 0xad21); ++ mdio_write(tp, 0x06, 0x09e0); ++ mdio_write(tp, 0x06, 0x8b2e); ++ mdio_write(tp, 0x06, 0xac20); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x834b); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x87ad); ++ mdio_write(tp, 0x06, 0x2409); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x2eac); ++ mdio_write(tp, 0x06, 0x2103); ++ mdio_write(tp, 0x06, 0x0283); ++ mdio_write(tp, 0x06, 0x30fc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x2ee0); ++ mdio_write(tp, 0x06, 0x8b81); ++ mdio_write(tp, 0x06, 0xad26); ++ mdio_write(tp, 0x06, 0x08e0); ++ mdio_write(tp, 0x06, 0x85d2); ++ mdio_write(tp, 0x06, 0xad25); ++ mdio_write(tp, 0x06, 0x02f6); ++ mdio_write(tp, 0x06, 0x28e0); ++ mdio_write(tp, 0x06, 0x8b81); ++ mdio_write(tp, 0x06, 0xad21); ++ mdio_write(tp, 0x06, 0x0ae0); ++ mdio_write(tp, 0x06, 0x860a); ++ mdio_write(tp, 0x06, 0xf627); ++ mdio_write(tp, 0x06, 0xa005); ++ mdio_write(tp, 0x06, 0x02f6); ++ mdio_write(tp, 0x06, 0x29e0); ++ mdio_write(tp, 0x06, 0x8b87); ++ mdio_write(tp, 0x06, 0xad24); ++ mdio_write(tp, 0x06, 0x08e0); ++ mdio_write(tp, 0x06, 0x8aed); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x02f6); ++ mdio_write(tp, 0x06, 0x2ae5); ++ mdio_write(tp, 0x06, 0x8b2e); ++ mdio_write(tp, 0x06, 0xa100); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x2111); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0xed00); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0xec00); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x87ad); ++ mdio_write(tp, 0x06, 0x243a); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0xeae1); ++ mdio_write(tp, 0x06, 0xe0eb); ++ mdio_write(tp, 0x06, 0x58f8); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xe4e0); ++ mdio_write(tp, 0x06, 0xeae5); ++ mdio_write(tp, 0x06, 0xe0eb); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x7ce1); ++ mdio_write(tp, 0x06, 0xe07d); ++ mdio_write(tp, 0x06, 0x5c00); ++ mdio_write(tp, 0x06, 0xff3c); ++ mdio_write(tp, 0x06, 0x001e); ++ mdio_write(tp, 0x06, 0xab1c); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x4ce1); ++ mdio_write(tp, 0x06, 0xe04d); ++ mdio_write(tp, 0x06, 0x58c1); ++ mdio_write(tp, 0x06, 0xe4e0); ++ mdio_write(tp, 0x06, 0x4ce5); ++ mdio_write(tp, 0x06, 0xe04d); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0xeee1); ++ mdio_write(tp, 0x06, 0xe0ef); ++ mdio_write(tp, 0x06, 0x693c); ++ mdio_write(tp, 0x06, 0xe4e0); ++ mdio_write(tp, 0x06, 0xeee5); ++ mdio_write(tp, 0x06, 0xe0ef); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b87); ++ mdio_write(tp, 0x06, 0xad24); ++ mdio_write(tp, 0x06, 0x12e0); ++ mdio_write(tp, 0x06, 0xe0ee); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0xef59); ++ mdio_write(tp, 0x06, 0xc3e4); ++ mdio_write(tp, 0x06, 0xe0ee); ++ mdio_write(tp, 0x06, 0xe5e0); ++ mdio_write(tp, 0x06, 0xefee); ++ mdio_write(tp, 0x06, 0x8aed); ++ mdio_write(tp, 0x06, 0x01fc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ac); ++ mdio_write(tp, 0x06, 0x2505); ++ mdio_write(tp, 0x06, 0x0283); ++ mdio_write(tp, 0x06, 0x5cae); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x2516); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69fa); ++ mdio_write(tp, 0x06, 0xe086); ++ mdio_write(tp, 0x06, 0x0aa0); ++ mdio_write(tp, 0x06, 0x0019); ++ mdio_write(tp, 0x06, 0xe086); ++ mdio_write(tp, 0x06, 0x0be1); ++ mdio_write(tp, 0x06, 0x8b33); ++ mdio_write(tp, 0x06, 0x1b10); ++ mdio_write(tp, 0x06, 0x9e04); ++ mdio_write(tp, 0x06, 0xaa02); ++ mdio_write(tp, 0x06, 0xae06); ++ mdio_write(tp, 0x06, 0xee86); ++ mdio_write(tp, 0x06, 0x0a01); ++ mdio_write(tp, 0x06, 0xaee6); ++ mdio_write(tp, 0x06, 0x0224); ++ mdio_write(tp, 0x06, 0x1eae); ++ mdio_write(tp, 0x06, 0x14a0); ++ mdio_write(tp, 0x06, 0x0114); ++ mdio_write(tp, 0x06, 0x0224); ++ mdio_write(tp, 0x06, 0x26bf); ++ mdio_write(tp, 0x06, 0x266d); ++ mdio_write(tp, 0x06, 0x022e); ++ mdio_write(tp, 0x06, 0xb0ee); ++ mdio_write(tp, 0x06, 0x860b); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x860a); ++ mdio_write(tp, 0x06, 0x02af); ++ mdio_write(tp, 0x06, 0x8435); ++ mdio_write(tp, 0x06, 0xa002); ++ mdio_write(tp, 0x06, 0x52ee); ++ mdio_write(tp, 0x06, 0x8604); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8605); ++ mdio_write(tp, 0x06, 0x00e0); ++ mdio_write(tp, 0x06, 0x860b); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x321b); ++ mdio_write(tp, 0x06, 0x109e); ++ mdio_write(tp, 0x06, 0x04aa); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0xcbee); ++ mdio_write(tp, 0x06, 0x860b); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x243a); ++ mdio_write(tp, 0x06, 0xe286); ++ mdio_write(tp, 0x06, 0x04e3); ++ mdio_write(tp, 0x06, 0x8605); ++ mdio_write(tp, 0x06, 0xef65); ++ mdio_write(tp, 0x06, 0xe286); ++ mdio_write(tp, 0x06, 0x06e3); ++ mdio_write(tp, 0x06, 0x8607); ++ mdio_write(tp, 0x06, 0x1b56); ++ mdio_write(tp, 0x06, 0xaa0e); ++ mdio_write(tp, 0x06, 0xef56); ++ mdio_write(tp, 0x06, 0xe686); ++ mdio_write(tp, 0x06, 0x06e7); ++ mdio_write(tp, 0x06, 0x8607); ++ mdio_write(tp, 0x06, 0xe286); ++ mdio_write(tp, 0x06, 0x09e6); ++ mdio_write(tp, 0x06, 0x8608); ++ mdio_write(tp, 0x06, 0xe086); ++ mdio_write(tp, 0x06, 0x09a0); ++ mdio_write(tp, 0x06, 0x0007); ++ mdio_write(tp, 0x06, 0xee86); ++ mdio_write(tp, 0x06, 0x0a03); ++ mdio_write(tp, 0x06, 0xaf83); ++ mdio_write(tp, 0x06, 0x6202); ++ mdio_write(tp, 0x06, 0x248e); ++ mdio_write(tp, 0x06, 0x0224); ++ mdio_write(tp, 0x06, 0x26ae); ++ mdio_write(tp, 0x06, 0x48a0); ++ mdio_write(tp, 0x06, 0x0321); ++ mdio_write(tp, 0x06, 0xe086); ++ mdio_write(tp, 0x06, 0x08e1); ++ mdio_write(tp, 0x06, 0x8609); ++ mdio_write(tp, 0x06, 0x1b01); ++ mdio_write(tp, 0x06, 0x9e0c); ++ mdio_write(tp, 0x06, 0xaa05); ++ mdio_write(tp, 0x06, 0x0224); ++ mdio_write(tp, 0x06, 0x9dae); ++ mdio_write(tp, 0x06, 0xe702); ++ mdio_write(tp, 0x06, 0x248e); ++ mdio_write(tp, 0x06, 0xaee2); ++ mdio_write(tp, 0x06, 0xee86); ++ mdio_write(tp, 0x06, 0x0a04); ++ mdio_write(tp, 0x06, 0xee86); ++ mdio_write(tp, 0x06, 0x0b00); ++ mdio_write(tp, 0x06, 0xaf83); ++ mdio_write(tp, 0x06, 0x62a0); ++ mdio_write(tp, 0x06, 0x0415); ++ mdio_write(tp, 0x06, 0xe086); ++ mdio_write(tp, 0x06, 0x0be1); ++ mdio_write(tp, 0x06, 0x8b34); ++ mdio_write(tp, 0x06, 0x1b10); ++ mdio_write(tp, 0x06, 0x9e05); ++ mdio_write(tp, 0x06, 0xaa03); ++ mdio_write(tp, 0x06, 0xaf83); ++ mdio_write(tp, 0x06, 0x7cee); ++ mdio_write(tp, 0x06, 0x860a); ++ mdio_write(tp, 0x06, 0x05ae); ++ mdio_write(tp, 0x06, 0x0ca0); ++ mdio_write(tp, 0x06, 0x0502); ++ mdio_write(tp, 0x06, 0xae07); ++ mdio_write(tp, 0x06, 0x0223); ++ mdio_write(tp, 0x06, 0x09ee); ++ mdio_write(tp, 0x06, 0x860a); ++ mdio_write(tp, 0x06, 0x00fe); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfefd); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xfbe0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xad25); ++ mdio_write(tp, 0x06, 0x22e0); ++ mdio_write(tp, 0x06, 0xe022); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x23e2); ++ mdio_write(tp, 0x06, 0xe036); ++ mdio_write(tp, 0x06, 0xe3e0); ++ mdio_write(tp, 0x06, 0x375a); ++ mdio_write(tp, 0x06, 0xc40d); ++ mdio_write(tp, 0x06, 0x0158); ++ mdio_write(tp, 0x06, 0x021e); ++ mdio_write(tp, 0x06, 0x20e3); ++ mdio_write(tp, 0x06, 0x8ae7); ++ mdio_write(tp, 0x06, 0xac31); ++ mdio_write(tp, 0x06, 0x60ac); ++ mdio_write(tp, 0x06, 0x3a08); ++ mdio_write(tp, 0x06, 0xac3e); ++ mdio_write(tp, 0x06, 0x26ae); ++ mdio_write(tp, 0x06, 0x67af); ++ mdio_write(tp, 0x06, 0x84d1); ++ mdio_write(tp, 0x06, 0xad37); ++ mdio_write(tp, 0x06, 0x61e0); ++ mdio_write(tp, 0x06, 0x8ae8); ++ mdio_write(tp, 0x06, 0x10e4); ++ mdio_write(tp, 0x06, 0x8ae8); ++ mdio_write(tp, 0x06, 0xe18a); ++ mdio_write(tp, 0x06, 0xe91b); ++ mdio_write(tp, 0x06, 0x109e); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x51d1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x84ee); ++ mdio_write(tp, 0x06, 0x022f); ++ mdio_write(tp, 0x06, 0x50ee); ++ mdio_write(tp, 0x06, 0x8ae8); ++ mdio_write(tp, 0x06, 0x00ae); ++ mdio_write(tp, 0x06, 0x43ad); ++ mdio_write(tp, 0x06, 0x3627); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xeee1); ++ mdio_write(tp, 0x06, 0x8aef); ++ mdio_write(tp, 0x06, 0xef74); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xeae1); ++ mdio_write(tp, 0x06, 0x8aeb); ++ mdio_write(tp, 0x06, 0x1b74); ++ mdio_write(tp, 0x06, 0x9e2e); ++ mdio_write(tp, 0x06, 0x14e4); ++ mdio_write(tp, 0x06, 0x8aea); ++ mdio_write(tp, 0x06, 0xe58a); ++ mdio_write(tp, 0x06, 0xebef); ++ mdio_write(tp, 0x06, 0x74e0); ++ mdio_write(tp, 0x06, 0x8aee); ++ mdio_write(tp, 0x06, 0xe18a); ++ mdio_write(tp, 0x06, 0xef1b); ++ mdio_write(tp, 0x06, 0x479e); ++ mdio_write(tp, 0x06, 0x0fae); ++ mdio_write(tp, 0x06, 0x19ee); ++ mdio_write(tp, 0x06, 0x8aea); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8aeb); ++ mdio_write(tp, 0x06, 0x00ae); ++ mdio_write(tp, 0x06, 0x0fac); ++ mdio_write(tp, 0x06, 0x390c); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xbf84); ++ mdio_write(tp, 0x06, 0xee02); ++ mdio_write(tp, 0x06, 0x2f50); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0xe800); ++ mdio_write(tp, 0x06, 0xe68a); ++ mdio_write(tp, 0x06, 0xe7ff); ++ mdio_write(tp, 0x06, 0xfdfc); ++ mdio_write(tp, 0x06, 0x04a7); ++ mdio_write(tp, 0x06, 0x25e5); ++ mdio_write(tp, 0x06, 0x0a1d); ++ mdio_write(tp, 0x06, 0xe50a); ++ mdio_write(tp, 0x06, 0x2ce5); ++ mdio_write(tp, 0x06, 0x0a6d); ++ mdio_write(tp, 0x06, 0xe50a); ++ mdio_write(tp, 0x06, 0x1de5); ++ mdio_write(tp, 0x06, 0x0a1c); ++ mdio_write(tp, 0x06, 0xe50a); ++ mdio_write(tp, 0x06, 0x2da7); ++ mdio_write(tp, 0x06, 0x5500); ++ mdio_write(tp, 0x06, 0xe234); ++ mdio_write(tp, 0x06, 0x88e2); ++ mdio_write(tp, 0x06, 0x00cc); ++ mdio_write(tp, 0x06, 0xe200); ++ gphy_val = mdio_read(tp, 0x01); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x01, gphy_val); ++ gphy_val = mdio_read(tp, 0x00); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x00, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x17, 0x2179); ++ mdio_write(tp, 0x1f, 0x0001); ++ mdio_write(tp, 0x10, 0xf274); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0042); ++ mdio_write(tp, 0x15, 0x0f00); ++ mdio_write(tp, 0x15, 0x0f00); ++ mdio_write(tp, 0x16, 0x7408); ++ mdio_write(tp, 0x15, 0x0e00); ++ mdio_write(tp, 0x15, 0x0f00); ++ mdio_write(tp, 0x15, 0x0f01); ++ mdio_write(tp, 0x16, 0x4000); ++ mdio_write(tp, 0x15, 0x0e01); ++ mdio_write(tp, 0x15, 0x0f01); ++ mdio_write(tp, 0x15, 0x0f02); ++ mdio_write(tp, 0x16, 0x9400); ++ mdio_write(tp, 0x15, 0x0e02); ++ mdio_write(tp, 0x15, 0x0f02); ++ mdio_write(tp, 0x15, 0x0f03); ++ mdio_write(tp, 0x16, 0x7408); ++ mdio_write(tp, 0x15, 0x0e03); ++ mdio_write(tp, 0x15, 0x0f03); ++ mdio_write(tp, 0x15, 0x0f04); ++ mdio_write(tp, 0x16, 0x4008); ++ mdio_write(tp, 0x15, 0x0e04); ++ mdio_write(tp, 0x15, 0x0f04); ++ mdio_write(tp, 0x15, 0x0f05); ++ mdio_write(tp, 0x16, 0x9400); ++ mdio_write(tp, 0x15, 0x0e05); ++ mdio_write(tp, 0x15, 0x0f05); ++ mdio_write(tp, 0x15, 0x0f06); ++ mdio_write(tp, 0x16, 0x0803); ++ mdio_write(tp, 0x15, 0x0e06); ++ mdio_write(tp, 0x15, 0x0f06); ++ mdio_write(tp, 0x15, 0x0d00); ++ mdio_write(tp, 0x15, 0x0100); ++ mdio_write(tp, 0x1f, 0x0001); ++ mdio_write(tp, 0x10, 0xf074); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x17, 0x2149); ++ mdio_write(tp, 0x1f, 0x0005); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x00); ++ if (gphy_val & BIT_7) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ gphy_val = mdio_read(tp, 0x17); ++ gphy_val &= ~(BIT_0); ++ if ((pdev->subsystem_vendor == 0x144d && ++ pdev->subsystem_device == 0xc098) || ++ (pdev->subsystem_vendor == 0x144d && ++ pdev->subsystem_device == 0xc0b1)) { ++ gphy_val &= ~(BIT_2); ++ } ++ mdio_write(tp, 0x17, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ gphy_val = mdio_read(tp, 0x17); ++ gphy_val |= BIT_14; ++ mdio_write(tp, 0x17, gphy_val); ++ mdio_write(tp, 0x1e, 0x0020); ++ gphy_val = mdio_read(tp, 0x1b); ++ gphy_val |= BIT_7; ++ mdio_write(tp, 0x1b, gphy_val); ++ mdio_write(tp, 0x1e, 0x0041); ++ mdio_write(tp, 0x15, 0x0e02); ++ mdio_write(tp, 0x1e, 0x0028); ++ gphy_val = mdio_read(tp, 0x19); ++ gphy_val |= BIT_15; ++ mdio_write(tp, 0x19, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ if (pdev->subsystem_vendor == 0x104d && ++ pdev->subsystem_device == 0x907b) { ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B86); ++ gphy_val = mdio_read(tp, 0x06) | BIT_4; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ } ++ } ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x0023); ++ gphy_val = mdio_read(tp, 0x17)|0x06; ++ mdio_write(tp, 0x17, gphy_val); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0x8b80); ++ mdio_write(tp, 0x06, 0xc896); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x0B, 0x6C20); ++ mdio_write(tp, 0x07, 0x2872); ++ mdio_write(tp, 0x1C, 0xEFFF); ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x14, 0x6420); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ gphy_val = mdio_read(tp, 0x08) & 0x00FF; ++ mdio_write(tp, 0x08, gphy_val | 0x8000); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x002D); ++ gphy_val = mdio_read(tp, 0x18); ++ mdio_write(tp, 0x18, gphy_val | 0x0050); ++ mdio_write(tp, 0x1F, 0x0000); ++ gphy_val = mdio_read(tp, 0x14); ++ mdio_write(tp, 0x14, gphy_val | 0x8000); ++ ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x00, 0x080B); ++ mdio_write(tp, 0x0B, 0x09D7); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x15, 0x1006); ++ ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x002F); ++ mdio_write(tp, 0x15, 0x1919); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B86); ++ gphy_val = mdio_read(tp, 0x06); ++ mdio_write(tp, 0x06, gphy_val | 0x0001); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x00AC); ++ mdio_write(tp, 0x18, 0x0006); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x19, 0x7F46); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8AD2); ++ mdio_write(tp, 0x06, 0x6810); ++ mdio_write(tp, 0x05, 0x8AD4); ++ mdio_write(tp, 0x06, 0x8002); ++ mdio_write(tp, 0x05, 0x8ADE); ++ mdio_write(tp, 0x06, 0x8025); ++ mdio_write(tp, 0x1F, 0x0000); ++ } else if (tp->mcfg == CFG_METHOD_16) { ++ RTL_W8(0x6E, RTL_R8(0x6E) | BIT_6); ++ rtl8168_eri_write(ioaddr, 0x1AE, 2, 0x0403, ERIAR_ExGMAC); ++ ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x1800); ++ gphy_val = mdio_read(tp, 0x15); ++ gphy_val &= ~(BIT_12); ++ mdio_write(tp, 0x15, gphy_val); ++ mdelay(20); ++ mdio_write(tp, 0x1f, 0x0004); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ gphy_val = mdio_read(tp, 0x17); ++ if ((gphy_val & BIT_11) == 0x0000) ++ { ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x17, gphy_val); ++ for (i=0;i<200;i++) ++ { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x17); ++ if (gphy_val & BIT_11) ++ break; ++ } ++ } ++ gphy_val = mdio_read(tp, 0x17); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x17, gphy_val); ++ mdio_write(tp, 0x1f, 0x0004); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1E, 0x002C); ++ mdio_write(tp, 0x1B, 0x5000); ++ mdio_write(tp, 0x1E, 0x002d); ++ mdio_write(tp, 0x19, 0x0004); ++ mdio_write(tp, 0x1f, 0x0002); ++ mdio_write(tp, 0x1f, 0x0000); ++ for (i=0;i<200;i++) ++ { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x1E); ++ if ((gphy_val & 0x03FF) == 0x0014) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0005); ++ for (i=0;i<200;i++) ++ { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x07); ++ if ((gphy_val & BIT_5) == 0) ++ break; ++ } ++ gphy_val = mdio_read(tp, 0x07); ++ if (gphy_val & BIT_5) ++ { ++ mdio_write(tp, 0x1f, 0x0004); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x00a1); ++ mdio_write(tp, 0x17, 0x1000); ++ mdio_write(tp, 0x17, 0x0000); ++ mdio_write(tp, 0x17, 0x2000); ++ mdio_write(tp, 0x1e, 0x002f); ++ mdio_write(tp, 0x18, 0x9bfb); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x07, 0x0000); ++ mdio_write(tp, 0x1f, 0x0002); ++ mdio_write(tp, 0x1f, 0x0000); ++ } ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ gphy_val = mdio_read(tp, 0x00); ++ gphy_val &= ~(BIT_7); ++ mdio_write(tp, 0x00, gphy_val); ++ mdio_write(tp, 0x1f, 0x0004); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0307); ++ mdio_write(tp, 0x15, 0x0000); ++ mdio_write(tp, 0x19, 0x407d); ++ mdio_write(tp, 0x15, 0x0001); ++ mdio_write(tp, 0x19, 0x440f); ++ mdio_write(tp, 0x15, 0x0002); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0003); ++ mdio_write(tp, 0x19, 0x6c03); ++ mdio_write(tp, 0x15, 0x0004); ++ mdio_write(tp, 0x19, 0xc4d5); ++ mdio_write(tp, 0x15, 0x0005); ++ mdio_write(tp, 0x19, 0x00ff); ++ mdio_write(tp, 0x15, 0x0006); ++ mdio_write(tp, 0x19, 0x74f0); ++ mdio_write(tp, 0x15, 0x0007); ++ mdio_write(tp, 0x19, 0x4880); ++ mdio_write(tp, 0x15, 0x0008); ++ mdio_write(tp, 0x19, 0x4c00); ++ mdio_write(tp, 0x15, 0x0009); ++ mdio_write(tp, 0x19, 0x4800); ++ mdio_write(tp, 0x15, 0x000a); ++ mdio_write(tp, 0x19, 0x5000); ++ mdio_write(tp, 0x15, 0x000b); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x000c); ++ mdio_write(tp, 0x19, 0x7801); ++ mdio_write(tp, 0x15, 0x000d); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x15, 0x000e); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x000f); ++ mdio_write(tp, 0x19, 0x7010); ++ mdio_write(tp, 0x15, 0x0010); ++ mdio_write(tp, 0x19, 0x6804); ++ mdio_write(tp, 0x15, 0x0011); ++ mdio_write(tp, 0x19, 0x64a0); ++ mdio_write(tp, 0x15, 0x0012); ++ mdio_write(tp, 0x19, 0x63da); ++ mdio_write(tp, 0x15, 0x0013); ++ mdio_write(tp, 0x19, 0x63d8); ++ mdio_write(tp, 0x15, 0x0014); ++ mdio_write(tp, 0x19, 0x6f05); ++ mdio_write(tp, 0x15, 0x0015); ++ mdio_write(tp, 0x19, 0x5420); ++ mdio_write(tp, 0x15, 0x0016); ++ mdio_write(tp, 0x19, 0x58ce); ++ mdio_write(tp, 0x15, 0x0017); ++ mdio_write(tp, 0x19, 0x5cf3); ++ mdio_write(tp, 0x15, 0x0018); ++ mdio_write(tp, 0x19, 0xb600); ++ mdio_write(tp, 0x15, 0x0019); ++ mdio_write(tp, 0x19, 0xc659); ++ mdio_write(tp, 0x15, 0x001a); ++ mdio_write(tp, 0x19, 0x0018); ++ mdio_write(tp, 0x15, 0x001b); ++ mdio_write(tp, 0x19, 0xc403); ++ mdio_write(tp, 0x15, 0x001c); ++ mdio_write(tp, 0x19, 0x0016); ++ mdio_write(tp, 0x15, 0x001d); ++ mdio_write(tp, 0x19, 0xaa05); ++ mdio_write(tp, 0x15, 0x001e); ++ mdio_write(tp, 0x19, 0xc503); ++ mdio_write(tp, 0x15, 0x001f); ++ mdio_write(tp, 0x19, 0x0003); ++ mdio_write(tp, 0x15, 0x0020); ++ mdio_write(tp, 0x19, 0x89f8); ++ mdio_write(tp, 0x15, 0x0021); ++ mdio_write(tp, 0x19, 0x32ae); ++ mdio_write(tp, 0x15, 0x0022); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0023); ++ mdio_write(tp, 0x19, 0x6c03); ++ mdio_write(tp, 0x15, 0x0024); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0025); ++ mdio_write(tp, 0x19, 0x6801); ++ mdio_write(tp, 0x15, 0x0026); ++ mdio_write(tp, 0x19, 0x66a0); ++ mdio_write(tp, 0x15, 0x0027); ++ mdio_write(tp, 0x19, 0xa300); ++ mdio_write(tp, 0x15, 0x0028); ++ mdio_write(tp, 0x19, 0x64a0); ++ mdio_write(tp, 0x15, 0x0029); ++ mdio_write(tp, 0x19, 0x76f0); ++ mdio_write(tp, 0x15, 0x002a); ++ mdio_write(tp, 0x19, 0x7670); ++ mdio_write(tp, 0x15, 0x002b); ++ mdio_write(tp, 0x19, 0x7630); ++ mdio_write(tp, 0x15, 0x002c); ++ mdio_write(tp, 0x19, 0x31a6); ++ mdio_write(tp, 0x15, 0x002d); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x002e); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x002f); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0030); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0031); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0032); ++ mdio_write(tp, 0x19, 0x4801); ++ mdio_write(tp, 0x15, 0x0033); ++ mdio_write(tp, 0x19, 0x6803); ++ mdio_write(tp, 0x15, 0x0034); ++ mdio_write(tp, 0x19, 0x66a1); ++ mdio_write(tp, 0x15, 0x0035); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0036); ++ mdio_write(tp, 0x19, 0x6c03); ++ mdio_write(tp, 0x15, 0x0037); ++ mdio_write(tp, 0x19, 0xa300); ++ mdio_write(tp, 0x15, 0x0038); ++ mdio_write(tp, 0x19, 0x64a1); ++ mdio_write(tp, 0x15, 0x0039); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x003a); ++ mdio_write(tp, 0x19, 0x74f8); ++ mdio_write(tp, 0x15, 0x003b); ++ mdio_write(tp, 0x19, 0x63d0); ++ mdio_write(tp, 0x15, 0x003c); ++ mdio_write(tp, 0x19, 0x7ff0); ++ mdio_write(tp, 0x15, 0x003d); ++ mdio_write(tp, 0x19, 0x77f0); ++ mdio_write(tp, 0x15, 0x003e); ++ mdio_write(tp, 0x19, 0x7ff0); ++ mdio_write(tp, 0x15, 0x003f); ++ mdio_write(tp, 0x19, 0x7750); ++ mdio_write(tp, 0x15, 0x0040); ++ mdio_write(tp, 0x19, 0x63d8); ++ mdio_write(tp, 0x15, 0x0041); ++ mdio_write(tp, 0x19, 0x7cf0); ++ mdio_write(tp, 0x15, 0x0042); ++ mdio_write(tp, 0x19, 0x7708); ++ mdio_write(tp, 0x15, 0x0043); ++ mdio_write(tp, 0x19, 0xa654); ++ mdio_write(tp, 0x15, 0x0044); ++ mdio_write(tp, 0x19, 0x304a); ++ mdio_write(tp, 0x15, 0x0045); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0046); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0047); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0048); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0049); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x004a); ++ mdio_write(tp, 0x19, 0x4802); ++ mdio_write(tp, 0x15, 0x004b); ++ mdio_write(tp, 0x19, 0x4003); ++ mdio_write(tp, 0x15, 0x004c); ++ mdio_write(tp, 0x19, 0x4440); ++ mdio_write(tp, 0x15, 0x004d); ++ mdio_write(tp, 0x19, 0x63c8); ++ mdio_write(tp, 0x15, 0x004e); ++ mdio_write(tp, 0x19, 0x6481); ++ mdio_write(tp, 0x15, 0x004f); ++ mdio_write(tp, 0x19, 0x9d00); ++ mdio_write(tp, 0x15, 0x0050); ++ mdio_write(tp, 0x19, 0x63e8); ++ mdio_write(tp, 0x15, 0x0051); ++ mdio_write(tp, 0x19, 0x7d00); ++ mdio_write(tp, 0x15, 0x0052); ++ mdio_write(tp, 0x19, 0x5900); ++ mdio_write(tp, 0x15, 0x0053); ++ mdio_write(tp, 0x19, 0x63f8); ++ mdio_write(tp, 0x15, 0x0054); ++ mdio_write(tp, 0x19, 0x64a1); ++ mdio_write(tp, 0x15, 0x0055); ++ mdio_write(tp, 0x19, 0x3116); ++ mdio_write(tp, 0x15, 0x0056); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0057); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0058); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0059); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x005a); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x005b); ++ mdio_write(tp, 0x19, 0x6c03); ++ mdio_write(tp, 0x15, 0x005c); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x005d); ++ mdio_write(tp, 0x19, 0x6000); ++ mdio_write(tp, 0x15, 0x005e); ++ mdio_write(tp, 0x19, 0x59ce); ++ mdio_write(tp, 0x15, 0x005f); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x0060); ++ mdio_write(tp, 0x19, 0x7d00); ++ mdio_write(tp, 0x15, 0x0061); ++ mdio_write(tp, 0x19, 0x72b0); ++ mdio_write(tp, 0x15, 0x0062); ++ mdio_write(tp, 0x19, 0x400e); ++ mdio_write(tp, 0x15, 0x0063); ++ mdio_write(tp, 0x19, 0x4440); ++ mdio_write(tp, 0x15, 0x0064); ++ mdio_write(tp, 0x19, 0x9d00); ++ mdio_write(tp, 0x15, 0x0065); ++ mdio_write(tp, 0x19, 0x7f00); ++ mdio_write(tp, 0x15, 0x0066); ++ mdio_write(tp, 0x19, 0x70b0); ++ mdio_write(tp, 0x15, 0x0067); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x0068); ++ mdio_write(tp, 0x19, 0x6008); ++ mdio_write(tp, 0x15, 0x0069); ++ mdio_write(tp, 0x19, 0x7cf0); ++ mdio_write(tp, 0x15, 0x006a); ++ mdio_write(tp, 0x19, 0x7750); ++ mdio_write(tp, 0x15, 0x006b); ++ mdio_write(tp, 0x19, 0x4007); ++ mdio_write(tp, 0x15, 0x006c); ++ mdio_write(tp, 0x19, 0x4500); ++ mdio_write(tp, 0x15, 0x006d); ++ mdio_write(tp, 0x19, 0x4023); ++ mdio_write(tp, 0x15, 0x006e); ++ mdio_write(tp, 0x19, 0x4580); ++ mdio_write(tp, 0x15, 0x006f); ++ mdio_write(tp, 0x19, 0x9f00); ++ mdio_write(tp, 0x15, 0x0070); ++ mdio_write(tp, 0x19, 0xcd78); ++ mdio_write(tp, 0x15, 0x0071); ++ mdio_write(tp, 0x19, 0x0003); ++ mdio_write(tp, 0x15, 0x0072); ++ mdio_write(tp, 0x19, 0xbe02); ++ mdio_write(tp, 0x15, 0x0073); ++ mdio_write(tp, 0x19, 0x3070); ++ mdio_write(tp, 0x15, 0x0074); ++ mdio_write(tp, 0x19, 0x7cf0); ++ mdio_write(tp, 0x15, 0x0075); ++ mdio_write(tp, 0x19, 0x77f0); ++ mdio_write(tp, 0x15, 0x0076); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x0077); ++ mdio_write(tp, 0x19, 0x4007); ++ mdio_write(tp, 0x15, 0x0078); ++ mdio_write(tp, 0x19, 0x4500); ++ mdio_write(tp, 0x15, 0x0079); ++ mdio_write(tp, 0x19, 0x4023); ++ mdio_write(tp, 0x15, 0x007a); ++ mdio_write(tp, 0x19, 0x4580); ++ mdio_write(tp, 0x15, 0x007b); ++ mdio_write(tp, 0x19, 0x9f00); ++ mdio_write(tp, 0x15, 0x007c); ++ mdio_write(tp, 0x19, 0xce80); ++ mdio_write(tp, 0x15, 0x007d); ++ mdio_write(tp, 0x19, 0x0004); ++ mdio_write(tp, 0x15, 0x007e); ++ mdio_write(tp, 0x19, 0xce80); ++ mdio_write(tp, 0x15, 0x007f); ++ mdio_write(tp, 0x19, 0x0002); ++ mdio_write(tp, 0x15, 0x0080); ++ mdio_write(tp, 0x19, 0x307c); ++ mdio_write(tp, 0x15, 0x0081); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x0082); ++ mdio_write(tp, 0x19, 0x480f); ++ mdio_write(tp, 0x15, 0x0083); ++ mdio_write(tp, 0x19, 0x6802); ++ mdio_write(tp, 0x15, 0x0084); ++ mdio_write(tp, 0x19, 0x6680); ++ mdio_write(tp, 0x15, 0x0085); ++ mdio_write(tp, 0x19, 0x7c10); ++ mdio_write(tp, 0x15, 0x0086); ++ mdio_write(tp, 0x19, 0x6010); ++ mdio_write(tp, 0x15, 0x0087); ++ mdio_write(tp, 0x19, 0x400a); ++ mdio_write(tp, 0x15, 0x0088); ++ mdio_write(tp, 0x19, 0x4580); ++ mdio_write(tp, 0x15, 0x0089); ++ mdio_write(tp, 0x19, 0x9e00); ++ mdio_write(tp, 0x15, 0x008a); ++ mdio_write(tp, 0x19, 0x7d00); ++ mdio_write(tp, 0x15, 0x008b); ++ mdio_write(tp, 0x19, 0x5800); ++ mdio_write(tp, 0x15, 0x008c); ++ mdio_write(tp, 0x19, 0x63c8); ++ mdio_write(tp, 0x15, 0x008d); ++ mdio_write(tp, 0x19, 0x63d8); ++ mdio_write(tp, 0x15, 0x008e); ++ mdio_write(tp, 0x19, 0x66a0); ++ mdio_write(tp, 0x15, 0x008f); ++ mdio_write(tp, 0x19, 0x8300); ++ mdio_write(tp, 0x15, 0x0090); ++ mdio_write(tp, 0x19, 0x7ff0); ++ mdio_write(tp, 0x15, 0x0091); ++ mdio_write(tp, 0x19, 0x74f0); ++ mdio_write(tp, 0x15, 0x0092); ++ mdio_write(tp, 0x19, 0x3006); ++ mdio_write(tp, 0x15, 0x0093); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0094); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0095); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0096); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0097); ++ mdio_write(tp, 0x19, 0x4803); ++ mdio_write(tp, 0x15, 0x0098); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0099); ++ mdio_write(tp, 0x19, 0x6c03); ++ mdio_write(tp, 0x15, 0x009a); ++ mdio_write(tp, 0x19, 0xa203); ++ mdio_write(tp, 0x15, 0x009b); ++ mdio_write(tp, 0x19, 0x64b1); ++ mdio_write(tp, 0x15, 0x009c); ++ mdio_write(tp, 0x19, 0x309e); ++ mdio_write(tp, 0x15, 0x009d); ++ mdio_write(tp, 0x19, 0x64b3); ++ mdio_write(tp, 0x15, 0x009e); ++ mdio_write(tp, 0x19, 0x4030); ++ mdio_write(tp, 0x15, 0x009f); ++ mdio_write(tp, 0x19, 0x440e); ++ mdio_write(tp, 0x15, 0x00a0); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x00a1); ++ mdio_write(tp, 0x19, 0x4419); ++ mdio_write(tp, 0x15, 0x00a2); ++ mdio_write(tp, 0x19, 0x7801); ++ mdio_write(tp, 0x15, 0x00a3); ++ mdio_write(tp, 0x19, 0xc520); ++ mdio_write(tp, 0x15, 0x00a4); ++ mdio_write(tp, 0x19, 0x000b); ++ mdio_write(tp, 0x15, 0x00a5); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x00a6); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x00a7); ++ mdio_write(tp, 0x19, 0x58a4); ++ mdio_write(tp, 0x15, 0x00a8); ++ mdio_write(tp, 0x19, 0x63da); ++ mdio_write(tp, 0x15, 0x00a9); ++ mdio_write(tp, 0x19, 0x5cb0); ++ mdio_write(tp, 0x15, 0x00aa); ++ mdio_write(tp, 0x19, 0x7d00); ++ mdio_write(tp, 0x15, 0x00ab); ++ mdio_write(tp, 0x19, 0x72b0); ++ mdio_write(tp, 0x15, 0x00ac); ++ mdio_write(tp, 0x19, 0x7f00); ++ mdio_write(tp, 0x15, 0x00ad); ++ mdio_write(tp, 0x19, 0x70b0); ++ mdio_write(tp, 0x15, 0x00ae); ++ mdio_write(tp, 0x19, 0x30b8); ++ mdio_write(tp, 0x15, 0x00AF); ++ mdio_write(tp, 0x19, 0x4060); ++ mdio_write(tp, 0x15, 0x00B0); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x00B1); ++ mdio_write(tp, 0x19, 0x7e00); ++ mdio_write(tp, 0x15, 0x00B2); ++ mdio_write(tp, 0x19, 0x72B0); ++ mdio_write(tp, 0x15, 0x00B3); ++ mdio_write(tp, 0x19, 0x7F00); ++ mdio_write(tp, 0x15, 0x00B4); ++ mdio_write(tp, 0x19, 0x73B0); ++ mdio_write(tp, 0x15, 0x00b5); ++ mdio_write(tp, 0x19, 0x58a0); ++ mdio_write(tp, 0x15, 0x00b6); ++ mdio_write(tp, 0x19, 0x63d2); ++ mdio_write(tp, 0x15, 0x00b7); ++ mdio_write(tp, 0x19, 0x5c00); ++ mdio_write(tp, 0x15, 0x00b8); ++ mdio_write(tp, 0x19, 0x5780); ++ mdio_write(tp, 0x15, 0x00b9); ++ mdio_write(tp, 0x19, 0xb60d); ++ mdio_write(tp, 0x15, 0x00ba); ++ mdio_write(tp, 0x19, 0x9bff); ++ mdio_write(tp, 0x15, 0x00bb); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x00bc); ++ mdio_write(tp, 0x19, 0x6001); ++ mdio_write(tp, 0x15, 0x00bd); ++ mdio_write(tp, 0x19, 0xc020); ++ mdio_write(tp, 0x15, 0x00be); ++ mdio_write(tp, 0x19, 0x002b); ++ mdio_write(tp, 0x15, 0x00bf); ++ mdio_write(tp, 0x19, 0xc137); ++ mdio_write(tp, 0x15, 0x00c0); ++ mdio_write(tp, 0x19, 0x0006); ++ mdio_write(tp, 0x15, 0x00c1); ++ mdio_write(tp, 0x19, 0x9af8); ++ mdio_write(tp, 0x15, 0x00c2); ++ mdio_write(tp, 0x19, 0x30c6); ++ mdio_write(tp, 0x15, 0x00c3); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00c4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00c5); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00c6); ++ mdio_write(tp, 0x19, 0x7d00); ++ mdio_write(tp, 0x15, 0x00c7); ++ mdio_write(tp, 0x19, 0x70b0); ++ mdio_write(tp, 0x15, 0x00c8); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x00c9); ++ mdio_write(tp, 0x19, 0x4804); ++ mdio_write(tp, 0x15, 0x00ca); ++ mdio_write(tp, 0x19, 0x7c80); ++ mdio_write(tp, 0x15, 0x00cb); ++ mdio_write(tp, 0x19, 0x5c80); ++ mdio_write(tp, 0x15, 0x00cc); ++ mdio_write(tp, 0x19, 0x4010); ++ mdio_write(tp, 0x15, 0x00cd); ++ mdio_write(tp, 0x19, 0x4415); ++ mdio_write(tp, 0x15, 0x00ce); ++ mdio_write(tp, 0x19, 0x9b00); ++ mdio_write(tp, 0x15, 0x00cf); ++ mdio_write(tp, 0x19, 0x7f00); ++ mdio_write(tp, 0x15, 0x00d0); ++ mdio_write(tp, 0x19, 0x70b0); ++ mdio_write(tp, 0x15, 0x00d1); ++ mdio_write(tp, 0x19, 0x3177); ++ mdio_write(tp, 0x15, 0x00d2); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00d3); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00d4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00d5); ++ mdio_write(tp, 0x19, 0x4808); ++ mdio_write(tp, 0x15, 0x00d6); ++ mdio_write(tp, 0x19, 0x4007); ++ mdio_write(tp, 0x15, 0x00d7); ++ mdio_write(tp, 0x19, 0x4420); ++ mdio_write(tp, 0x15, 0x00d8); ++ mdio_write(tp, 0x19, 0x63d8); ++ mdio_write(tp, 0x15, 0x00d9); ++ mdio_write(tp, 0x19, 0xb608); ++ mdio_write(tp, 0x15, 0x00da); ++ mdio_write(tp, 0x19, 0xbcbd); ++ mdio_write(tp, 0x15, 0x00db); ++ mdio_write(tp, 0x19, 0xc60b); ++ mdio_write(tp, 0x15, 0x00dc); ++ mdio_write(tp, 0x19, 0x00fd); ++ mdio_write(tp, 0x15, 0x00dd); ++ mdio_write(tp, 0x19, 0x30e1); ++ mdio_write(tp, 0x15, 0x00de); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00df); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00e0); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00e1); ++ mdio_write(tp, 0x19, 0x4809); ++ mdio_write(tp, 0x15, 0x00e2); ++ mdio_write(tp, 0x19, 0x7e40); ++ mdio_write(tp, 0x15, 0x00e3); ++ mdio_write(tp, 0x19, 0x5a40); ++ mdio_write(tp, 0x15, 0x00e4); ++ mdio_write(tp, 0x19, 0x305a); ++ mdio_write(tp, 0x15, 0x00e5); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00e6); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00e7); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00e8); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00e9); ++ mdio_write(tp, 0x19, 0x480a); ++ mdio_write(tp, 0x15, 0x00ea); ++ mdio_write(tp, 0x19, 0x5820); ++ mdio_write(tp, 0x15, 0x00eb); ++ mdio_write(tp, 0x19, 0x6c03); ++ mdio_write(tp, 0x15, 0x00ec); ++ mdio_write(tp, 0x19, 0xb60a); ++ mdio_write(tp, 0x15, 0x00ed); ++ mdio_write(tp, 0x19, 0xda07); ++ mdio_write(tp, 0x15, 0x00ee); ++ mdio_write(tp, 0x19, 0x0008); ++ mdio_write(tp, 0x15, 0x00ef); ++ mdio_write(tp, 0x19, 0xc60b); ++ mdio_write(tp, 0x15, 0x00f0); ++ mdio_write(tp, 0x19, 0x00fc); ++ mdio_write(tp, 0x15, 0x00f1); ++ mdio_write(tp, 0x19, 0x30f6); ++ mdio_write(tp, 0x15, 0x00f2); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00f3); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00f4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00f5); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x00f6); ++ mdio_write(tp, 0x19, 0x4408); ++ mdio_write(tp, 0x15, 0x00f7); ++ mdio_write(tp, 0x19, 0x480b); ++ mdio_write(tp, 0x15, 0x00f8); ++ mdio_write(tp, 0x19, 0x6f03); ++ mdio_write(tp, 0x15, 0x00f9); ++ mdio_write(tp, 0x19, 0x405f); ++ mdio_write(tp, 0x15, 0x00fa); ++ mdio_write(tp, 0x19, 0x4448); ++ mdio_write(tp, 0x15, 0x00fb); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x00fc); ++ mdio_write(tp, 0x19, 0x4468); ++ mdio_write(tp, 0x15, 0x00fd); ++ mdio_write(tp, 0x19, 0x9c03); ++ mdio_write(tp, 0x15, 0x00fe); ++ mdio_write(tp, 0x19, 0x6f07); ++ mdio_write(tp, 0x15, 0x00ff); ++ mdio_write(tp, 0x19, 0x58a0); ++ mdio_write(tp, 0x15, 0x0100); ++ mdio_write(tp, 0x19, 0xd6d1); ++ mdio_write(tp, 0x15, 0x0101); ++ mdio_write(tp, 0x19, 0x0004); ++ mdio_write(tp, 0x15, 0x0102); ++ mdio_write(tp, 0x19, 0xc137); ++ mdio_write(tp, 0x15, 0x0103); ++ mdio_write(tp, 0x19, 0x0002); ++ mdio_write(tp, 0x15, 0x0104); ++ mdio_write(tp, 0x19, 0xa0e5); ++ mdio_write(tp, 0x15, 0x0105); ++ mdio_write(tp, 0x19, 0x9df8); ++ mdio_write(tp, 0x15, 0x0106); ++ mdio_write(tp, 0x19, 0x30c6); ++ mdio_write(tp, 0x15, 0x0107); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0108); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0109); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x010a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x010b); ++ mdio_write(tp, 0x19, 0x4808); ++ mdio_write(tp, 0x15, 0x010c); ++ mdio_write(tp, 0x19, 0xc32d); ++ mdio_write(tp, 0x15, 0x010d); ++ mdio_write(tp, 0x19, 0x0003); ++ mdio_write(tp, 0x15, 0x010e); ++ mdio_write(tp, 0x19, 0xc8b3); ++ mdio_write(tp, 0x15, 0x010f); ++ mdio_write(tp, 0x19, 0x00fc); ++ mdio_write(tp, 0x15, 0x0110); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x0111); ++ mdio_write(tp, 0x19, 0x3116); ++ mdio_write(tp, 0x15, 0x0112); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0113); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0114); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0115); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0116); ++ mdio_write(tp, 0x19, 0x4803); ++ mdio_write(tp, 0x15, 0x0117); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0118); ++ mdio_write(tp, 0x19, 0x6c02); ++ mdio_write(tp, 0x15, 0x0119); ++ mdio_write(tp, 0x19, 0x7c04); ++ mdio_write(tp, 0x15, 0x011a); ++ mdio_write(tp, 0x19, 0x6000); ++ mdio_write(tp, 0x15, 0x011b); ++ mdio_write(tp, 0x19, 0x5cf7); ++ mdio_write(tp, 0x15, 0x011c); ++ mdio_write(tp, 0x19, 0x7c2a); ++ mdio_write(tp, 0x15, 0x011d); ++ mdio_write(tp, 0x19, 0x5800); ++ mdio_write(tp, 0x15, 0x011e); ++ mdio_write(tp, 0x19, 0x5400); ++ mdio_write(tp, 0x15, 0x011f); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x0120); ++ mdio_write(tp, 0x19, 0x74f0); ++ mdio_write(tp, 0x15, 0x0121); ++ mdio_write(tp, 0x19, 0x4019); ++ mdio_write(tp, 0x15, 0x0122); ++ mdio_write(tp, 0x19, 0x440d); ++ mdio_write(tp, 0x15, 0x0123); ++ mdio_write(tp, 0x19, 0xb6c1); ++ mdio_write(tp, 0x15, 0x0124); ++ mdio_write(tp, 0x19, 0xc05b); ++ mdio_write(tp, 0x15, 0x0125); ++ mdio_write(tp, 0x19, 0x00bf); ++ mdio_write(tp, 0x15, 0x0126); ++ mdio_write(tp, 0x19, 0xc025); ++ mdio_write(tp, 0x15, 0x0127); ++ mdio_write(tp, 0x19, 0x00bd); ++ mdio_write(tp, 0x15, 0x0128); ++ mdio_write(tp, 0x19, 0xc603); ++ mdio_write(tp, 0x15, 0x0129); ++ mdio_write(tp, 0x19, 0x00bb); ++ mdio_write(tp, 0x15, 0x012a); ++ mdio_write(tp, 0x19, 0x8805); ++ mdio_write(tp, 0x15, 0x012b); ++ mdio_write(tp, 0x19, 0x7801); ++ mdio_write(tp, 0x15, 0x012c); ++ mdio_write(tp, 0x19, 0x4001); ++ mdio_write(tp, 0x15, 0x012d); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x012e); ++ mdio_write(tp, 0x19, 0xa3dd); ++ mdio_write(tp, 0x15, 0x012f); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0130); ++ mdio_write(tp, 0x19, 0x6c03); ++ mdio_write(tp, 0x15, 0x0131); ++ mdio_write(tp, 0x19, 0x8407); ++ mdio_write(tp, 0x15, 0x0132); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0133); ++ mdio_write(tp, 0x19, 0x6c02); ++ mdio_write(tp, 0x15, 0x0134); ++ mdio_write(tp, 0x19, 0xd9b8); ++ mdio_write(tp, 0x15, 0x0135); ++ mdio_write(tp, 0x19, 0x0003); ++ mdio_write(tp, 0x15, 0x0136); ++ mdio_write(tp, 0x19, 0xc240); ++ mdio_write(tp, 0x15, 0x0137); ++ mdio_write(tp, 0x19, 0x0015); ++ mdio_write(tp, 0x15, 0x0138); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0139); ++ mdio_write(tp, 0x19, 0x6c02); ++ mdio_write(tp, 0x15, 0x013a); ++ mdio_write(tp, 0x19, 0x9ae9); ++ mdio_write(tp, 0x15, 0x013b); ++ mdio_write(tp, 0x19, 0x3140); ++ mdio_write(tp, 0x15, 0x013c); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x013d); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x013e); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x013f); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0140); ++ mdio_write(tp, 0x19, 0x4807); ++ mdio_write(tp, 0x15, 0x0141); ++ mdio_write(tp, 0x19, 0x4004); ++ mdio_write(tp, 0x15, 0x0142); ++ mdio_write(tp, 0x19, 0x4410); ++ mdio_write(tp, 0x15, 0x0143); ++ mdio_write(tp, 0x19, 0x7c0c); ++ mdio_write(tp, 0x15, 0x0144); ++ mdio_write(tp, 0x19, 0x600c); ++ mdio_write(tp, 0x15, 0x0145); ++ mdio_write(tp, 0x19, 0x9b00); ++ mdio_write(tp, 0x15, 0x0146); ++ mdio_write(tp, 0x19, 0xa68f); ++ mdio_write(tp, 0x15, 0x0147); ++ mdio_write(tp, 0x19, 0x3116); ++ mdio_write(tp, 0x15, 0x0148); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0149); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x014a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x014b); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x014c); ++ mdio_write(tp, 0x19, 0x4804); ++ mdio_write(tp, 0x15, 0x014d); ++ mdio_write(tp, 0x19, 0x54c0); ++ mdio_write(tp, 0x15, 0x014e); ++ mdio_write(tp, 0x19, 0xb703); ++ mdio_write(tp, 0x15, 0x014f); ++ mdio_write(tp, 0x19, 0x5cff); ++ mdio_write(tp, 0x15, 0x0150); ++ mdio_write(tp, 0x19, 0x315f); ++ mdio_write(tp, 0x15, 0x0151); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x0152); ++ mdio_write(tp, 0x19, 0x74f8); ++ mdio_write(tp, 0x15, 0x0153); ++ mdio_write(tp, 0x19, 0x6421); ++ mdio_write(tp, 0x15, 0x0154); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x0155); ++ mdio_write(tp, 0x19, 0x6000); ++ mdio_write(tp, 0x15, 0x0156); ++ mdio_write(tp, 0x19, 0x4003); ++ mdio_write(tp, 0x15, 0x0157); ++ mdio_write(tp, 0x19, 0x4418); ++ mdio_write(tp, 0x15, 0x0158); ++ mdio_write(tp, 0x19, 0x9b00); ++ mdio_write(tp, 0x15, 0x0159); ++ mdio_write(tp, 0x19, 0x6461); ++ mdio_write(tp, 0x15, 0x015a); ++ mdio_write(tp, 0x19, 0x64e1); ++ mdio_write(tp, 0x15, 0x015b); ++ mdio_write(tp, 0x19, 0x7c20); ++ mdio_write(tp, 0x15, 0x015c); ++ mdio_write(tp, 0x19, 0x5820); ++ mdio_write(tp, 0x15, 0x015d); ++ mdio_write(tp, 0x19, 0x5ccf); ++ mdio_write(tp, 0x15, 0x015e); ++ mdio_write(tp, 0x19, 0x7050); ++ mdio_write(tp, 0x15, 0x015f); ++ mdio_write(tp, 0x19, 0xd9b8); ++ mdio_write(tp, 0x15, 0x0160); ++ mdio_write(tp, 0x19, 0x0008); ++ mdio_write(tp, 0x15, 0x0161); ++ mdio_write(tp, 0x19, 0xdab1); ++ mdio_write(tp, 0x15, 0x0162); ++ mdio_write(tp, 0x19, 0x0015); ++ mdio_write(tp, 0x15, 0x0163); ++ mdio_write(tp, 0x19, 0xc244); ++ mdio_write(tp, 0x15, 0x0164); ++ mdio_write(tp, 0x19, 0x0013); ++ mdio_write(tp, 0x15, 0x0165); ++ mdio_write(tp, 0x19, 0xc021); ++ mdio_write(tp, 0x15, 0x0166); ++ mdio_write(tp, 0x19, 0x00f9); ++ mdio_write(tp, 0x15, 0x0167); ++ mdio_write(tp, 0x19, 0x3177); ++ mdio_write(tp, 0x15, 0x0168); ++ mdio_write(tp, 0x19, 0x5cf7); ++ mdio_write(tp, 0x15, 0x0169); ++ mdio_write(tp, 0x19, 0x4010); ++ mdio_write(tp, 0x15, 0x016a); ++ mdio_write(tp, 0x19, 0x4428); ++ mdio_write(tp, 0x15, 0x016b); ++ mdio_write(tp, 0x19, 0x9c00); ++ mdio_write(tp, 0x15, 0x016c); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x016d); ++ mdio_write(tp, 0x19, 0x6008); ++ mdio_write(tp, 0x15, 0x016e); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x016f); ++ mdio_write(tp, 0x19, 0x74f0); ++ mdio_write(tp, 0x15, 0x0170); ++ mdio_write(tp, 0x19, 0x6461); ++ mdio_write(tp, 0x15, 0x0171); ++ mdio_write(tp, 0x19, 0x6421); ++ mdio_write(tp, 0x15, 0x0172); ++ mdio_write(tp, 0x19, 0x64a1); ++ mdio_write(tp, 0x15, 0x0173); ++ mdio_write(tp, 0x19, 0x3116); ++ mdio_write(tp, 0x15, 0x0174); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0175); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0176); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0177); ++ mdio_write(tp, 0x19, 0x4805); ++ mdio_write(tp, 0x15, 0x0178); ++ mdio_write(tp, 0x19, 0xa103); ++ mdio_write(tp, 0x15, 0x0179); ++ mdio_write(tp, 0x19, 0x7c02); ++ mdio_write(tp, 0x15, 0x017a); ++ mdio_write(tp, 0x19, 0x6002); ++ mdio_write(tp, 0x15, 0x017b); ++ mdio_write(tp, 0x19, 0x7e00); ++ mdio_write(tp, 0x15, 0x017c); ++ mdio_write(tp, 0x19, 0x5400); ++ mdio_write(tp, 0x15, 0x017d); ++ mdio_write(tp, 0x19, 0x7c6b); ++ mdio_write(tp, 0x15, 0x017e); ++ mdio_write(tp, 0x19, 0x5c63); ++ mdio_write(tp, 0x15, 0x017f); ++ mdio_write(tp, 0x19, 0x407d); ++ mdio_write(tp, 0x15, 0x0180); ++ mdio_write(tp, 0x19, 0xa602); ++ mdio_write(tp, 0x15, 0x0181); ++ mdio_write(tp, 0x19, 0x4001); ++ mdio_write(tp, 0x15, 0x0182); ++ mdio_write(tp, 0x19, 0x4420); ++ mdio_write(tp, 0x15, 0x0183); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x0184); ++ mdio_write(tp, 0x19, 0x44a1); ++ mdio_write(tp, 0x15, 0x0185); ++ mdio_write(tp, 0x19, 0xd6e0); ++ mdio_write(tp, 0x15, 0x0186); ++ mdio_write(tp, 0x19, 0x0009); ++ mdio_write(tp, 0x15, 0x0187); ++ mdio_write(tp, 0x19, 0x9efe); ++ mdio_write(tp, 0x15, 0x0188); ++ mdio_write(tp, 0x19, 0x7c02); ++ mdio_write(tp, 0x15, 0x0189); ++ mdio_write(tp, 0x19, 0x6000); ++ mdio_write(tp, 0x15, 0x018a); ++ mdio_write(tp, 0x19, 0x9c00); ++ mdio_write(tp, 0x15, 0x018b); ++ mdio_write(tp, 0x19, 0x318f); ++ mdio_write(tp, 0x15, 0x018c); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x018d); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x018e); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x018f); ++ mdio_write(tp, 0x19, 0x4806); ++ mdio_write(tp, 0x15, 0x0190); ++ mdio_write(tp, 0x19, 0x7c10); ++ mdio_write(tp, 0x15, 0x0191); ++ mdio_write(tp, 0x19, 0x5c10); ++ mdio_write(tp, 0x15, 0x0192); ++ mdio_write(tp, 0x19, 0x40fa); ++ mdio_write(tp, 0x15, 0x0193); ++ mdio_write(tp, 0x19, 0xa602); ++ mdio_write(tp, 0x15, 0x0194); ++ mdio_write(tp, 0x19, 0x4010); ++ mdio_write(tp, 0x15, 0x0195); ++ mdio_write(tp, 0x19, 0x4440); ++ mdio_write(tp, 0x15, 0x0196); ++ mdio_write(tp, 0x19, 0x9d00); ++ mdio_write(tp, 0x15, 0x0197); ++ mdio_write(tp, 0x19, 0x7c80); ++ mdio_write(tp, 0x15, 0x0198); ++ mdio_write(tp, 0x19, 0x6400); ++ mdio_write(tp, 0x15, 0x0199); ++ mdio_write(tp, 0x19, 0x4003); ++ mdio_write(tp, 0x15, 0x019a); ++ mdio_write(tp, 0x19, 0x4540); ++ mdio_write(tp, 0x15, 0x019b); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x019c); ++ mdio_write(tp, 0x19, 0x6008); ++ mdio_write(tp, 0x15, 0x019d); ++ mdio_write(tp, 0x19, 0x9f00); ++ mdio_write(tp, 0x15, 0x019e); ++ mdio_write(tp, 0x19, 0x7c40); ++ mdio_write(tp, 0x15, 0x019f); ++ mdio_write(tp, 0x19, 0x6400); ++ mdio_write(tp, 0x15, 0x01a0); ++ mdio_write(tp, 0x19, 0x7c80); ++ mdio_write(tp, 0x15, 0x01a1); ++ mdio_write(tp, 0x19, 0x6480); ++ mdio_write(tp, 0x15, 0x01a2); ++ mdio_write(tp, 0x19, 0x3140); ++ mdio_write(tp, 0x15, 0x01a3); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01a4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01a5); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01a6); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x01a7); ++ mdio_write(tp, 0x19, 0x7c0b); ++ mdio_write(tp, 0x15, 0x01a8); ++ mdio_write(tp, 0x19, 0x6c01); ++ mdio_write(tp, 0x15, 0x01a9); ++ mdio_write(tp, 0x19, 0x64a8); ++ mdio_write(tp, 0x15, 0x01aa); ++ mdio_write(tp, 0x19, 0x6800); ++ mdio_write(tp, 0x15, 0x01ab); ++ mdio_write(tp, 0x19, 0x5cf0); ++ mdio_write(tp, 0x15, 0x01ac); ++ mdio_write(tp, 0x19, 0x588f); ++ mdio_write(tp, 0x15, 0x01ad); ++ mdio_write(tp, 0x19, 0xb628); ++ mdio_write(tp, 0x15, 0x01ae); ++ mdio_write(tp, 0x19, 0xc053); ++ mdio_write(tp, 0x15, 0x01af); ++ mdio_write(tp, 0x19, 0x0026); ++ mdio_write(tp, 0x15, 0x01b0); ++ mdio_write(tp, 0x19, 0xc02d); ++ mdio_write(tp, 0x15, 0x01b1); ++ mdio_write(tp, 0x19, 0x0024); ++ mdio_write(tp, 0x15, 0x01b2); ++ mdio_write(tp, 0x19, 0xc603); ++ mdio_write(tp, 0x15, 0x01b3); ++ mdio_write(tp, 0x19, 0x0022); ++ mdio_write(tp, 0x15, 0x01b4); ++ mdio_write(tp, 0x19, 0x8cf9); ++ mdio_write(tp, 0x15, 0x01b5); ++ mdio_write(tp, 0x19, 0x31ba); ++ mdio_write(tp, 0x15, 0x01b6); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01b7); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01b8); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01b9); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01ba); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x01bb); ++ mdio_write(tp, 0x19, 0x5420); ++ mdio_write(tp, 0x15, 0x01bc); ++ mdio_write(tp, 0x19, 0x4811); ++ mdio_write(tp, 0x15, 0x01bd); ++ mdio_write(tp, 0x19, 0x5000); ++ mdio_write(tp, 0x15, 0x01be); ++ mdio_write(tp, 0x19, 0x4801); ++ mdio_write(tp, 0x15, 0x01bf); ++ mdio_write(tp, 0x19, 0x6800); ++ mdio_write(tp, 0x15, 0x01c0); ++ mdio_write(tp, 0x19, 0x31f5); ++ mdio_write(tp, 0x15, 0x01c1); ++ mdio_write(tp, 0x19, 0xb614); ++ mdio_write(tp, 0x15, 0x01c2); ++ mdio_write(tp, 0x19, 0x8ce4); ++ mdio_write(tp, 0x15, 0x01c3); ++ mdio_write(tp, 0x19, 0xb30c); ++ mdio_write(tp, 0x15, 0x01c4); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x01c5); ++ mdio_write(tp, 0x19, 0x6c02); ++ mdio_write(tp, 0x15, 0x01c6); ++ mdio_write(tp, 0x19, 0x8206); ++ mdio_write(tp, 0x15, 0x01c7); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x01c8); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x01c9); ++ mdio_write(tp, 0x19, 0x7c04); ++ mdio_write(tp, 0x15, 0x01ca); ++ mdio_write(tp, 0x19, 0x7404); ++ mdio_write(tp, 0x15, 0x01cb); ++ mdio_write(tp, 0x19, 0x31c0); ++ mdio_write(tp, 0x15, 0x01cc); ++ mdio_write(tp, 0x19, 0x7c04); ++ mdio_write(tp, 0x15, 0x01cd); ++ mdio_write(tp, 0x19, 0x7400); ++ mdio_write(tp, 0x15, 0x01ce); ++ mdio_write(tp, 0x19, 0x31c0); ++ mdio_write(tp, 0x15, 0x01cf); ++ mdio_write(tp, 0x19, 0x8df1); ++ mdio_write(tp, 0x15, 0x01d0); ++ mdio_write(tp, 0x19, 0x3248); ++ mdio_write(tp, 0x15, 0x01d1); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01d2); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01d3); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01d4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01d5); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x01d6); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x01d7); ++ mdio_write(tp, 0x19, 0x6c03); ++ mdio_write(tp, 0x15, 0x01d8); ++ mdio_write(tp, 0x19, 0x7670); ++ mdio_write(tp, 0x15, 0x01d9); ++ mdio_write(tp, 0x19, 0x4023); ++ mdio_write(tp, 0x15, 0x01da); ++ mdio_write(tp, 0x19, 0x4500); ++ mdio_write(tp, 0x15, 0x01db); ++ mdio_write(tp, 0x19, 0x4069); ++ mdio_write(tp, 0x15, 0x01dc); ++ mdio_write(tp, 0x19, 0x4580); ++ mdio_write(tp, 0x15, 0x01dd); ++ mdio_write(tp, 0x19, 0x9f00); ++ mdio_write(tp, 0x15, 0x01de); ++ mdio_write(tp, 0x19, 0xcff5); ++ mdio_write(tp, 0x15, 0x01df); ++ mdio_write(tp, 0x19, 0x00ff); ++ mdio_write(tp, 0x15, 0x01e0); ++ mdio_write(tp, 0x19, 0x76f0); ++ mdio_write(tp, 0x15, 0x01e1); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x01e2); ++ mdio_write(tp, 0x19, 0x4023); ++ mdio_write(tp, 0x15, 0x01e3); ++ mdio_write(tp, 0x19, 0x4500); ++ mdio_write(tp, 0x15, 0x01e4); ++ mdio_write(tp, 0x19, 0x4069); ++ mdio_write(tp, 0x15, 0x01e5); ++ mdio_write(tp, 0x19, 0x4580); ++ mdio_write(tp, 0x15, 0x01e6); ++ mdio_write(tp, 0x19, 0x9f00); ++ mdio_write(tp, 0x15, 0x01e7); ++ mdio_write(tp, 0x19, 0xd0f5); ++ mdio_write(tp, 0x15, 0x01e8); ++ mdio_write(tp, 0x19, 0x00ff); ++ mdio_write(tp, 0x15, 0x01e9); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x01ea); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x01eb); ++ mdio_write(tp, 0x19, 0x6800); ++ mdio_write(tp, 0x15, 0x01ec); ++ mdio_write(tp, 0x19, 0x66a0); ++ mdio_write(tp, 0x15, 0x01ed); ++ mdio_write(tp, 0x19, 0x8300); ++ mdio_write(tp, 0x15, 0x01ee); ++ mdio_write(tp, 0x19, 0x74f0); ++ mdio_write(tp, 0x15, 0x01ef); ++ mdio_write(tp, 0x19, 0x3006); ++ mdio_write(tp, 0x15, 0x01f0); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01f1); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01f2); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01f3); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01f4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x01f5); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x01f6); ++ mdio_write(tp, 0x19, 0x6c02); ++ mdio_write(tp, 0x15, 0x01f7); ++ mdio_write(tp, 0x19, 0x409d); ++ mdio_write(tp, 0x15, 0x01f8); ++ mdio_write(tp, 0x19, 0x7c87); ++ mdio_write(tp, 0x15, 0x01f9); ++ mdio_write(tp, 0x19, 0xae14); ++ mdio_write(tp, 0x15, 0x01fa); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x01fb); ++ mdio_write(tp, 0x19, 0x7c40); ++ mdio_write(tp, 0x15, 0x01fc); ++ mdio_write(tp, 0x19, 0x6800); ++ mdio_write(tp, 0x15, 0x01fd); ++ mdio_write(tp, 0x19, 0x7801); ++ mdio_write(tp, 0x15, 0x01fe); ++ mdio_write(tp, 0x19, 0x980e); ++ mdio_write(tp, 0x15, 0x01ff); ++ mdio_write(tp, 0x19, 0x930c); ++ mdio_write(tp, 0x15, 0x0200); ++ mdio_write(tp, 0x19, 0x9206); ++ mdio_write(tp, 0x15, 0x0201); ++ mdio_write(tp, 0x19, 0x4002); ++ mdio_write(tp, 0x15, 0x0202); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x0203); ++ mdio_write(tp, 0x19, 0x588f); ++ mdio_write(tp, 0x15, 0x0204); ++ mdio_write(tp, 0x19, 0x5520); ++ mdio_write(tp, 0x15, 0x0205); ++ mdio_write(tp, 0x19, 0x320c); ++ mdio_write(tp, 0x15, 0x0206); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x15, 0x0207); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x0208); ++ mdio_write(tp, 0x19, 0x588d); ++ mdio_write(tp, 0x15, 0x0209); ++ mdio_write(tp, 0x19, 0x5500); ++ mdio_write(tp, 0x15, 0x020a); ++ mdio_write(tp, 0x19, 0x320c); ++ mdio_write(tp, 0x15, 0x020b); ++ mdio_write(tp, 0x19, 0x4002); ++ mdio_write(tp, 0x15, 0x020c); ++ mdio_write(tp, 0x19, 0x3220); ++ mdio_write(tp, 0x15, 0x020d); ++ mdio_write(tp, 0x19, 0x4480); ++ mdio_write(tp, 0x15, 0x020e); ++ mdio_write(tp, 0x19, 0x9e03); ++ mdio_write(tp, 0x15, 0x020f); ++ mdio_write(tp, 0x19, 0x7c40); ++ mdio_write(tp, 0x15, 0x0210); ++ mdio_write(tp, 0x19, 0x6840); ++ mdio_write(tp, 0x15, 0x0211); ++ mdio_write(tp, 0x19, 0x7801); ++ mdio_write(tp, 0x15, 0x0212); ++ mdio_write(tp, 0x19, 0x980e); ++ mdio_write(tp, 0x15, 0x0213); ++ mdio_write(tp, 0x19, 0x930c); ++ mdio_write(tp, 0x15, 0x0214); ++ mdio_write(tp, 0x19, 0x9206); ++ mdio_write(tp, 0x15, 0x0215); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x15, 0x0216); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x0217); ++ mdio_write(tp, 0x19, 0x588f); ++ mdio_write(tp, 0x15, 0x0218); ++ mdio_write(tp, 0x19, 0x5520); ++ mdio_write(tp, 0x15, 0x0219); ++ mdio_write(tp, 0x19, 0x3220); ++ mdio_write(tp, 0x15, 0x021a); ++ mdio_write(tp, 0x19, 0x4002); ++ mdio_write(tp, 0x15, 0x021b); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x021c); ++ mdio_write(tp, 0x19, 0x588d); ++ mdio_write(tp, 0x15, 0x021d); ++ mdio_write(tp, 0x19, 0x5540); ++ mdio_write(tp, 0x15, 0x021e); ++ mdio_write(tp, 0x19, 0x3220); ++ mdio_write(tp, 0x15, 0x021f); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x15, 0x0220); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x0221); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0222); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x0223); ++ mdio_write(tp, 0x19, 0x3231); ++ mdio_write(tp, 0x15, 0x0224); ++ mdio_write(tp, 0x19, 0xab06); ++ mdio_write(tp, 0x15, 0x0225); ++ mdio_write(tp, 0x19, 0xbf08); ++ mdio_write(tp, 0x15, 0x0226); ++ mdio_write(tp, 0x19, 0x4076); ++ mdio_write(tp, 0x15, 0x0227); ++ mdio_write(tp, 0x19, 0x7d07); ++ mdio_write(tp, 0x15, 0x0228); ++ mdio_write(tp, 0x19, 0x4502); ++ mdio_write(tp, 0x15, 0x0229); ++ mdio_write(tp, 0x19, 0x3231); ++ mdio_write(tp, 0x15, 0x022a); ++ mdio_write(tp, 0x19, 0x7d80); ++ mdio_write(tp, 0x15, 0x022b); ++ mdio_write(tp, 0x19, 0x5180); ++ mdio_write(tp, 0x15, 0x022c); ++ mdio_write(tp, 0x19, 0x322f); ++ mdio_write(tp, 0x15, 0x022d); ++ mdio_write(tp, 0x19, 0x7d80); ++ mdio_write(tp, 0x15, 0x022e); ++ mdio_write(tp, 0x19, 0x5000); ++ mdio_write(tp, 0x15, 0x022f); ++ mdio_write(tp, 0x19, 0x7d07); ++ mdio_write(tp, 0x15, 0x0230); ++ mdio_write(tp, 0x19, 0x4402); ++ mdio_write(tp, 0x15, 0x0231); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0232); ++ mdio_write(tp, 0x19, 0x6c02); ++ mdio_write(tp, 0x15, 0x0233); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0234); ++ mdio_write(tp, 0x19, 0xb309); ++ mdio_write(tp, 0x15, 0x0235); ++ mdio_write(tp, 0x19, 0xb204); ++ mdio_write(tp, 0x15, 0x0236); ++ mdio_write(tp, 0x19, 0xb105); ++ mdio_write(tp, 0x15, 0x0237); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x0238); ++ mdio_write(tp, 0x19, 0x31c1); ++ mdio_write(tp, 0x15, 0x0239); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x023a); ++ mdio_write(tp, 0x19, 0x3261); ++ mdio_write(tp, 0x15, 0x023b); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x023c); ++ mdio_write(tp, 0x19, 0x3250); ++ mdio_write(tp, 0x15, 0x023d); ++ mdio_write(tp, 0x19, 0xb203); ++ mdio_write(tp, 0x15, 0x023e); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x023f); ++ mdio_write(tp, 0x19, 0x327a); ++ mdio_write(tp, 0x15, 0x0240); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x0241); ++ mdio_write(tp, 0x19, 0x3293); ++ mdio_write(tp, 0x15, 0x0242); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0243); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0244); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0245); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0246); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0247); ++ mdio_write(tp, 0x19, 0x32a3); ++ mdio_write(tp, 0x15, 0x0248); ++ mdio_write(tp, 0x19, 0x5520); ++ mdio_write(tp, 0x15, 0x0249); ++ mdio_write(tp, 0x19, 0x403d); ++ mdio_write(tp, 0x15, 0x024a); ++ mdio_write(tp, 0x19, 0x440c); ++ mdio_write(tp, 0x15, 0x024b); ++ mdio_write(tp, 0x19, 0x4812); ++ mdio_write(tp, 0x15, 0x024c); ++ mdio_write(tp, 0x19, 0x5001); ++ mdio_write(tp, 0x15, 0x024d); ++ mdio_write(tp, 0x19, 0x4802); ++ mdio_write(tp, 0x15, 0x024e); ++ mdio_write(tp, 0x19, 0x6880); ++ mdio_write(tp, 0x15, 0x024f); ++ mdio_write(tp, 0x19, 0x31f5); ++ mdio_write(tp, 0x15, 0x0250); ++ mdio_write(tp, 0x19, 0xb685); ++ mdio_write(tp, 0x15, 0x0251); ++ mdio_write(tp, 0x19, 0x801c); ++ mdio_write(tp, 0x15, 0x0252); ++ mdio_write(tp, 0x19, 0xbaf5); ++ mdio_write(tp, 0x15, 0x0253); ++ mdio_write(tp, 0x19, 0xc07c); ++ mdio_write(tp, 0x15, 0x0254); ++ mdio_write(tp, 0x19, 0x00fb); ++ mdio_write(tp, 0x15, 0x0255); ++ mdio_write(tp, 0x19, 0x325a); ++ mdio_write(tp, 0x15, 0x0256); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0257); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0258); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0259); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x025a); ++ mdio_write(tp, 0x19, 0x481a); ++ mdio_write(tp, 0x15, 0x025b); ++ mdio_write(tp, 0x19, 0x5001); ++ mdio_write(tp, 0x15, 0x025c); ++ mdio_write(tp, 0x19, 0x401b); ++ mdio_write(tp, 0x15, 0x025d); ++ mdio_write(tp, 0x19, 0x480a); ++ mdio_write(tp, 0x15, 0x025e); ++ mdio_write(tp, 0x19, 0x4418); ++ mdio_write(tp, 0x15, 0x025f); ++ mdio_write(tp, 0x19, 0x6900); ++ mdio_write(tp, 0x15, 0x0260); ++ mdio_write(tp, 0x19, 0x31f5); ++ mdio_write(tp, 0x15, 0x0261); ++ mdio_write(tp, 0x19, 0xb64b); ++ mdio_write(tp, 0x15, 0x0262); ++ mdio_write(tp, 0x19, 0xdb00); ++ mdio_write(tp, 0x15, 0x0263); ++ mdio_write(tp, 0x19, 0x0048); ++ mdio_write(tp, 0x15, 0x0264); ++ mdio_write(tp, 0x19, 0xdb7d); ++ mdio_write(tp, 0x15, 0x0265); ++ mdio_write(tp, 0x19, 0x0002); ++ mdio_write(tp, 0x15, 0x0266); ++ mdio_write(tp, 0x19, 0xa0fa); ++ mdio_write(tp, 0x15, 0x0267); ++ mdio_write(tp, 0x19, 0x4408); ++ mdio_write(tp, 0x15, 0x0268); ++ mdio_write(tp, 0x19, 0x3248); ++ mdio_write(tp, 0x15, 0x0269); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x026a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x026b); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x026c); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x026d); ++ mdio_write(tp, 0x19, 0xb806); ++ mdio_write(tp, 0x15, 0x026e); ++ mdio_write(tp, 0x19, 0x588d); ++ mdio_write(tp, 0x15, 0x026f); ++ mdio_write(tp, 0x19, 0x5500); ++ mdio_write(tp, 0x15, 0x0270); ++ mdio_write(tp, 0x19, 0x7801); ++ mdio_write(tp, 0x15, 0x0271); ++ mdio_write(tp, 0x19, 0x4002); ++ mdio_write(tp, 0x15, 0x0272); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x0273); ++ mdio_write(tp, 0x19, 0x4814); ++ mdio_write(tp, 0x15, 0x0274); ++ mdio_write(tp, 0x19, 0x500b); ++ mdio_write(tp, 0x15, 0x0275); ++ mdio_write(tp, 0x19, 0x4804); ++ mdio_write(tp, 0x15, 0x0276); ++ mdio_write(tp, 0x19, 0x40c4); ++ mdio_write(tp, 0x15, 0x0277); ++ mdio_write(tp, 0x19, 0x4425); ++ mdio_write(tp, 0x15, 0x0278); ++ mdio_write(tp, 0x19, 0x6a00); ++ mdio_write(tp, 0x15, 0x0279); ++ mdio_write(tp, 0x19, 0x31f5); ++ mdio_write(tp, 0x15, 0x027a); ++ mdio_write(tp, 0x19, 0xb632); ++ mdio_write(tp, 0x15, 0x027b); ++ mdio_write(tp, 0x19, 0xdc03); ++ mdio_write(tp, 0x15, 0x027c); ++ mdio_write(tp, 0x19, 0x0027); ++ mdio_write(tp, 0x15, 0x027d); ++ mdio_write(tp, 0x19, 0x80fc); ++ mdio_write(tp, 0x15, 0x027e); ++ mdio_write(tp, 0x19, 0x3283); ++ mdio_write(tp, 0x15, 0x027f); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0280); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0281); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0282); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0283); ++ mdio_write(tp, 0x19, 0xb806); ++ mdio_write(tp, 0x15, 0x0284); ++ mdio_write(tp, 0x19, 0x588f); ++ mdio_write(tp, 0x15, 0x0285); ++ mdio_write(tp, 0x19, 0x5520); ++ mdio_write(tp, 0x15, 0x0286); ++ mdio_write(tp, 0x19, 0x7801); ++ mdio_write(tp, 0x15, 0x0287); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x15, 0x0288); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x0289); ++ mdio_write(tp, 0x19, 0x4818); ++ mdio_write(tp, 0x15, 0x028a); ++ mdio_write(tp, 0x19, 0x5051); ++ mdio_write(tp, 0x15, 0x028b); ++ mdio_write(tp, 0x19, 0x4808); ++ mdio_write(tp, 0x15, 0x028c); ++ mdio_write(tp, 0x19, 0x4050); ++ mdio_write(tp, 0x15, 0x028d); ++ mdio_write(tp, 0x19, 0x4462); ++ mdio_write(tp, 0x15, 0x028e); ++ mdio_write(tp, 0x19, 0x40c4); ++ mdio_write(tp, 0x15, 0x028f); ++ mdio_write(tp, 0x19, 0x4473); ++ mdio_write(tp, 0x15, 0x0290); ++ mdio_write(tp, 0x19, 0x5041); ++ mdio_write(tp, 0x15, 0x0291); ++ mdio_write(tp, 0x19, 0x6b00); ++ mdio_write(tp, 0x15, 0x0292); ++ mdio_write(tp, 0x19, 0x31f5); ++ mdio_write(tp, 0x15, 0x0293); ++ mdio_write(tp, 0x19, 0xb619); ++ mdio_write(tp, 0x15, 0x0294); ++ mdio_write(tp, 0x19, 0x80d9); ++ mdio_write(tp, 0x15, 0x0295); ++ mdio_write(tp, 0x19, 0xbd06); ++ mdio_write(tp, 0x15, 0x0296); ++ mdio_write(tp, 0x19, 0xbb0d); ++ mdio_write(tp, 0x15, 0x0297); ++ mdio_write(tp, 0x19, 0xaf14); ++ mdio_write(tp, 0x15, 0x0298); ++ mdio_write(tp, 0x19, 0x8efa); ++ mdio_write(tp, 0x15, 0x0299); ++ mdio_write(tp, 0x19, 0x5049); ++ mdio_write(tp, 0x15, 0x029a); ++ mdio_write(tp, 0x19, 0x3248); ++ mdio_write(tp, 0x15, 0x029b); ++ mdio_write(tp, 0x19, 0x4c10); ++ mdio_write(tp, 0x15, 0x029c); ++ mdio_write(tp, 0x19, 0x44b0); ++ mdio_write(tp, 0x15, 0x029d); ++ mdio_write(tp, 0x19, 0x4c00); ++ mdio_write(tp, 0x15, 0x029e); ++ mdio_write(tp, 0x19, 0x3292); ++ mdio_write(tp, 0x15, 0x029f); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02a0); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02a1); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02a2); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02a3); ++ mdio_write(tp, 0x19, 0x481f); ++ mdio_write(tp, 0x15, 0x02a4); ++ mdio_write(tp, 0x19, 0x5005); ++ mdio_write(tp, 0x15, 0x02a5); ++ mdio_write(tp, 0x19, 0x480f); ++ mdio_write(tp, 0x15, 0x02a6); ++ mdio_write(tp, 0x19, 0xac00); ++ mdio_write(tp, 0x15, 0x02a7); ++ mdio_write(tp, 0x19, 0x31a6); ++ mdio_write(tp, 0x15, 0x02a8); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02a9); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02aa); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02ab); ++ mdio_write(tp, 0x19, 0x31ba); ++ mdio_write(tp, 0x15, 0x02ac); ++ mdio_write(tp, 0x19, 0x31d5); ++ mdio_write(tp, 0x15, 0x02ad); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02ae); ++ mdio_write(tp, 0x19, 0x5cf0); ++ mdio_write(tp, 0x15, 0x02af); ++ mdio_write(tp, 0x19, 0x588c); ++ mdio_write(tp, 0x15, 0x02b0); ++ mdio_write(tp, 0x19, 0x542f); ++ mdio_write(tp, 0x15, 0x02b1); ++ mdio_write(tp, 0x19, 0x7ffb); ++ mdio_write(tp, 0x15, 0x02b2); ++ mdio_write(tp, 0x19, 0x6ff8); ++ mdio_write(tp, 0x15, 0x02b3); ++ mdio_write(tp, 0x19, 0x64a4); ++ mdio_write(tp, 0x15, 0x02b4); ++ mdio_write(tp, 0x19, 0x64a0); ++ mdio_write(tp, 0x15, 0x02b5); ++ mdio_write(tp, 0x19, 0x6800); ++ mdio_write(tp, 0x15, 0x02b6); ++ mdio_write(tp, 0x19, 0x4400); ++ mdio_write(tp, 0x15, 0x02b7); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x02b8); ++ mdio_write(tp, 0x19, 0x4480); ++ mdio_write(tp, 0x15, 0x02b9); ++ mdio_write(tp, 0x19, 0x9e00); ++ mdio_write(tp, 0x15, 0x02ba); ++ mdio_write(tp, 0x19, 0x4891); ++ mdio_write(tp, 0x15, 0x02bb); ++ mdio_write(tp, 0x19, 0x4cc0); ++ mdio_write(tp, 0x15, 0x02bc); ++ mdio_write(tp, 0x19, 0x4801); ++ mdio_write(tp, 0x15, 0x02bd); ++ mdio_write(tp, 0x19, 0xa609); ++ mdio_write(tp, 0x15, 0x02be); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x02bf); ++ mdio_write(tp, 0x19, 0x004e); ++ mdio_write(tp, 0x15, 0x02c0); ++ mdio_write(tp, 0x19, 0x87fe); ++ mdio_write(tp, 0x15, 0x02c1); ++ mdio_write(tp, 0x19, 0x32c6); ++ mdio_write(tp, 0x15, 0x02c2); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02c3); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02c4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02c5); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02c6); ++ mdio_write(tp, 0x19, 0x48b2); ++ mdio_write(tp, 0x15, 0x02c7); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x02c8); ++ mdio_write(tp, 0x19, 0x4822); ++ mdio_write(tp, 0x15, 0x02c9); ++ mdio_write(tp, 0x19, 0x4488); ++ mdio_write(tp, 0x15, 0x02ca); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x02cb); ++ mdio_write(tp, 0x19, 0x0042); ++ mdio_write(tp, 0x15, 0x02cc); ++ mdio_write(tp, 0x19, 0x8203); ++ mdio_write(tp, 0x15, 0x02cd); ++ mdio_write(tp, 0x19, 0x4cc8); ++ mdio_write(tp, 0x15, 0x02ce); ++ mdio_write(tp, 0x19, 0x32d0); ++ mdio_write(tp, 0x15, 0x02cf); ++ mdio_write(tp, 0x19, 0x4cc0); ++ mdio_write(tp, 0x15, 0x02d0); ++ mdio_write(tp, 0x19, 0xc4d4); ++ mdio_write(tp, 0x15, 0x02d1); ++ mdio_write(tp, 0x19, 0x00f9); ++ mdio_write(tp, 0x15, 0x02d2); ++ mdio_write(tp, 0x19, 0xa51a); ++ mdio_write(tp, 0x15, 0x02d3); ++ mdio_write(tp, 0x19, 0x32d9); ++ mdio_write(tp, 0x15, 0x02d4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02d5); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02d6); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02d7); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02d8); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02d9); ++ mdio_write(tp, 0x19, 0x48b3); ++ mdio_write(tp, 0x15, 0x02da); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x02db); ++ mdio_write(tp, 0x19, 0x4823); ++ mdio_write(tp, 0x15, 0x02dc); ++ mdio_write(tp, 0x19, 0x4410); ++ mdio_write(tp, 0x15, 0x02dd); ++ mdio_write(tp, 0x19, 0xb630); ++ mdio_write(tp, 0x15, 0x02de); ++ mdio_write(tp, 0x19, 0x7dc8); ++ mdio_write(tp, 0x15, 0x02df); ++ mdio_write(tp, 0x19, 0x8203); ++ mdio_write(tp, 0x15, 0x02e0); ++ mdio_write(tp, 0x19, 0x4c48); ++ mdio_write(tp, 0x15, 0x02e1); ++ mdio_write(tp, 0x19, 0x32e3); ++ mdio_write(tp, 0x15, 0x02e2); ++ mdio_write(tp, 0x19, 0x4c40); ++ mdio_write(tp, 0x15, 0x02e3); ++ mdio_write(tp, 0x19, 0x9bfa); ++ mdio_write(tp, 0x15, 0x02e4); ++ mdio_write(tp, 0x19, 0x84ca); ++ mdio_write(tp, 0x15, 0x02e5); ++ mdio_write(tp, 0x19, 0x85f8); ++ mdio_write(tp, 0x15, 0x02e6); ++ mdio_write(tp, 0x19, 0x32ec); ++ mdio_write(tp, 0x15, 0x02e7); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02e8); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02e9); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02ea); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02eb); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x02ec); ++ mdio_write(tp, 0x19, 0x48d4); ++ mdio_write(tp, 0x15, 0x02ed); ++ mdio_write(tp, 0x19, 0x4020); ++ mdio_write(tp, 0x15, 0x02ee); ++ mdio_write(tp, 0x19, 0x4844); ++ mdio_write(tp, 0x15, 0x02ef); ++ mdio_write(tp, 0x19, 0x4420); ++ mdio_write(tp, 0x15, 0x02f0); ++ mdio_write(tp, 0x19, 0x6800); ++ mdio_write(tp, 0x15, 0x02f1); ++ mdio_write(tp, 0x19, 0x7dc0); ++ mdio_write(tp, 0x15, 0x02f2); ++ mdio_write(tp, 0x19, 0x4c40); ++ mdio_write(tp, 0x15, 0x02f3); ++ mdio_write(tp, 0x19, 0x7c0b); ++ mdio_write(tp, 0x15, 0x02f4); ++ mdio_write(tp, 0x19, 0x6c08); ++ mdio_write(tp, 0x15, 0x02f5); ++ mdio_write(tp, 0x19, 0x3311); ++ mdio_write(tp, 0x15, 0x02f6); ++ mdio_write(tp, 0x19, 0x9cfd); ++ mdio_write(tp, 0x15, 0x02f7); ++ mdio_write(tp, 0x19, 0xb616); ++ mdio_write(tp, 0x15, 0x02f8); ++ mdio_write(tp, 0x19, 0xc42b); ++ mdio_write(tp, 0x15, 0x02f9); ++ mdio_write(tp, 0x19, 0x00e0); ++ mdio_write(tp, 0x15, 0x02fa); ++ mdio_write(tp, 0x19, 0xc455); ++ mdio_write(tp, 0x15, 0x02fb); ++ mdio_write(tp, 0x19, 0x00b3); ++ mdio_write(tp, 0x15, 0x02fc); ++ mdio_write(tp, 0x19, 0xb20a); ++ mdio_write(tp, 0x15, 0x02fd); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x02fe); ++ mdio_write(tp, 0x19, 0x6c02); ++ mdio_write(tp, 0x15, 0x02ff); ++ mdio_write(tp, 0x19, 0x8204); ++ mdio_write(tp, 0x15, 0x0300); ++ mdio_write(tp, 0x19, 0x7c04); ++ mdio_write(tp, 0x15, 0x0301); ++ mdio_write(tp, 0x19, 0x7404); ++ mdio_write(tp, 0x15, 0x0302); ++ mdio_write(tp, 0x19, 0x32f3); ++ mdio_write(tp, 0x15, 0x0303); ++ mdio_write(tp, 0x19, 0x7c04); ++ mdio_write(tp, 0x15, 0x0304); ++ mdio_write(tp, 0x19, 0x7400); ++ mdio_write(tp, 0x15, 0x0305); ++ mdio_write(tp, 0x19, 0x32f3); ++ mdio_write(tp, 0x15, 0x0306); ++ mdio_write(tp, 0x19, 0xefed); ++ mdio_write(tp, 0x15, 0x0307); ++ mdio_write(tp, 0x19, 0x3342); ++ mdio_write(tp, 0x15, 0x0308); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0309); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x030a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x030b); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x030c); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x030d); ++ mdio_write(tp, 0x19, 0x3006); ++ mdio_write(tp, 0x15, 0x030e); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x030f); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0310); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0311); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x0312); ++ mdio_write(tp, 0x19, 0xa207); ++ mdio_write(tp, 0x15, 0x0313); ++ mdio_write(tp, 0x19, 0x4c00); ++ mdio_write(tp, 0x15, 0x0314); ++ mdio_write(tp, 0x19, 0x3322); ++ mdio_write(tp, 0x15, 0x0315); ++ mdio_write(tp, 0x19, 0x4041); ++ mdio_write(tp, 0x15, 0x0316); ++ mdio_write(tp, 0x19, 0x7d07); ++ mdio_write(tp, 0x15, 0x0317); ++ mdio_write(tp, 0x19, 0x4502); ++ mdio_write(tp, 0x15, 0x0318); ++ mdio_write(tp, 0x19, 0x3322); ++ mdio_write(tp, 0x15, 0x0319); ++ mdio_write(tp, 0x19, 0x4c08); ++ mdio_write(tp, 0x15, 0x031a); ++ mdio_write(tp, 0x19, 0x3322); ++ mdio_write(tp, 0x15, 0x031b); ++ mdio_write(tp, 0x19, 0x7d80); ++ mdio_write(tp, 0x15, 0x031c); ++ mdio_write(tp, 0x19, 0x5180); ++ mdio_write(tp, 0x15, 0x031d); ++ mdio_write(tp, 0x19, 0x3320); ++ mdio_write(tp, 0x15, 0x031e); ++ mdio_write(tp, 0x19, 0x7d80); ++ mdio_write(tp, 0x15, 0x031f); ++ mdio_write(tp, 0x19, 0x5000); ++ mdio_write(tp, 0x15, 0x0320); ++ mdio_write(tp, 0x19, 0x7d07); ++ mdio_write(tp, 0x15, 0x0321); ++ mdio_write(tp, 0x19, 0x4402); ++ mdio_write(tp, 0x15, 0x0322); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0323); ++ mdio_write(tp, 0x19, 0x6c02); ++ mdio_write(tp, 0x15, 0x0324); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x0325); ++ mdio_write(tp, 0x19, 0xb30c); ++ mdio_write(tp, 0x15, 0x0326); ++ mdio_write(tp, 0x19, 0xb206); ++ mdio_write(tp, 0x15, 0x0327); ++ mdio_write(tp, 0x19, 0xb103); ++ mdio_write(tp, 0x15, 0x0328); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x0329); ++ mdio_write(tp, 0x19, 0x32f6); ++ mdio_write(tp, 0x15, 0x032a); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x032b); ++ mdio_write(tp, 0x19, 0x3352); ++ mdio_write(tp, 0x15, 0x032c); ++ mdio_write(tp, 0x19, 0xb103); ++ mdio_write(tp, 0x15, 0x032d); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x032e); ++ mdio_write(tp, 0x19, 0x336a); ++ mdio_write(tp, 0x15, 0x032f); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x0330); ++ mdio_write(tp, 0x19, 0x3382); ++ mdio_write(tp, 0x15, 0x0331); ++ mdio_write(tp, 0x19, 0xb206); ++ mdio_write(tp, 0x15, 0x0332); ++ mdio_write(tp, 0x19, 0xb103); ++ mdio_write(tp, 0x15, 0x0333); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x0334); ++ mdio_write(tp, 0x19, 0x3395); ++ mdio_write(tp, 0x15, 0x0335); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x0336); ++ mdio_write(tp, 0x19, 0x33c6); ++ mdio_write(tp, 0x15, 0x0337); ++ mdio_write(tp, 0x19, 0xb103); ++ mdio_write(tp, 0x15, 0x0338); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x0339); ++ mdio_write(tp, 0x19, 0x33d7); ++ mdio_write(tp, 0x15, 0x033a); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x033b); ++ mdio_write(tp, 0x19, 0x33f2); ++ mdio_write(tp, 0x15, 0x033c); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x033d); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x033e); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x033f); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0340); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0341); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0342); ++ mdio_write(tp, 0x19, 0x49b5); ++ mdio_write(tp, 0x15, 0x0343); ++ mdio_write(tp, 0x19, 0x7d00); ++ mdio_write(tp, 0x15, 0x0344); ++ mdio_write(tp, 0x19, 0x4d00); ++ mdio_write(tp, 0x15, 0x0345); ++ mdio_write(tp, 0x19, 0x6880); ++ mdio_write(tp, 0x15, 0x0346); ++ mdio_write(tp, 0x19, 0x7c08); ++ mdio_write(tp, 0x15, 0x0347); ++ mdio_write(tp, 0x19, 0x6c08); ++ mdio_write(tp, 0x15, 0x0348); ++ mdio_write(tp, 0x19, 0x4925); ++ mdio_write(tp, 0x15, 0x0349); ++ mdio_write(tp, 0x19, 0x403b); ++ mdio_write(tp, 0x15, 0x034a); ++ mdio_write(tp, 0x19, 0xa602); ++ mdio_write(tp, 0x15, 0x034b); ++ mdio_write(tp, 0x19, 0x402f); ++ mdio_write(tp, 0x15, 0x034c); ++ mdio_write(tp, 0x19, 0x4484); ++ mdio_write(tp, 0x15, 0x034d); ++ mdio_write(tp, 0x19, 0x40c8); ++ mdio_write(tp, 0x15, 0x034e); ++ mdio_write(tp, 0x19, 0x44c4); ++ mdio_write(tp, 0x15, 0x034f); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x0350); ++ mdio_write(tp, 0x19, 0x00bd); ++ mdio_write(tp, 0x15, 0x0351); ++ mdio_write(tp, 0x19, 0x3311); ++ mdio_write(tp, 0x15, 0x0352); ++ mdio_write(tp, 0x19, 0xc8ed); ++ mdio_write(tp, 0x15, 0x0353); ++ mdio_write(tp, 0x19, 0x00fc); ++ mdio_write(tp, 0x15, 0x0354); ++ mdio_write(tp, 0x19, 0x8221); ++ mdio_write(tp, 0x15, 0x0355); ++ mdio_write(tp, 0x19, 0xd11d); ++ mdio_write(tp, 0x15, 0x0356); ++ mdio_write(tp, 0x19, 0x001f); ++ mdio_write(tp, 0x15, 0x0357); ++ mdio_write(tp, 0x19, 0xde18); ++ mdio_write(tp, 0x15, 0x0358); ++ mdio_write(tp, 0x19, 0x0008); ++ mdio_write(tp, 0x15, 0x0359); ++ mdio_write(tp, 0x19, 0x91f6); ++ mdio_write(tp, 0x15, 0x035a); ++ mdio_write(tp, 0x19, 0x3360); ++ mdio_write(tp, 0x15, 0x035b); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x035c); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x035d); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x035e); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x035f); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0360); ++ mdio_write(tp, 0x19, 0x4bb6); ++ mdio_write(tp, 0x15, 0x0361); ++ mdio_write(tp, 0x19, 0x4064); ++ mdio_write(tp, 0x15, 0x0362); ++ mdio_write(tp, 0x19, 0x4b26); ++ mdio_write(tp, 0x15, 0x0363); ++ mdio_write(tp, 0x19, 0x4410); ++ mdio_write(tp, 0x15, 0x0364); ++ mdio_write(tp, 0x19, 0x4006); ++ mdio_write(tp, 0x15, 0x0365); ++ mdio_write(tp, 0x19, 0x4490); ++ mdio_write(tp, 0x15, 0x0366); ++ mdio_write(tp, 0x19, 0x6900); ++ mdio_write(tp, 0x15, 0x0367); ++ mdio_write(tp, 0x19, 0xb6a6); ++ mdio_write(tp, 0x15, 0x0368); ++ mdio_write(tp, 0x19, 0x9e02); ++ mdio_write(tp, 0x15, 0x0369); ++ mdio_write(tp, 0x19, 0x3311); ++ mdio_write(tp, 0x15, 0x036a); ++ mdio_write(tp, 0x19, 0xd11d); ++ mdio_write(tp, 0x15, 0x036b); ++ mdio_write(tp, 0x19, 0x000a); ++ mdio_write(tp, 0x15, 0x036c); ++ mdio_write(tp, 0x19, 0xbb0f); ++ mdio_write(tp, 0x15, 0x036d); ++ mdio_write(tp, 0x19, 0x8102); ++ mdio_write(tp, 0x15, 0x036e); ++ mdio_write(tp, 0x19, 0x3371); ++ mdio_write(tp, 0x15, 0x036f); ++ mdio_write(tp, 0x19, 0xa21e); ++ mdio_write(tp, 0x15, 0x0370); ++ mdio_write(tp, 0x19, 0x33b6); ++ mdio_write(tp, 0x15, 0x0371); ++ mdio_write(tp, 0x19, 0x91f6); ++ mdio_write(tp, 0x15, 0x0372); ++ mdio_write(tp, 0x19, 0xc218); ++ mdio_write(tp, 0x15, 0x0373); ++ mdio_write(tp, 0x19, 0x00f4); ++ mdio_write(tp, 0x15, 0x0374); ++ mdio_write(tp, 0x19, 0x33b6); ++ mdio_write(tp, 0x15, 0x0375); ++ mdio_write(tp, 0x19, 0x32ec); ++ mdio_write(tp, 0x15, 0x0376); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0377); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0378); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x0379); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x037a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x037b); ++ mdio_write(tp, 0x19, 0x4b97); ++ mdio_write(tp, 0x15, 0x037c); ++ mdio_write(tp, 0x19, 0x402b); ++ mdio_write(tp, 0x15, 0x037d); ++ mdio_write(tp, 0x19, 0x4b07); ++ mdio_write(tp, 0x15, 0x037e); ++ mdio_write(tp, 0x19, 0x4422); ++ mdio_write(tp, 0x15, 0x037f); ++ mdio_write(tp, 0x19, 0x6980); ++ mdio_write(tp, 0x15, 0x0380); ++ mdio_write(tp, 0x19, 0xb608); ++ mdio_write(tp, 0x15, 0x0381); ++ mdio_write(tp, 0x19, 0x3311); ++ mdio_write(tp, 0x15, 0x0382); ++ mdio_write(tp, 0x19, 0xbc05); ++ mdio_write(tp, 0x15, 0x0383); ++ mdio_write(tp, 0x19, 0xc21c); ++ mdio_write(tp, 0x15, 0x0384); ++ mdio_write(tp, 0x19, 0x0032); ++ mdio_write(tp, 0x15, 0x0385); ++ mdio_write(tp, 0x19, 0xa1fb); ++ mdio_write(tp, 0x15, 0x0386); ++ mdio_write(tp, 0x19, 0x338d); ++ mdio_write(tp, 0x15, 0x0387); ++ mdio_write(tp, 0x19, 0x32ae); ++ mdio_write(tp, 0x15, 0x0388); ++ mdio_write(tp, 0x19, 0x330d); ++ mdio_write(tp, 0x15, 0x0389); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x038a); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x038b); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x038c); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x038d); ++ mdio_write(tp, 0x19, 0x4b97); ++ mdio_write(tp, 0x15, 0x038e); ++ mdio_write(tp, 0x19, 0x6a08); ++ mdio_write(tp, 0x15, 0x038f); ++ mdio_write(tp, 0x19, 0x4b07); ++ mdio_write(tp, 0x15, 0x0390); ++ mdio_write(tp, 0x19, 0x40ac); ++ mdio_write(tp, 0x15, 0x0391); ++ mdio_write(tp, 0x19, 0x4445); ++ mdio_write(tp, 0x15, 0x0392); ++ mdio_write(tp, 0x19, 0x404e); ++ mdio_write(tp, 0x15, 0x0393); ++ mdio_write(tp, 0x19, 0x4461); ++ mdio_write(tp, 0x15, 0x0394); ++ mdio_write(tp, 0x19, 0x3311); ++ mdio_write(tp, 0x15, 0x0395); ++ mdio_write(tp, 0x19, 0x9c0a); ++ mdio_write(tp, 0x15, 0x0396); ++ mdio_write(tp, 0x19, 0x63da); ++ mdio_write(tp, 0x15, 0x0397); ++ mdio_write(tp, 0x19, 0x6f0c); ++ mdio_write(tp, 0x15, 0x0398); ++ mdio_write(tp, 0x19, 0x5440); ++ mdio_write(tp, 0x15, 0x0399); ++ mdio_write(tp, 0x19, 0x4b98); ++ mdio_write(tp, 0x15, 0x039a); ++ mdio_write(tp, 0x19, 0x7c40); ++ mdio_write(tp, 0x15, 0x039b); ++ mdio_write(tp, 0x19, 0x4c00); ++ mdio_write(tp, 0x15, 0x039c); ++ mdio_write(tp, 0x19, 0x4b08); ++ mdio_write(tp, 0x15, 0x039d); ++ mdio_write(tp, 0x19, 0x63d8); ++ mdio_write(tp, 0x15, 0x039e); ++ mdio_write(tp, 0x19, 0x33a5); ++ mdio_write(tp, 0x15, 0x039f); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x03a0); ++ mdio_write(tp, 0x19, 0x00e8); ++ mdio_write(tp, 0x15, 0x03a1); ++ mdio_write(tp, 0x19, 0x820e); ++ mdio_write(tp, 0x15, 0x03a2); ++ mdio_write(tp, 0x19, 0xa10d); ++ mdio_write(tp, 0x15, 0x03a3); ++ mdio_write(tp, 0x19, 0x9df1); ++ mdio_write(tp, 0x15, 0x03a4); ++ mdio_write(tp, 0x19, 0x33af); ++ mdio_write(tp, 0x15, 0x03a5); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x03a6); ++ mdio_write(tp, 0x19, 0x00f9); ++ mdio_write(tp, 0x15, 0x03a7); ++ mdio_write(tp, 0x19, 0xc017); ++ mdio_write(tp, 0x15, 0x03a8); ++ mdio_write(tp, 0x19, 0x0007); ++ mdio_write(tp, 0x15, 0x03a9); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x03aa); ++ mdio_write(tp, 0x19, 0x6c03); ++ mdio_write(tp, 0x15, 0x03ab); ++ mdio_write(tp, 0x19, 0xa104); ++ mdio_write(tp, 0x15, 0x03ac); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x03ad); ++ mdio_write(tp, 0x19, 0x6c00); ++ mdio_write(tp, 0x15, 0x03ae); ++ mdio_write(tp, 0x19, 0x9df7); ++ mdio_write(tp, 0x15, 0x03af); ++ mdio_write(tp, 0x19, 0x7c03); ++ mdio_write(tp, 0x15, 0x03b0); ++ mdio_write(tp, 0x19, 0x6c08); ++ mdio_write(tp, 0x15, 0x03b1); ++ mdio_write(tp, 0x19, 0x33b6); ++ mdio_write(tp, 0x15, 0x03b2); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03b3); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03b4); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03b5); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03b6); ++ mdio_write(tp, 0x19, 0x55af); ++ mdio_write(tp, 0x15, 0x03b7); ++ mdio_write(tp, 0x19, 0x7ff0); ++ mdio_write(tp, 0x15, 0x03b8); ++ mdio_write(tp, 0x19, 0x6ff0); ++ mdio_write(tp, 0x15, 0x03b9); ++ mdio_write(tp, 0x19, 0x4bb9); ++ mdio_write(tp, 0x15, 0x03ba); ++ mdio_write(tp, 0x19, 0x6a80); ++ mdio_write(tp, 0x15, 0x03bb); ++ mdio_write(tp, 0x19, 0x4b29); ++ mdio_write(tp, 0x15, 0x03bc); ++ mdio_write(tp, 0x19, 0x4041); ++ mdio_write(tp, 0x15, 0x03bd); ++ mdio_write(tp, 0x19, 0x440a); ++ mdio_write(tp, 0x15, 0x03be); ++ mdio_write(tp, 0x19, 0x4029); ++ mdio_write(tp, 0x15, 0x03bf); ++ mdio_write(tp, 0x19, 0x4418); ++ mdio_write(tp, 0x15, 0x03c0); ++ mdio_write(tp, 0x19, 0x4090); ++ mdio_write(tp, 0x15, 0x03c1); ++ mdio_write(tp, 0x19, 0x4438); ++ mdio_write(tp, 0x15, 0x03c2); ++ mdio_write(tp, 0x19, 0x40c4); ++ mdio_write(tp, 0x15, 0x03c3); ++ mdio_write(tp, 0x19, 0x447b); ++ mdio_write(tp, 0x15, 0x03c4); ++ mdio_write(tp, 0x19, 0xb6c4); ++ mdio_write(tp, 0x15, 0x03c5); ++ mdio_write(tp, 0x19, 0x3311); ++ mdio_write(tp, 0x15, 0x03c6); ++ mdio_write(tp, 0x19, 0x9bfe); ++ mdio_write(tp, 0x15, 0x03c7); ++ mdio_write(tp, 0x19, 0x33cc); ++ mdio_write(tp, 0x15, 0x03c8); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03c9); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03ca); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03cb); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03cc); ++ mdio_write(tp, 0x19, 0x542f); ++ mdio_write(tp, 0x15, 0x03cd); ++ mdio_write(tp, 0x19, 0x499a); ++ mdio_write(tp, 0x15, 0x03ce); ++ mdio_write(tp, 0x19, 0x7c40); ++ mdio_write(tp, 0x15, 0x03cf); ++ mdio_write(tp, 0x19, 0x4c40); ++ mdio_write(tp, 0x15, 0x03d0); ++ mdio_write(tp, 0x19, 0x490a); ++ mdio_write(tp, 0x15, 0x03d1); ++ mdio_write(tp, 0x19, 0x405e); ++ mdio_write(tp, 0x15, 0x03d2); ++ mdio_write(tp, 0x19, 0x44f8); ++ mdio_write(tp, 0x15, 0x03d3); ++ mdio_write(tp, 0x19, 0x6b00); ++ mdio_write(tp, 0x15, 0x03d4); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x03d5); ++ mdio_write(tp, 0x19, 0x0028); ++ mdio_write(tp, 0x15, 0x03d6); ++ mdio_write(tp, 0x19, 0x3311); ++ mdio_write(tp, 0x15, 0x03d7); ++ mdio_write(tp, 0x19, 0xbd27); ++ mdio_write(tp, 0x15, 0x03d8); ++ mdio_write(tp, 0x19, 0x9cfc); ++ mdio_write(tp, 0x15, 0x03d9); ++ mdio_write(tp, 0x19, 0xc639); ++ mdio_write(tp, 0x15, 0x03da); ++ mdio_write(tp, 0x19, 0x000f); ++ mdio_write(tp, 0x15, 0x03db); ++ mdio_write(tp, 0x19, 0x9e03); ++ mdio_write(tp, 0x15, 0x03dc); ++ mdio_write(tp, 0x19, 0x7c01); ++ mdio_write(tp, 0x15, 0x03dd); ++ mdio_write(tp, 0x19, 0x4c01); ++ mdio_write(tp, 0x15, 0x03de); ++ mdio_write(tp, 0x19, 0x9af6); ++ mdio_write(tp, 0x15, 0x03df); ++ mdio_write(tp, 0x19, 0x7c12); ++ mdio_write(tp, 0x15, 0x03e0); ++ mdio_write(tp, 0x19, 0x4c52); ++ mdio_write(tp, 0x15, 0x03e1); ++ mdio_write(tp, 0x19, 0x4470); ++ mdio_write(tp, 0x15, 0x03e2); ++ mdio_write(tp, 0x19, 0x7c12); ++ mdio_write(tp, 0x15, 0x03e3); ++ mdio_write(tp, 0x19, 0x4c40); ++ mdio_write(tp, 0x15, 0x03e4); ++ mdio_write(tp, 0x19, 0x33d4); ++ mdio_write(tp, 0x15, 0x03e5); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03e6); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03e7); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03e8); ++ mdio_write(tp, 0x19, 0x0000); ++ mdio_write(tp, 0x15, 0x03e9); ++ mdio_write(tp, 0x19, 0x49bb); ++ mdio_write(tp, 0x15, 0x03ea); ++ mdio_write(tp, 0x19, 0x4478); ++ mdio_write(tp, 0x15, 0x03eb); ++ mdio_write(tp, 0x19, 0x492b); ++ mdio_write(tp, 0x15, 0x03ec); ++ mdio_write(tp, 0x19, 0x6b80); ++ mdio_write(tp, 0x15, 0x03ed); ++ mdio_write(tp, 0x19, 0x7c01); ++ mdio_write(tp, 0x15, 0x03ee); ++ mdio_write(tp, 0x19, 0x4c00); ++ mdio_write(tp, 0x15, 0x03ef); ++ mdio_write(tp, 0x19, 0xd64f); ++ mdio_write(tp, 0x15, 0x03f0); ++ mdio_write(tp, 0x19, 0x000d); ++ mdio_write(tp, 0x15, 0x03f1); ++ mdio_write(tp, 0x19, 0x3311); ++ mdio_write(tp, 0x15, 0x03f2); ++ mdio_write(tp, 0x19, 0xbd0c); ++ mdio_write(tp, 0x15, 0x03f3); ++ mdio_write(tp, 0x19, 0xc428); ++ mdio_write(tp, 0x15, 0x03f4); ++ mdio_write(tp, 0x19, 0x0008); ++ mdio_write(tp, 0x15, 0x03f5); ++ mdio_write(tp, 0x19, 0x9afa); ++ mdio_write(tp, 0x15, 0x03f6); ++ mdio_write(tp, 0x19, 0x7c12); ++ mdio_write(tp, 0x15, 0x03f7); ++ mdio_write(tp, 0x19, 0x4c52); ++ mdio_write(tp, 0x15, 0x03f8); ++ mdio_write(tp, 0x19, 0x4470); ++ mdio_write(tp, 0x15, 0x03f9); ++ mdio_write(tp, 0x19, 0x7c12); ++ mdio_write(tp, 0x15, 0x03fa); ++ mdio_write(tp, 0x19, 0x4c40); ++ mdio_write(tp, 0x15, 0x03fb); ++ mdio_write(tp, 0x19, 0x33ef); ++ mdio_write(tp, 0x15, 0x03fc); ++ mdio_write(tp, 0x19, 0x3342); ++ mdio_write(tp, 0x15, 0x03fd); ++ mdio_write(tp, 0x19, 0x330d); ++ mdio_write(tp, 0x15, 0x03fe); ++ mdio_write(tp, 0x19, 0x32ae); ++ mdio_write(tp, 0x15, 0x0000); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0300); ++ mdio_write(tp, 0x1f, 0x0002); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x05, 0x8000); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0x48f7); ++ mdio_write(tp, 0x06, 0x00e0); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0xa080); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0xf602); ++ mdio_write(tp, 0x06, 0x0112); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x1f02); ++ mdio_write(tp, 0x06, 0x012c); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x3c02); ++ mdio_write(tp, 0x06, 0x0156); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x6d02); ++ mdio_write(tp, 0x06, 0x809d); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x88e1); ++ mdio_write(tp, 0x06, 0x8b89); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8a1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8b); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8c1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8e1e); ++ mdio_write(tp, 0x06, 0x01a0); ++ mdio_write(tp, 0x06, 0x00c7); ++ mdio_write(tp, 0x06, 0xaebb); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xc702); ++ mdio_write(tp, 0x06, 0x320a); ++ mdio_write(tp, 0x06, 0xd105); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xcd02); ++ mdio_write(tp, 0x06, 0x320a); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xca02); ++ mdio_write(tp, 0x06, 0x320a); ++ mdio_write(tp, 0x06, 0xd105); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xd002); ++ mdio_write(tp, 0x06, 0x320a); ++ mdio_write(tp, 0x06, 0xd481); ++ mdio_write(tp, 0x06, 0xc9e4); ++ mdio_write(tp, 0x06, 0x8b90); ++ mdio_write(tp, 0x06, 0xe58b); ++ mdio_write(tp, 0x06, 0x91d4); ++ mdio_write(tp, 0x06, 0x81b8); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x92e5); ++ mdio_write(tp, 0x06, 0x8b93); ++ mdio_write(tp, 0x06, 0xbf8b); ++ mdio_write(tp, 0x06, 0x88ec); ++ mdio_write(tp, 0x06, 0x0019); ++ mdio_write(tp, 0x06, 0xa98b); ++ mdio_write(tp, 0x06, 0x90f9); ++ mdio_write(tp, 0x06, 0xeeff); ++ mdio_write(tp, 0x06, 0xf600); ++ mdio_write(tp, 0x06, 0xeeff); ++ mdio_write(tp, 0x06, 0xf7fc); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xc102); ++ mdio_write(tp, 0x06, 0x320a); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xc402); ++ mdio_write(tp, 0x06, 0x320a); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x201a); ++ mdio_write(tp, 0x06, 0xf620); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x824b); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0x1902); ++ mdio_write(tp, 0x06, 0x2c9d); ++ mdio_write(tp, 0x06, 0x0203); ++ mdio_write(tp, 0x06, 0x9602); ++ mdio_write(tp, 0x06, 0x0473); ++ mdio_write(tp, 0x06, 0x022e); ++ mdio_write(tp, 0x06, 0x3902); ++ mdio_write(tp, 0x06, 0x044d); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x210b); ++ mdio_write(tp, 0x06, 0xf621); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x0416); ++ mdio_write(tp, 0x06, 0x021b); ++ mdio_write(tp, 0x06, 0xa4e0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad22); ++ mdio_write(tp, 0x06, 0x05f6); ++ mdio_write(tp, 0x06, 0x22e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2305); ++ mdio_write(tp, 0x06, 0xf623); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8ee0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad24); ++ mdio_write(tp, 0x06, 0x05f6); ++ mdio_write(tp, 0x06, 0x24e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2505); ++ mdio_write(tp, 0x06, 0xf625); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8ee0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad26); ++ mdio_write(tp, 0x06, 0x08f6); ++ mdio_write(tp, 0x06, 0x26e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0xdae0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad27); ++ mdio_write(tp, 0x06, 0x05f6); ++ mdio_write(tp, 0x06, 0x27e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x0203); ++ mdio_write(tp, 0x06, 0x5cfc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69e0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xad21); ++ mdio_write(tp, 0x06, 0x57e0); ++ mdio_write(tp, 0x06, 0xe022); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x2358); ++ mdio_write(tp, 0x06, 0xc059); ++ mdio_write(tp, 0x06, 0x021e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b3c); ++ mdio_write(tp, 0x06, 0x1f10); ++ mdio_write(tp, 0x06, 0x9e44); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x3cad); ++ mdio_write(tp, 0x06, 0x211d); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x84f7); ++ mdio_write(tp, 0x06, 0x29e5); ++ mdio_write(tp, 0x06, 0x8b84); ++ mdio_write(tp, 0x06, 0xac27); ++ mdio_write(tp, 0x06, 0x0dac); ++ mdio_write(tp, 0x06, 0x2605); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0x7fae); ++ mdio_write(tp, 0x06, 0x2b02); ++ mdio_write(tp, 0x06, 0x2c23); ++ mdio_write(tp, 0x06, 0xae26); ++ mdio_write(tp, 0x06, 0x022c); ++ mdio_write(tp, 0x06, 0x41ae); ++ mdio_write(tp, 0x06, 0x21e0); ++ mdio_write(tp, 0x06, 0x8b87); ++ mdio_write(tp, 0x06, 0xad22); ++ mdio_write(tp, 0x06, 0x18e0); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0x58fc); ++ mdio_write(tp, 0x06, 0xe4ff); ++ mdio_write(tp, 0x06, 0xf7d1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x2eee); ++ mdio_write(tp, 0x06, 0x0232); ++ mdio_write(tp, 0x06, 0x0ad1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x82e8); ++ mdio_write(tp, 0x06, 0x0232); ++ mdio_write(tp, 0x06, 0x0a02); ++ mdio_write(tp, 0x06, 0x2bdf); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfefc); ++ mdio_write(tp, 0x06, 0x04d0); ++ mdio_write(tp, 0x06, 0x0202); ++ mdio_write(tp, 0x06, 0x1e97); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x87ad); ++ mdio_write(tp, 0x06, 0x2228); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xd302); ++ mdio_write(tp, 0x06, 0x320a); ++ mdio_write(tp, 0x06, 0xd10c); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xd602); ++ mdio_write(tp, 0x06, 0x320a); ++ mdio_write(tp, 0x06, 0xd104); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xd902); ++ mdio_write(tp, 0x06, 0x320a); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xe802); ++ mdio_write(tp, 0x06, 0x320a); ++ mdio_write(tp, 0x06, 0xe0ff); ++ mdio_write(tp, 0x06, 0xf768); ++ mdio_write(tp, 0x06, 0x03e4); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0xd004); ++ mdio_write(tp, 0x06, 0x0228); ++ mdio_write(tp, 0x06, 0x7a04); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0xe234); ++ mdio_write(tp, 0x06, 0xe1e2); ++ mdio_write(tp, 0x06, 0x35f6); ++ mdio_write(tp, 0x06, 0x2be4); ++ mdio_write(tp, 0x06, 0xe234); ++ mdio_write(tp, 0x06, 0xe5e2); ++ mdio_write(tp, 0x06, 0x35fc); ++ mdio_write(tp, 0x06, 0x05f8); ++ mdio_write(tp, 0x06, 0xe0e2); ++ mdio_write(tp, 0x06, 0x34e1); ++ mdio_write(tp, 0x06, 0xe235); ++ mdio_write(tp, 0x06, 0xf72b); ++ mdio_write(tp, 0x06, 0xe4e2); ++ mdio_write(tp, 0x06, 0x34e5); ++ mdio_write(tp, 0x06, 0xe235); ++ mdio_write(tp, 0x06, 0xfc05); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69ac); ++ mdio_write(tp, 0x06, 0x1b4c); ++ mdio_write(tp, 0x06, 0xbf2e); ++ mdio_write(tp, 0x06, 0x3002); ++ mdio_write(tp, 0x06, 0x31dd); ++ mdio_write(tp, 0x06, 0xef01); ++ mdio_write(tp, 0x06, 0xe28a); ++ mdio_write(tp, 0x06, 0x76e4); ++ mdio_write(tp, 0x06, 0x8a76); ++ mdio_write(tp, 0x06, 0x1f12); ++ mdio_write(tp, 0x06, 0x9e3a); ++ mdio_write(tp, 0x06, 0xef12); ++ mdio_write(tp, 0x06, 0x5907); ++ mdio_write(tp, 0x06, 0x9f12); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b40); ++ mdio_write(tp, 0x06, 0xf721); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x40d0); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x287a); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0x34fc); ++ mdio_write(tp, 0x06, 0xa000); ++ mdio_write(tp, 0x06, 0x1002); ++ mdio_write(tp, 0x06, 0x2dc3); ++ mdio_write(tp, 0x06, 0x022e); ++ mdio_write(tp, 0x06, 0x21e0); ++ mdio_write(tp, 0x06, 0x8b40); ++ mdio_write(tp, 0x06, 0xf621); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x40ae); ++ mdio_write(tp, 0x06, 0x0fbf); ++ mdio_write(tp, 0x06, 0x3fa5); ++ mdio_write(tp, 0x06, 0x0231); ++ mdio_write(tp, 0x06, 0x6cbf); ++ mdio_write(tp, 0x06, 0x3fa2); ++ mdio_write(tp, 0x06, 0x0231); ++ mdio_write(tp, 0x06, 0x6c02); ++ mdio_write(tp, 0x06, 0x2dc3); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfefd); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0xe2f4); ++ mdio_write(tp, 0x06, 0xe1e2); ++ mdio_write(tp, 0x06, 0xf5e4); ++ mdio_write(tp, 0x06, 0x8a78); ++ mdio_write(tp, 0x06, 0xe58a); ++ mdio_write(tp, 0x06, 0x79ee); ++ mdio_write(tp, 0x06, 0xe2f4); ++ mdio_write(tp, 0x06, 0xd8ee); ++ mdio_write(tp, 0x06, 0xe2f5); ++ mdio_write(tp, 0x06, 0x20fc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xf9fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x87ad); ++ mdio_write(tp, 0x06, 0x2065); ++ mdio_write(tp, 0x06, 0xd200); ++ mdio_write(tp, 0x06, 0xbf2e); ++ mdio_write(tp, 0x06, 0xe802); ++ mdio_write(tp, 0x06, 0x31dd); ++ mdio_write(tp, 0x06, 0x1e21); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xdf02); ++ mdio_write(tp, 0x06, 0x31dd); ++ mdio_write(tp, 0x06, 0x0c11); ++ mdio_write(tp, 0x06, 0x1e21); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xe202); ++ mdio_write(tp, 0x06, 0x31dd); ++ mdio_write(tp, 0x06, 0x0c12); ++ mdio_write(tp, 0x06, 0x1e21); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xe502); ++ mdio_write(tp, 0x06, 0x31dd); ++ mdio_write(tp, 0x06, 0x0c13); ++ mdio_write(tp, 0x06, 0x1e21); ++ mdio_write(tp, 0x06, 0xbf1f); ++ mdio_write(tp, 0x06, 0x5302); ++ mdio_write(tp, 0x06, 0x31dd); ++ mdio_write(tp, 0x06, 0x0c14); ++ mdio_write(tp, 0x06, 0x1e21); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0xeb02); ++ mdio_write(tp, 0x06, 0x31dd); ++ mdio_write(tp, 0x06, 0x0c16); ++ mdio_write(tp, 0x06, 0x1e21); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0xe01f); ++ mdio_write(tp, 0x06, 0x029e); ++ mdio_write(tp, 0x06, 0x22e6); ++ mdio_write(tp, 0x06, 0x83e0); ++ mdio_write(tp, 0x06, 0xad31); ++ mdio_write(tp, 0x06, 0x14ad); ++ mdio_write(tp, 0x06, 0x3011); ++ mdio_write(tp, 0x06, 0xef02); ++ mdio_write(tp, 0x06, 0x580c); ++ mdio_write(tp, 0x06, 0x9e07); ++ mdio_write(tp, 0x06, 0xad36); ++ mdio_write(tp, 0x06, 0x085a); ++ mdio_write(tp, 0x06, 0x309f); ++ mdio_write(tp, 0x06, 0x04d1); ++ mdio_write(tp, 0x06, 0x01ae); ++ mdio_write(tp, 0x06, 0x02d1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x82dc); ++ mdio_write(tp, 0x06, 0x0232); ++ mdio_write(tp, 0x06, 0x0aef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfdfc); ++ mdio_write(tp, 0x06, 0x0400); ++ mdio_write(tp, 0x06, 0xe140); ++ mdio_write(tp, 0x06, 0x77e1); ++ mdio_write(tp, 0x06, 0x4010); ++ mdio_write(tp, 0x06, 0xe150); ++ mdio_write(tp, 0x06, 0x32e1); ++ mdio_write(tp, 0x06, 0x5030); ++ mdio_write(tp, 0x06, 0xe144); ++ mdio_write(tp, 0x06, 0x74e1); ++ mdio_write(tp, 0x06, 0x44bb); ++ mdio_write(tp, 0x06, 0xe2d2); ++ mdio_write(tp, 0x06, 0x40e0); ++ mdio_write(tp, 0x06, 0x2cfc); ++ mdio_write(tp, 0x06, 0xe2cc); ++ mdio_write(tp, 0x06, 0xcce2); ++ mdio_write(tp, 0x06, 0x00cc); ++ mdio_write(tp, 0x06, 0xe000); ++ mdio_write(tp, 0x06, 0x99e0); ++ mdio_write(tp, 0x06, 0x3688); ++ mdio_write(tp, 0x06, 0xe036); ++ mdio_write(tp, 0x06, 0x99e1); ++ mdio_write(tp, 0x06, 0x40dd); ++ mdio_write(tp, 0x06, 0xe022); ++ mdio_write(tp, 0x05, 0xe142); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x05, 0xe140); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0005); ++ for (i=0;i<200;i++) ++ { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x00); ++ if (gphy_val & BIT_7) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0004); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ gphy_val = mdio_read(tp, 0x17); ++ gphy_val &= ~(BIT_0); ++ gphy_val |= BIT_2; ++ mdio_write(tp, 0x17, gphy_val); ++ mdio_write(tp, 0x1f, 0x0002); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B80); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_2 | BIT_1; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1f, 0x0004); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x002D); ++ gphy_val = mdio_read(tp, 0x18); ++ gphy_val |= BIT_4; ++ mdio_write(tp, 0x18, gphy_val); ++ mdio_write(tp, 0x1f, 0x0002); ++ mdio_write(tp, 0x1f, 0x0000); ++ gphy_val = mdio_read(tp, 0x14); ++ gphy_val |= BIT_15; ++ mdio_write(tp, 0x14, gphy_val); ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x15, 0x1006); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B86); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x0B, 0x6C14); ++ mdio_write(tp, 0x14, 0x7F3D); ++ mdio_write(tp, 0x1C, 0xFAFE); ++ mdio_write(tp, 0x08, 0x07C5); ++ mdio_write(tp, 0x10, 0xF090); ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x14, 0x641A); ++ mdio_write(tp, 0x1A, 0x0606); ++ mdio_write(tp, 0x12, 0xF480); ++ mdio_write(tp, 0x13, 0x0747); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0004); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x0078); ++ mdio_write(tp, 0x15, 0xA408); ++ mdio_write(tp, 0x17, 0x5100); ++ mdio_write(tp, 0x19, 0x0008); ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x0D, 0x0207); ++ mdio_write(tp, 0x02, 0x5FD0); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0004); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x00A1); ++ gphy_val = mdio_read(tp, 0x1A); ++ gphy_val &= ~BIT_2; ++ mdio_write(tp, 0x1A, gphy_val); ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0004); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x002D); ++ gphy_val = mdio_read(tp, 0x16); ++ gphy_val |= BIT_5; ++ mdio_write(tp, 0x16, gphy_val); ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0004); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x00AC); ++ mdio_write(tp, 0x18, 0x0006); ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x09, 0xA20F); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B5B); ++ mdio_write(tp, 0x06, 0x9222); ++ mdio_write(tp, 0x05, 0x8B6D); ++ mdio_write(tp, 0x06, 0x8000); ++ mdio_write(tp, 0x05, 0x8B76); ++ mdio_write(tp, 0x06, 0x8000); ++ mdio_write(tp, 0x1F, 0x0000); ++ } else if (tp->mcfg == CFG_METHOD_17) { ++ struct pci_dev *pdev = tp->pci_dev; ++ ++ RTL_W8(0x6E, RTL_R8(0x6E) | BIT_6); ++ rtl8168_eri_write(ioaddr, 0x1AE, 2, 0x0403, ERIAR_ExGMAC); ++ ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x1800); ++ gphy_val = mdio_read(tp, 0x15); ++ gphy_val &= ~(BIT_12); ++ mdio_write(tp, 0x15, gphy_val); ++ mdio_write(tp, 0x00, 0x4800); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x002f); ++ for (i = 0; i < 1000; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x1c); ++ if ((gphy_val & 0x0080) == 0x0080) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x1800); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x17); ++ if (!(gphy_val & 0x0001)) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0307); ++ mdio_write(tp, 0x15, 0x00AF); ++ mdio_write(tp, 0x19, 0x4060); ++ mdio_write(tp, 0x15, 0x00B0); ++ mdio_write(tp, 0x19, 0x7800); ++ mdio_write(tp, 0x15, 0x00B1); ++ mdio_write(tp, 0x19, 0x7e00); ++ mdio_write(tp, 0x15, 0x00B2); ++ mdio_write(tp, 0x19, 0x72B0); ++ mdio_write(tp, 0x15, 0x00B3); ++ mdio_write(tp, 0x19, 0x7F00); ++ mdio_write(tp, 0x15, 0x00B4); ++ mdio_write(tp, 0x19, 0x73B0); ++ mdio_write(tp, 0x15, 0x0101); ++ mdio_write(tp, 0x19, 0x0005); ++ mdio_write(tp, 0x15, 0x0103); ++ mdio_write(tp, 0x19, 0x0003); ++ mdio_write(tp, 0x15, 0x0105); ++ mdio_write(tp, 0x19, 0x30FD); ++ mdio_write(tp, 0x15, 0x0106); ++ mdio_write(tp, 0x19, 0x9DF7); ++ mdio_write(tp, 0x15, 0x0107); ++ mdio_write(tp, 0x19, 0x30C6); ++ mdio_write(tp, 0x15, 0x0098); ++ mdio_write(tp, 0x19, 0x7c0b); ++ mdio_write(tp, 0x15, 0x0099); ++ mdio_write(tp, 0x19, 0x6c0b); ++ mdio_write(tp, 0x15, 0x00eb); ++ mdio_write(tp, 0x19, 0x6c0b); ++ mdio_write(tp, 0x15, 0x00f8); ++ mdio_write(tp, 0x19, 0x6f0b); ++ mdio_write(tp, 0x15, 0x00fe); ++ mdio_write(tp, 0x19, 0x6f0f); ++ mdio_write(tp, 0x15, 0x00db); ++ mdio_write(tp, 0x19, 0x6f09); ++ mdio_write(tp, 0x15, 0x00dc); ++ mdio_write(tp, 0x19, 0xaefd); ++ mdio_write(tp, 0x15, 0x00dd); ++ mdio_write(tp, 0x19, 0x6f0b); ++ mdio_write(tp, 0x15, 0x00de); ++ mdio_write(tp, 0x19, 0xc60b); ++ mdio_write(tp, 0x15, 0x00df); ++ mdio_write(tp, 0x19, 0x00fa); ++ mdio_write(tp, 0x15, 0x00e0); ++ mdio_write(tp, 0x19, 0x30e1); ++ mdio_write(tp, 0x15, 0x0000); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0300); ++ mdio_write(tp, 0x1f, 0x0002); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x17, 0x2160); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0040); ++ mdio_write(tp, 0x18, 0x0004); ++ if (pdev->subsystem_vendor == 0x144d && ++ pdev->subsystem_device == 0xc0a6) { ++ mdio_write(tp, 0x18, 0x0724); ++ mdio_write(tp, 0x19, 0xfe00); ++ mdio_write(tp, 0x18, 0x0734); ++ mdio_write(tp, 0x19, 0xfd00); ++ mdio_write(tp, 0x18, 0x1824); ++ mdio_write(tp, 0x19, 0xfc00); ++ mdio_write(tp, 0x18, 0x1834); ++ mdio_write(tp, 0x19, 0xfd00); ++ } ++ mdio_write(tp, 0x18, 0x09d4); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x09e4); ++ mdio_write(tp, 0x19, 0x0800); ++ mdio_write(tp, 0x18, 0x09f4); ++ mdio_write(tp, 0x19, 0xff00); ++ mdio_write(tp, 0x18, 0x0a04); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x0a14); ++ mdio_write(tp, 0x19, 0x0c00); ++ mdio_write(tp, 0x18, 0x0a24); ++ mdio_write(tp, 0x19, 0xff00); ++ mdio_write(tp, 0x18, 0x0a74); ++ mdio_write(tp, 0x19, 0xf600); ++ mdio_write(tp, 0x18, 0x1a24); ++ mdio_write(tp, 0x19, 0x7d00); ++ mdio_write(tp, 0x18, 0x1a64); ++ mdio_write(tp, 0x19, 0x0500); ++ mdio_write(tp, 0x18, 0x1a74); ++ mdio_write(tp, 0x19, 0x9500); ++ mdio_write(tp, 0x18, 0x1a84); ++ mdio_write(tp, 0x19, 0x8000); ++ mdio_write(tp, 0x18, 0x1a94); ++ mdio_write(tp, 0x19, 0x7d00); ++ mdio_write(tp, 0x18, 0x1aa4); ++ mdio_write(tp, 0x19, 0x9600); ++ mdio_write(tp, 0x18, 0x1ac4); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x1ad4); ++ mdio_write(tp, 0x19, 0x0800); ++ mdio_write(tp, 0x18, 0x1af4); ++ mdio_write(tp, 0x19, 0xc400); ++ mdio_write(tp, 0x18, 0x1b04); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x1b14); ++ mdio_write(tp, 0x19, 0x0800); ++ mdio_write(tp, 0x18, 0x1b24); ++ mdio_write(tp, 0x19, 0xfd00); ++ mdio_write(tp, 0x18, 0x1b34); ++ mdio_write(tp, 0x19, 0x4000); ++ mdio_write(tp, 0x18, 0x1b44); ++ mdio_write(tp, 0x19, 0x0400); ++ mdio_write(tp, 0x18, 0x1b94); ++ mdio_write(tp, 0x19, 0xf100); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x17, 0x2100); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0040); ++ mdio_write(tp, 0x18, 0x0000); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x05, 0x8000); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0x48f7); ++ mdio_write(tp, 0x06, 0x00e0); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0xa080); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0xf602); ++ mdio_write(tp, 0x06, 0x0115); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x2202); ++ mdio_write(tp, 0x06, 0x80a0); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x3f02); ++ mdio_write(tp, 0x06, 0x0159); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0xbd02); ++ mdio_write(tp, 0x06, 0x80da); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x88e1); ++ mdio_write(tp, 0x06, 0x8b89); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8a1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8b); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8c1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8e1e); ++ mdio_write(tp, 0x06, 0x01a0); ++ mdio_write(tp, 0x06, 0x00c7); ++ mdio_write(tp, 0x06, 0xaebb); ++ mdio_write(tp, 0x06, 0xd481); ++ mdio_write(tp, 0x06, 0xd2e4); ++ mdio_write(tp, 0x06, 0x8b92); ++ mdio_write(tp, 0x06, 0xe58b); ++ mdio_write(tp, 0x06, 0x93d1); ++ mdio_write(tp, 0x06, 0x03bf); ++ mdio_write(tp, 0x06, 0x8598); ++ mdio_write(tp, 0x06, 0x0237); ++ mdio_write(tp, 0x06, 0x23d1); ++ mdio_write(tp, 0x06, 0x02bf); ++ mdio_write(tp, 0x06, 0x859b); ++ mdio_write(tp, 0x06, 0x0237); ++ mdio_write(tp, 0x06, 0x23ee); ++ mdio_write(tp, 0x06, 0x8608); ++ mdio_write(tp, 0x06, 0x03ee); ++ mdio_write(tp, 0x06, 0x860a); ++ mdio_write(tp, 0x06, 0x60ee); ++ mdio_write(tp, 0x06, 0x8610); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8611); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8abe); ++ mdio_write(tp, 0x06, 0x07ee); ++ mdio_write(tp, 0x06, 0x8abf); ++ mdio_write(tp, 0x06, 0x73ee); ++ mdio_write(tp, 0x06, 0x8a95); ++ mdio_write(tp, 0x06, 0x02bf); ++ mdio_write(tp, 0x06, 0x8b88); ++ mdio_write(tp, 0x06, 0xec00); ++ mdio_write(tp, 0x06, 0x19a9); ++ mdio_write(tp, 0x06, 0x8b90); ++ mdio_write(tp, 0x06, 0xf9ee); ++ mdio_write(tp, 0x06, 0xfff6); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0xfed1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x858f); ++ mdio_write(tp, 0x06, 0x0237); ++ mdio_write(tp, 0x06, 0x23d1); ++ mdio_write(tp, 0x06, 0x01bf); ++ mdio_write(tp, 0x06, 0x8592); ++ mdio_write(tp, 0x06, 0x0237); ++ mdio_write(tp, 0x06, 0x2304); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b8a); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x14ee); ++ mdio_write(tp, 0x06, 0x8b8a); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x1f9a); ++ mdio_write(tp, 0x06, 0xe0e4); ++ mdio_write(tp, 0x06, 0x26e1); ++ mdio_write(tp, 0x06, 0xe427); ++ mdio_write(tp, 0x06, 0xeee4); ++ mdio_write(tp, 0x06, 0x2623); ++ mdio_write(tp, 0x06, 0xe5e4); ++ mdio_write(tp, 0x06, 0x27fc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8dad); ++ mdio_write(tp, 0x06, 0x2014); ++ mdio_write(tp, 0x06, 0xee8b); ++ mdio_write(tp, 0x06, 0x8d00); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0x5a78); ++ mdio_write(tp, 0x06, 0x039e); ++ mdio_write(tp, 0x06, 0x0902); ++ mdio_write(tp, 0x06, 0x05db); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0x7b02); ++ mdio_write(tp, 0x06, 0x3231); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x1df6); ++ mdio_write(tp, 0x06, 0x20e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0x5c02); ++ mdio_write(tp, 0x06, 0x2bcb); ++ mdio_write(tp, 0x06, 0x022d); ++ mdio_write(tp, 0x06, 0x2902); ++ mdio_write(tp, 0x06, 0x03b4); ++ mdio_write(tp, 0x06, 0x0285); ++ mdio_write(tp, 0x06, 0x5e02); ++ mdio_write(tp, 0x06, 0x2eca); ++ mdio_write(tp, 0x06, 0x0284); ++ mdio_write(tp, 0x06, 0xc702); ++ mdio_write(tp, 0x06, 0x046f); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x210b); ++ mdio_write(tp, 0x06, 0xf621); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x851a); ++ mdio_write(tp, 0x06, 0x021b); ++ mdio_write(tp, 0x06, 0xe8e0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad22); ++ mdio_write(tp, 0x06, 0x05f6); ++ mdio_write(tp, 0x06, 0x22e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2308); ++ mdio_write(tp, 0x06, 0xf623); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x311c); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2405); ++ mdio_write(tp, 0x06, 0xf624); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8ee0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad25); ++ mdio_write(tp, 0x06, 0x05f6); ++ mdio_write(tp, 0x06, 0x25e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2608); ++ mdio_write(tp, 0x06, 0xf626); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x2df5); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2705); ++ mdio_write(tp, 0x06, 0xf627); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x037a); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69e0); ++ mdio_write(tp, 0x06, 0x8b87); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x65d2); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x2fe9); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0xf61e); ++ mdio_write(tp, 0x06, 0x21bf); ++ mdio_write(tp, 0x06, 0x2ff5); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0xf60c); ++ mdio_write(tp, 0x06, 0x111e); ++ mdio_write(tp, 0x06, 0x21bf); ++ mdio_write(tp, 0x06, 0x2ff8); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0xf60c); ++ mdio_write(tp, 0x06, 0x121e); ++ mdio_write(tp, 0x06, 0x21bf); ++ mdio_write(tp, 0x06, 0x2ffb); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0xf60c); ++ mdio_write(tp, 0x06, 0x131e); ++ mdio_write(tp, 0x06, 0x21bf); ++ mdio_write(tp, 0x06, 0x1f97); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0xf60c); ++ mdio_write(tp, 0x06, 0x141e); ++ mdio_write(tp, 0x06, 0x21bf); ++ mdio_write(tp, 0x06, 0x8595); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0xf60c); ++ mdio_write(tp, 0x06, 0x161e); ++ mdio_write(tp, 0x06, 0x21e0); ++ mdio_write(tp, 0x06, 0x8a8c); ++ mdio_write(tp, 0x06, 0x1f02); ++ mdio_write(tp, 0x06, 0x9e22); ++ mdio_write(tp, 0x06, 0xe68a); ++ mdio_write(tp, 0x06, 0x8cad); ++ mdio_write(tp, 0x06, 0x3114); ++ mdio_write(tp, 0x06, 0xad30); ++ mdio_write(tp, 0x06, 0x11ef); ++ mdio_write(tp, 0x06, 0x0258); ++ mdio_write(tp, 0x06, 0x0c9e); ++ mdio_write(tp, 0x06, 0x07ad); ++ mdio_write(tp, 0x06, 0x3608); ++ mdio_write(tp, 0x06, 0x5a30); ++ mdio_write(tp, 0x06, 0x9f04); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xae02); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf2f); ++ mdio_write(tp, 0x06, 0xf202); ++ mdio_write(tp, 0x06, 0x3723); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfefd); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xface); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69fa); ++ mdio_write(tp, 0x06, 0xd401); ++ mdio_write(tp, 0x06, 0x55b4); ++ mdio_write(tp, 0x06, 0xfebf); ++ mdio_write(tp, 0x06, 0x85a1); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0xf6ac); ++ mdio_write(tp, 0x06, 0x280b); ++ mdio_write(tp, 0x06, 0xbf85); ++ mdio_write(tp, 0x06, 0x9e02); ++ mdio_write(tp, 0x06, 0x36f6); ++ mdio_write(tp, 0x06, 0xac28); ++ mdio_write(tp, 0x06, 0x49ae); ++ mdio_write(tp, 0x06, 0x64bf); ++ mdio_write(tp, 0x06, 0x859e); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0xf6ac); ++ mdio_write(tp, 0x06, 0x285b); ++ mdio_write(tp, 0x06, 0xd000); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0x60ac); ++ mdio_write(tp, 0x06, 0x2105); ++ mdio_write(tp, 0x06, 0xac22); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x4ebf); ++ mdio_write(tp, 0x06, 0xe0c4); ++ mdio_write(tp, 0x06, 0xbe86); ++ mdio_write(tp, 0x06, 0x14d2); ++ mdio_write(tp, 0x06, 0x04d8); ++ mdio_write(tp, 0x06, 0x19d9); ++ mdio_write(tp, 0x06, 0x1907); ++ mdio_write(tp, 0x06, 0xdc19); ++ mdio_write(tp, 0x06, 0xdd19); ++ mdio_write(tp, 0x06, 0x0789); ++ mdio_write(tp, 0x06, 0x89ef); ++ mdio_write(tp, 0x06, 0x645e); ++ mdio_write(tp, 0x06, 0x07ff); ++ mdio_write(tp, 0x06, 0x0d65); ++ mdio_write(tp, 0x06, 0x5cf8); ++ mdio_write(tp, 0x06, 0x001e); ++ mdio_write(tp, 0x06, 0x46dc); ++ mdio_write(tp, 0x06, 0x19dd); ++ mdio_write(tp, 0x06, 0x19b2); ++ mdio_write(tp, 0x06, 0xe2d4); ++ mdio_write(tp, 0x06, 0x0001); ++ mdio_write(tp, 0x06, 0xbf85); ++ mdio_write(tp, 0x06, 0x9e02); ++ mdio_write(tp, 0x06, 0x3723); ++ mdio_write(tp, 0x06, 0xae1d); ++ mdio_write(tp, 0x06, 0xbee0); ++ mdio_write(tp, 0x06, 0xc4bf); ++ mdio_write(tp, 0x06, 0x8614); ++ mdio_write(tp, 0x06, 0xd204); ++ mdio_write(tp, 0x06, 0xd819); ++ mdio_write(tp, 0x06, 0xd919); ++ mdio_write(tp, 0x06, 0x07dc); ++ mdio_write(tp, 0x06, 0x19dd); ++ mdio_write(tp, 0x06, 0x1907); ++ mdio_write(tp, 0x06, 0xb2f4); ++ mdio_write(tp, 0x06, 0xd400); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x859e); ++ mdio_write(tp, 0x06, 0x0237); ++ mdio_write(tp, 0x06, 0x23fe); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfec6); ++ mdio_write(tp, 0x06, 0xfefd); ++ mdio_write(tp, 0x06, 0xfc05); ++ mdio_write(tp, 0x06, 0xf9e2); ++ mdio_write(tp, 0x06, 0xe0ea); ++ mdio_write(tp, 0x06, 0xe3e0); ++ mdio_write(tp, 0x06, 0xeb5a); ++ mdio_write(tp, 0x06, 0x070c); ++ mdio_write(tp, 0x06, 0x031e); ++ mdio_write(tp, 0x06, 0x20e6); ++ mdio_write(tp, 0x06, 0xe0ea); ++ mdio_write(tp, 0x06, 0xe7e0); ++ mdio_write(tp, 0x06, 0xebe0); ++ mdio_write(tp, 0x06, 0xe0fc); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0xfdfd); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xf9e0); ++ mdio_write(tp, 0x06, 0x8b81); ++ mdio_write(tp, 0x06, 0xac26); ++ mdio_write(tp, 0x06, 0x1ae0); ++ mdio_write(tp, 0x06, 0x8b81); ++ mdio_write(tp, 0x06, 0xac21); ++ mdio_write(tp, 0x06, 0x14e0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xac20); ++ mdio_write(tp, 0x06, 0x0ee0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xac23); ++ mdio_write(tp, 0x06, 0x08e0); ++ mdio_write(tp, 0x06, 0x8b87); ++ mdio_write(tp, 0x06, 0xac24); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x32ee); ++ mdio_write(tp, 0x06, 0xe41c); ++ mdio_write(tp, 0x06, 0x04ee); ++ mdio_write(tp, 0x06, 0xe41d); ++ mdio_write(tp, 0x06, 0x04e2); ++ mdio_write(tp, 0x06, 0xe07c); ++ mdio_write(tp, 0x06, 0xe3e0); ++ mdio_write(tp, 0x06, 0x7de0); ++ mdio_write(tp, 0x06, 0xe038); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x39ad); ++ mdio_write(tp, 0x06, 0x2e1b); ++ mdio_write(tp, 0x06, 0xad39); ++ mdio_write(tp, 0x06, 0x0dd1); ++ mdio_write(tp, 0x06, 0x01bf); ++ mdio_write(tp, 0x06, 0x21d5); ++ mdio_write(tp, 0x06, 0x0237); ++ mdio_write(tp, 0x06, 0x2302); ++ mdio_write(tp, 0x06, 0x82d2); ++ mdio_write(tp, 0x06, 0xae0b); ++ mdio_write(tp, 0x06, 0xac38); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x0602); ++ mdio_write(tp, 0x06, 0x8312); ++ mdio_write(tp, 0x06, 0x0283); ++ mdio_write(tp, 0x06, 0x5afd); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e1); ++ mdio_write(tp, 0x06, 0x8af4); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x2605); ++ mdio_write(tp, 0x06, 0x0222); ++ mdio_write(tp, 0x06, 0xa4f7); ++ mdio_write(tp, 0x06, 0x28e0); ++ mdio_write(tp, 0x06, 0x8b81); ++ mdio_write(tp, 0x06, 0xad21); ++ mdio_write(tp, 0x06, 0x0502); ++ mdio_write(tp, 0x06, 0x23a9); ++ mdio_write(tp, 0x06, 0xf729); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x85ad); ++ mdio_write(tp, 0x06, 0x2005); ++ mdio_write(tp, 0x06, 0x0214); ++ mdio_write(tp, 0x06, 0xabf7); ++ mdio_write(tp, 0x06, 0x2ae0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xad23); ++ mdio_write(tp, 0x06, 0x0502); ++ mdio_write(tp, 0x06, 0x12e7); ++ mdio_write(tp, 0x06, 0xf72b); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x87ad); ++ mdio_write(tp, 0x06, 0x2405); ++ mdio_write(tp, 0x06, 0x0283); ++ mdio_write(tp, 0x06, 0xb6f7); ++ mdio_write(tp, 0x06, 0x2ce5); ++ mdio_write(tp, 0x06, 0x8af4); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b81); ++ mdio_write(tp, 0x06, 0xad26); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x21e5); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x2109); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xf4ac); ++ mdio_write(tp, 0x06, 0x2003); ++ mdio_write(tp, 0x06, 0x0223); ++ mdio_write(tp, 0x06, 0x98e0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x09e0); ++ mdio_write(tp, 0x06, 0x8af4); ++ mdio_write(tp, 0x06, 0xac21); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x13fb); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x85ad); ++ mdio_write(tp, 0x06, 0x2309); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xf4ac); ++ mdio_write(tp, 0x06, 0x2203); ++ mdio_write(tp, 0x06, 0x0212); ++ mdio_write(tp, 0x06, 0xfae0); ++ mdio_write(tp, 0x06, 0x8b87); ++ mdio_write(tp, 0x06, 0xad24); ++ mdio_write(tp, 0x06, 0x09e0); ++ mdio_write(tp, 0x06, 0x8af4); ++ mdio_write(tp, 0x06, 0xac23); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x83bb); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e1); ++ mdio_write(tp, 0x06, 0x8af4); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x2608); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0xd2ad); ++ mdio_write(tp, 0x06, 0x2502); ++ mdio_write(tp, 0x06, 0xf628); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x210a); ++ mdio_write(tp, 0x06, 0xe084); ++ mdio_write(tp, 0x06, 0x0af6); ++ mdio_write(tp, 0x06, 0x27a0); ++ mdio_write(tp, 0x06, 0x0502); ++ mdio_write(tp, 0x06, 0xf629); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x85ad); ++ mdio_write(tp, 0x06, 0x2008); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xe8ad); ++ mdio_write(tp, 0x06, 0x2102); ++ mdio_write(tp, 0x06, 0xf62a); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x85ad); ++ mdio_write(tp, 0x06, 0x2308); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x20a0); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0xf62b); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x87ad); ++ mdio_write(tp, 0x06, 0x2408); ++ mdio_write(tp, 0x06, 0xe086); ++ mdio_write(tp, 0x06, 0x02a0); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0xf62c); ++ mdio_write(tp, 0x06, 0xe58a); ++ mdio_write(tp, 0x06, 0xf4a1); ++ mdio_write(tp, 0x06, 0x0008); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf21); ++ mdio_write(tp, 0x06, 0xd502); ++ mdio_write(tp, 0x06, 0x3723); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xee86); ++ mdio_write(tp, 0x06, 0x0200); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x87ad); ++ mdio_write(tp, 0x06, 0x241e); ++ mdio_write(tp, 0x06, 0xe086); ++ mdio_write(tp, 0x06, 0x02a0); ++ mdio_write(tp, 0x06, 0x0005); ++ mdio_write(tp, 0x06, 0x0283); ++ mdio_write(tp, 0x06, 0xe2ae); ++ mdio_write(tp, 0x06, 0xf5a0); ++ mdio_write(tp, 0x06, 0x0105); ++ mdio_write(tp, 0x06, 0x0283); ++ mdio_write(tp, 0x06, 0xf2ae); ++ mdio_write(tp, 0x06, 0x0ba0); ++ mdio_write(tp, 0x06, 0x0205); ++ mdio_write(tp, 0x06, 0x0284); ++ mdio_write(tp, 0x06, 0x0eae); ++ mdio_write(tp, 0x06, 0x03a0); ++ mdio_write(tp, 0x06, 0x0300); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0x0284); ++ mdio_write(tp, 0x06, 0x25ee); ++ mdio_write(tp, 0x06, 0x8602); ++ mdio_write(tp, 0x06, 0x01ef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8ee); ++ mdio_write(tp, 0x06, 0x8609); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x845b); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xae10); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8608); ++ mdio_write(tp, 0x06, 0xe186); ++ mdio_write(tp, 0x06, 0x091f); ++ mdio_write(tp, 0x06, 0x019e); ++ mdio_write(tp, 0x06, 0x0611); ++ mdio_write(tp, 0x06, 0xe586); ++ mdio_write(tp, 0x06, 0x09ae); ++ mdio_write(tp, 0x06, 0x04ee); ++ mdio_write(tp, 0x06, 0x8602); ++ mdio_write(tp, 0x06, 0x01fc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xf9fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0xfbbf); ++ mdio_write(tp, 0x06, 0x8604); ++ mdio_write(tp, 0x06, 0xef79); ++ mdio_write(tp, 0x06, 0xd200); ++ mdio_write(tp, 0x06, 0xd400); ++ mdio_write(tp, 0x06, 0x221e); ++ mdio_write(tp, 0x06, 0x02bf); ++ mdio_write(tp, 0x06, 0x2fec); ++ mdio_write(tp, 0x06, 0x0237); ++ mdio_write(tp, 0x06, 0x23bf); ++ mdio_write(tp, 0x06, 0x13f2); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0xf60d); ++ mdio_write(tp, 0x06, 0x4559); ++ mdio_write(tp, 0x06, 0x1fef); ++ mdio_write(tp, 0x06, 0x97dd); ++ mdio_write(tp, 0x06, 0xd308); ++ mdio_write(tp, 0x06, 0x1a93); ++ mdio_write(tp, 0x06, 0xdd12); ++ mdio_write(tp, 0x06, 0x17a2); ++ mdio_write(tp, 0x06, 0x04de); ++ mdio_write(tp, 0x06, 0xffef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfdfc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xf9fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0xfbee); ++ mdio_write(tp, 0x06, 0x8602); ++ mdio_write(tp, 0x06, 0x03d5); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x06, 0xbf86); ++ mdio_write(tp, 0x06, 0x04ef); ++ mdio_write(tp, 0x06, 0x79ef); ++ mdio_write(tp, 0x06, 0x45bf); ++ mdio_write(tp, 0x06, 0x2fec); ++ mdio_write(tp, 0x06, 0x0237); ++ mdio_write(tp, 0x06, 0x23bf); ++ mdio_write(tp, 0x06, 0x13f2); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0xf6ad); ++ mdio_write(tp, 0x06, 0x2702); ++ mdio_write(tp, 0x06, 0x78ff); ++ mdio_write(tp, 0x06, 0xe186); ++ mdio_write(tp, 0x06, 0x0a1b); ++ mdio_write(tp, 0x06, 0x01aa); ++ mdio_write(tp, 0x06, 0x2eef); ++ mdio_write(tp, 0x06, 0x97d9); ++ mdio_write(tp, 0x06, 0x7900); ++ mdio_write(tp, 0x06, 0x9e2b); ++ mdio_write(tp, 0x06, 0x81dd); ++ mdio_write(tp, 0x06, 0xbf85); ++ mdio_write(tp, 0x06, 0xa702); ++ mdio_write(tp, 0x06, 0x3723); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xef02); ++ mdio_write(tp, 0x06, 0x100c); ++ mdio_write(tp, 0x06, 0x11b0); ++ mdio_write(tp, 0x06, 0xfc0d); ++ mdio_write(tp, 0x06, 0x11bf); ++ mdio_write(tp, 0x06, 0x85a4); ++ mdio_write(tp, 0x06, 0x0237); ++ mdio_write(tp, 0x06, 0x23d1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x85a4); ++ mdio_write(tp, 0x06, 0x0237); ++ mdio_write(tp, 0x06, 0x23ee); ++ mdio_write(tp, 0x06, 0x8602); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x0413); ++ mdio_write(tp, 0x06, 0xa38b); ++ mdio_write(tp, 0x06, 0xb4d3); ++ mdio_write(tp, 0x06, 0x8012); ++ mdio_write(tp, 0x06, 0x17a2); ++ mdio_write(tp, 0x06, 0x04ad); ++ mdio_write(tp, 0x06, 0xffef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfdfc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xf9e0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xad25); ++ mdio_write(tp, 0x06, 0x48e0); ++ mdio_write(tp, 0x06, 0x8a96); ++ mdio_write(tp, 0x06, 0xe18a); ++ mdio_write(tp, 0x06, 0x977c); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x9e35); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0x9600); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0x9700); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xbee1); ++ mdio_write(tp, 0x06, 0x8abf); ++ mdio_write(tp, 0x06, 0xe286); ++ mdio_write(tp, 0x06, 0x10e3); ++ mdio_write(tp, 0x06, 0x8611); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0x1aad); ++ mdio_write(tp, 0x06, 0x2012); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0x9603); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0x97b7); ++ mdio_write(tp, 0x06, 0xee86); ++ mdio_write(tp, 0x06, 0x1000); ++ mdio_write(tp, 0x06, 0xee86); ++ mdio_write(tp, 0x06, 0x1100); ++ mdio_write(tp, 0x06, 0xae11); ++ mdio_write(tp, 0x06, 0x15e6); ++ mdio_write(tp, 0x06, 0x8610); ++ mdio_write(tp, 0x06, 0xe786); ++ mdio_write(tp, 0x06, 0x11ae); ++ mdio_write(tp, 0x06, 0x08ee); ++ mdio_write(tp, 0x06, 0x8610); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8611); ++ mdio_write(tp, 0x06, 0x00fd); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x00e1); ++ mdio_write(tp, 0x06, 0xe001); ++ mdio_write(tp, 0x06, 0xad27); ++ mdio_write(tp, 0x06, 0x32e0); ++ mdio_write(tp, 0x06, 0x8b40); ++ mdio_write(tp, 0x06, 0xf720); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x40bf); ++ mdio_write(tp, 0x06, 0x31f5); ++ mdio_write(tp, 0x06, 0x0236); ++ mdio_write(tp, 0x06, 0xf6ad); ++ mdio_write(tp, 0x06, 0x2821); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x20e1); ++ mdio_write(tp, 0x06, 0xe021); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x18e0); ++ mdio_write(tp, 0x06, 0x8b40); ++ mdio_write(tp, 0x06, 0xf620); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x40ee); ++ mdio_write(tp, 0x06, 0x8b3b); ++ mdio_write(tp, 0x06, 0xffe0); ++ mdio_write(tp, 0x06, 0x8a8a); ++ mdio_write(tp, 0x06, 0xe18a); ++ mdio_write(tp, 0x06, 0x8be4); ++ mdio_write(tp, 0x06, 0xe000); ++ mdio_write(tp, 0x06, 0xe5e0); ++ mdio_write(tp, 0x06, 0x01ef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x80ad); ++ mdio_write(tp, 0x06, 0x2722); ++ mdio_write(tp, 0x06, 0xbf44); ++ mdio_write(tp, 0x06, 0xfc02); ++ mdio_write(tp, 0x06, 0x36f6); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x441f); ++ mdio_write(tp, 0x06, 0x019e); ++ mdio_write(tp, 0x06, 0x15e5); ++ mdio_write(tp, 0x06, 0x8b44); ++ mdio_write(tp, 0x06, 0xad29); ++ mdio_write(tp, 0x06, 0x07ac); ++ mdio_write(tp, 0x06, 0x2804); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xae02); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf85); ++ mdio_write(tp, 0x06, 0xaa02); ++ mdio_write(tp, 0x06, 0x3723); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfefc); ++ mdio_write(tp, 0x06, 0x0400); ++ mdio_write(tp, 0x06, 0xe140); ++ mdio_write(tp, 0x06, 0x77e1); ++ mdio_write(tp, 0x06, 0x40dd); ++ mdio_write(tp, 0x06, 0xe022); ++ mdio_write(tp, 0x06, 0x32e1); ++ mdio_write(tp, 0x06, 0x5074); ++ mdio_write(tp, 0x06, 0xe144); ++ mdio_write(tp, 0x06, 0xffe0); ++ mdio_write(tp, 0x06, 0xdaff); ++ mdio_write(tp, 0x06, 0xe0c0); ++ mdio_write(tp, 0x06, 0x52e0); ++ mdio_write(tp, 0x06, 0xeed9); ++ mdio_write(tp, 0x06, 0xe04c); ++ mdio_write(tp, 0x06, 0xbbe0); ++ mdio_write(tp, 0x06, 0x2a00); ++ mdio_write(tp, 0x05, 0xe142); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x05, 0xe140); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0005); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x00); ++ if (gphy_val & BIT_7) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0042); ++ mdio_write(tp, 0x18, 0x2300); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ if ((pdev->subsystem_vendor == 0x144d && ++ pdev->subsystem_device == 0xc098) || ++ (pdev->subsystem_vendor == 0x144d && ++ pdev->subsystem_device == 0xc0b1)) { ++ gphy_val = mdio_read(tp, 0x17); ++ gphy_val &= ~(BIT_2); ++ mdio_write(tp, 0x17, gphy_val); ++ } ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x9200); ++ ++ if (pdev->subsystem_vendor == 0x144d && ++ pdev->subsystem_device == 0xc0a6) { ++ mdio_write(tp, 0x1F, 0x0001); ++ mdio_write(tp, 0x0e, 0x6b7f); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B86); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_4; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ } else { ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B80); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_2 | BIT_1; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B86); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val &= ~BIT_4; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ } ++ ++ mdio_write(tp, 0x1f, 0x0004); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x002D); ++ gphy_val = mdio_read(tp, 0x18); ++ gphy_val |= BIT_4; ++ mdio_write(tp, 0x18, gphy_val); ++ mdio_write(tp, 0x1f, 0x0002); ++ mdio_write(tp, 0x1f, 0x0000); ++ gphy_val = mdio_read(tp, 0x14); ++ gphy_val |= BIT_15; ++ mdio_write(tp, 0x14, gphy_val); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B86); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0004); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x00AC); ++ mdio_write(tp, 0x18, 0x0006); ++ mdio_write(tp, 0x1F, 0x0002); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x09, 0xA20F); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B85); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_14; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B5B); ++ mdio_write(tp, 0x06, 0x9222); ++ mdio_write(tp, 0x05, 0x8B6D); ++ mdio_write(tp, 0x06, 0x8000); ++ mdio_write(tp, 0x05, 0x8B76); ++ mdio_write(tp, 0x06, 0x8000); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1f, 0x0000); ++ gphy_val = mdio_read(tp, 0x15); ++ gphy_val |= BIT_12; ++ mdio_write(tp, 0x15, gphy_val); ++ } else if (tp->mcfg == CFG_METHOD_18) { ++ RTL_W8(0x6E, RTL_R8(0x6E) | BIT_6); ++ rtl8168_eri_write(ioaddr, 0x1AE, 2, 0x0403, ERIAR_ExGMAC); ++ ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x1800); ++ gphy_val = mdio_read(tp, 0x15); ++ gphy_val &= ~(BIT_12); ++ mdio_write(tp, 0x15, gphy_val); ++ mdio_write(tp, 0x00, 0x4800); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x002f); ++ for (i = 0; i < 1000; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x1c); ++ if (gphy_val & 0x0080) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x1800); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x18); ++ if (!(gphy_val & 0x0001)) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0307); ++ mdio_write(tp, 0x15, 0x0194); ++ mdio_write(tp, 0x19, 0x407D); ++ mdio_write(tp, 0x15, 0x0098); ++ mdio_write(tp, 0x19, 0x7c0b); ++ mdio_write(tp, 0x15, 0x0099); ++ mdio_write(tp, 0x19, 0x6c0b); ++ mdio_write(tp, 0x15, 0x00eb); ++ mdio_write(tp, 0x19, 0x6c0b); ++ mdio_write(tp, 0x15, 0x00f8); ++ mdio_write(tp, 0x19, 0x6f0b); ++ mdio_write(tp, 0x15, 0x00fe); ++ mdio_write(tp, 0x19, 0x6f0f); ++ mdio_write(tp, 0x15, 0x00db); ++ mdio_write(tp, 0x19, 0x6f09); ++ mdio_write(tp, 0x15, 0x00dc); ++ mdio_write(tp, 0x19, 0xaefd); ++ mdio_write(tp, 0x15, 0x00dd); ++ mdio_write(tp, 0x19, 0x6f0b); ++ mdio_write(tp, 0x15, 0x00de); ++ mdio_write(tp, 0x19, 0xc60b); ++ mdio_write(tp, 0x15, 0x00df); ++ mdio_write(tp, 0x19, 0x00fa); ++ mdio_write(tp, 0x15, 0x00e0); ++ mdio_write(tp, 0x19, 0x30e1); ++ mdio_write(tp, 0x15, 0x0000); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0300); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x05, 0x8000); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0x48f7); ++ mdio_write(tp, 0x06, 0x00e0); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0xa080); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0xf602); ++ mdio_write(tp, 0x06, 0x0118); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x2502); ++ mdio_write(tp, 0x06, 0x8090); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x4202); ++ mdio_write(tp, 0x06, 0x015c); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0xad02); ++ mdio_write(tp, 0x06, 0x80ca); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x88e1); ++ mdio_write(tp, 0x06, 0x8b89); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8a1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8b); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8c1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8e1e); ++ mdio_write(tp, 0x06, 0x01a0); ++ mdio_write(tp, 0x06, 0x00c7); ++ mdio_write(tp, 0x06, 0xaebb); ++ mdio_write(tp, 0x06, 0xd484); ++ mdio_write(tp, 0x06, 0x36e4); ++ mdio_write(tp, 0x06, 0x8b92); ++ mdio_write(tp, 0x06, 0xe58b); ++ mdio_write(tp, 0x06, 0x93ee); ++ mdio_write(tp, 0x06, 0x8ac8); ++ mdio_write(tp, 0x06, 0x03ee); ++ mdio_write(tp, 0x06, 0x8aca); ++ mdio_write(tp, 0x06, 0x60ee); ++ mdio_write(tp, 0x06, 0x8ac0); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8ac1); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8abe); ++ mdio_write(tp, 0x06, 0x07ee); ++ mdio_write(tp, 0x06, 0x8abf); ++ mdio_write(tp, 0x06, 0x73ee); ++ mdio_write(tp, 0x06, 0x8a95); ++ mdio_write(tp, 0x06, 0x02bf); ++ mdio_write(tp, 0x06, 0x8b88); ++ mdio_write(tp, 0x06, 0xec00); ++ mdio_write(tp, 0x06, 0x19a9); ++ mdio_write(tp, 0x06, 0x8b90); ++ mdio_write(tp, 0x06, 0xf9ee); ++ mdio_write(tp, 0x06, 0xfff6); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0xfed1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x8510); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x7dd1); ++ mdio_write(tp, 0x06, 0x01bf); ++ mdio_write(tp, 0x06, 0x8513); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x7d04); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b8a); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x14ee); ++ mdio_write(tp, 0x06, 0x8b8a); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x204b); ++ mdio_write(tp, 0x06, 0xe0e4); ++ mdio_write(tp, 0x06, 0x26e1); ++ mdio_write(tp, 0x06, 0xe427); ++ mdio_write(tp, 0x06, 0xeee4); ++ mdio_write(tp, 0x06, 0x2623); ++ mdio_write(tp, 0x06, 0xe5e4); ++ mdio_write(tp, 0x06, 0x27fc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8dad); ++ mdio_write(tp, 0x06, 0x2014); ++ mdio_write(tp, 0x06, 0xee8b); ++ mdio_write(tp, 0x06, 0x8d00); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0x5a78); ++ mdio_write(tp, 0x06, 0x039e); ++ mdio_write(tp, 0x06, 0x0902); ++ mdio_write(tp, 0x06, 0x05e8); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0x4f02); ++ mdio_write(tp, 0x06, 0x326c); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x1df6); ++ mdio_write(tp, 0x06, 0x20e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x022f); ++ mdio_write(tp, 0x06, 0x0902); ++ mdio_write(tp, 0x06, 0x2ab0); ++ mdio_write(tp, 0x06, 0x022c); ++ mdio_write(tp, 0x06, 0x0e02); ++ mdio_write(tp, 0x06, 0x03ba); ++ mdio_write(tp, 0x06, 0x0284); ++ mdio_write(tp, 0x06, 0xdf02); ++ mdio_write(tp, 0x06, 0x2df1); ++ mdio_write(tp, 0x06, 0x0283); ++ mdio_write(tp, 0x06, 0x7d02); ++ mdio_write(tp, 0x06, 0x0475); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x210b); ++ mdio_write(tp, 0x06, 0xf621); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x83d0); ++ mdio_write(tp, 0x06, 0x021c); ++ mdio_write(tp, 0x06, 0x99e0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad22); ++ mdio_write(tp, 0x06, 0x08f6); ++ mdio_write(tp, 0x06, 0x22e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x0235); ++ mdio_write(tp, 0x06, 0x63e0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad23); ++ mdio_write(tp, 0x06, 0x08f6); ++ mdio_write(tp, 0x06, 0x23e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x0231); ++ mdio_write(tp, 0x06, 0x57e0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad24); ++ mdio_write(tp, 0x06, 0x05f6); ++ mdio_write(tp, 0x06, 0x24e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2505); ++ mdio_write(tp, 0x06, 0xf625); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8ee0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad26); ++ mdio_write(tp, 0x06, 0x08f6); ++ mdio_write(tp, 0x06, 0x26e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x022d); ++ mdio_write(tp, 0x06, 0x1ce0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad27); ++ mdio_write(tp, 0x06, 0x05f6); ++ mdio_write(tp, 0x06, 0x27e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x0203); ++ mdio_write(tp, 0x06, 0x80fc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xf9e0); ++ mdio_write(tp, 0x06, 0x8b81); ++ mdio_write(tp, 0x06, 0xac26); ++ mdio_write(tp, 0x06, 0x1ae0); ++ mdio_write(tp, 0x06, 0x8b81); ++ mdio_write(tp, 0x06, 0xac21); ++ mdio_write(tp, 0x06, 0x14e0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xac20); ++ mdio_write(tp, 0x06, 0x0ee0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xac23); ++ mdio_write(tp, 0x06, 0x08e0); ++ mdio_write(tp, 0x06, 0x8b87); ++ mdio_write(tp, 0x06, 0xac24); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x32ee); ++ mdio_write(tp, 0x06, 0xe41c); ++ mdio_write(tp, 0x06, 0x04ee); ++ mdio_write(tp, 0x06, 0xe41d); ++ mdio_write(tp, 0x06, 0x04e2); ++ mdio_write(tp, 0x06, 0xe07c); ++ mdio_write(tp, 0x06, 0xe3e0); ++ mdio_write(tp, 0x06, 0x7de0); ++ mdio_write(tp, 0x06, 0xe038); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0x39ad); ++ mdio_write(tp, 0x06, 0x2e1b); ++ mdio_write(tp, 0x06, 0xad39); ++ mdio_write(tp, 0x06, 0x0dd1); ++ mdio_write(tp, 0x06, 0x01bf); ++ mdio_write(tp, 0x06, 0x227a); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x7d02); ++ mdio_write(tp, 0x06, 0x81a6); ++ mdio_write(tp, 0x06, 0xae0b); ++ mdio_write(tp, 0x06, 0xac38); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x0602); ++ mdio_write(tp, 0x06, 0x81e3); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0x28fd); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e1); ++ mdio_write(tp, 0x06, 0x8af4); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x2602); ++ mdio_write(tp, 0x06, 0xf728); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x2105); ++ mdio_write(tp, 0x06, 0x0222); ++ mdio_write(tp, 0x06, 0x8ef7); ++ mdio_write(tp, 0x06, 0x29e0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x0502); ++ mdio_write(tp, 0x06, 0x14b8); ++ mdio_write(tp, 0x06, 0xf72a); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x85ad); ++ mdio_write(tp, 0x06, 0x2305); ++ mdio_write(tp, 0x06, 0x0212); ++ mdio_write(tp, 0x06, 0xf4f7); ++ mdio_write(tp, 0x06, 0x2be0); ++ mdio_write(tp, 0x06, 0x8b87); ++ mdio_write(tp, 0x06, 0xad24); ++ mdio_write(tp, 0x06, 0x0502); ++ mdio_write(tp, 0x06, 0x827e); ++ mdio_write(tp, 0x06, 0xf72c); ++ mdio_write(tp, 0x06, 0xe58a); ++ mdio_write(tp, 0x06, 0xf4fc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x2600); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x2109); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xf4ac); ++ mdio_write(tp, 0x06, 0x2003); ++ mdio_write(tp, 0x06, 0x0222); ++ mdio_write(tp, 0x06, 0x7de0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x09e0); ++ mdio_write(tp, 0x06, 0x8af4); ++ mdio_write(tp, 0x06, 0xac21); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x1408); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x85ad); ++ mdio_write(tp, 0x06, 0x2309); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xf4ac); ++ mdio_write(tp, 0x06, 0x2203); ++ mdio_write(tp, 0x06, 0x0213); ++ mdio_write(tp, 0x06, 0x07e0); ++ mdio_write(tp, 0x06, 0x8b87); ++ mdio_write(tp, 0x06, 0xad24); ++ mdio_write(tp, 0x06, 0x09e0); ++ mdio_write(tp, 0x06, 0x8af4); ++ mdio_write(tp, 0x06, 0xac23); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0x8283); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e1); ++ mdio_write(tp, 0x06, 0x8af4); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x2602); ++ mdio_write(tp, 0x06, 0xf628); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x81ad); ++ mdio_write(tp, 0x06, 0x210a); ++ mdio_write(tp, 0x06, 0xe083); ++ mdio_write(tp, 0x06, 0xecf6); ++ mdio_write(tp, 0x06, 0x27a0); ++ mdio_write(tp, 0x06, 0x0502); ++ mdio_write(tp, 0x06, 0xf629); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x85ad); ++ mdio_write(tp, 0x06, 0x2008); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xe8ad); ++ mdio_write(tp, 0x06, 0x2102); ++ mdio_write(tp, 0x06, 0xf62a); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x85ad); ++ mdio_write(tp, 0x06, 0x2308); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x20a0); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0xf62b); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x87ad); ++ mdio_write(tp, 0x06, 0x2408); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xc2a0); ++ mdio_write(tp, 0x06, 0x0302); ++ mdio_write(tp, 0x06, 0xf62c); ++ mdio_write(tp, 0x06, 0xe58a); ++ mdio_write(tp, 0x06, 0xf4a1); ++ mdio_write(tp, 0x06, 0x0008); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf22); ++ mdio_write(tp, 0x06, 0x7a02); ++ mdio_write(tp, 0x06, 0x387d); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0xc200); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x87ad); ++ mdio_write(tp, 0x06, 0x241e); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xc2a0); ++ mdio_write(tp, 0x06, 0x0005); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0xaaae); ++ mdio_write(tp, 0x06, 0xf5a0); ++ mdio_write(tp, 0x06, 0x0105); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0xbaae); ++ mdio_write(tp, 0x06, 0x0ba0); ++ mdio_write(tp, 0x06, 0x0205); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0xc4ae); ++ mdio_write(tp, 0x06, 0x03a0); ++ mdio_write(tp, 0x06, 0x0300); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0x0282); ++ mdio_write(tp, 0x06, 0xdbee); ++ mdio_write(tp, 0x06, 0x8ac2); ++ mdio_write(tp, 0x06, 0x01ef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8ee); ++ mdio_write(tp, 0x06, 0x8ac9); ++ mdio_write(tp, 0x06, 0x0002); ++ mdio_write(tp, 0x06, 0x8311); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8ac8); ++ mdio_write(tp, 0x06, 0xe18a); ++ mdio_write(tp, 0x06, 0xc91f); ++ mdio_write(tp, 0x06, 0x019e); ++ mdio_write(tp, 0x06, 0x0611); ++ mdio_write(tp, 0x06, 0xe58a); ++ mdio_write(tp, 0x06, 0xc9ae); ++ mdio_write(tp, 0x06, 0x04ee); ++ mdio_write(tp, 0x06, 0x8ac2); ++ mdio_write(tp, 0x06, 0x01fc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xf9fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0xfbbf); ++ mdio_write(tp, 0x06, 0x8ac4); ++ mdio_write(tp, 0x06, 0xef79); ++ mdio_write(tp, 0x06, 0xd200); ++ mdio_write(tp, 0x06, 0xd400); ++ mdio_write(tp, 0x06, 0x221e); ++ mdio_write(tp, 0x06, 0x02bf); ++ mdio_write(tp, 0x06, 0x3024); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x7dbf); ++ mdio_write(tp, 0x06, 0x13ff); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x500d); ++ mdio_write(tp, 0x06, 0x4559); ++ mdio_write(tp, 0x06, 0x1fef); ++ mdio_write(tp, 0x06, 0x97dd); ++ mdio_write(tp, 0x06, 0xd308); ++ mdio_write(tp, 0x06, 0x1a93); ++ mdio_write(tp, 0x06, 0xdd12); ++ mdio_write(tp, 0x06, 0x17a2); ++ mdio_write(tp, 0x06, 0x04de); ++ mdio_write(tp, 0x06, 0xffef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfdfc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xf9fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0xfbee); ++ mdio_write(tp, 0x06, 0x8ac2); ++ mdio_write(tp, 0x06, 0x03d5); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x06, 0xbf8a); ++ mdio_write(tp, 0x06, 0xc4ef); ++ mdio_write(tp, 0x06, 0x79ef); ++ mdio_write(tp, 0x06, 0x45bf); ++ mdio_write(tp, 0x06, 0x3024); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x7dbf); ++ mdio_write(tp, 0x06, 0x13ff); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x50ad); ++ mdio_write(tp, 0x06, 0x2702); ++ mdio_write(tp, 0x06, 0x78ff); ++ mdio_write(tp, 0x06, 0xe18a); ++ mdio_write(tp, 0x06, 0xca1b); ++ mdio_write(tp, 0x06, 0x01aa); ++ mdio_write(tp, 0x06, 0x2eef); ++ mdio_write(tp, 0x06, 0x97d9); ++ mdio_write(tp, 0x06, 0x7900); ++ mdio_write(tp, 0x06, 0x9e2b); ++ mdio_write(tp, 0x06, 0x81dd); ++ mdio_write(tp, 0x06, 0xbf85); ++ mdio_write(tp, 0x06, 0x1902); ++ mdio_write(tp, 0x06, 0x387d); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xef02); ++ mdio_write(tp, 0x06, 0x100c); ++ mdio_write(tp, 0x06, 0x11b0); ++ mdio_write(tp, 0x06, 0xfc0d); ++ mdio_write(tp, 0x06, 0x11bf); ++ mdio_write(tp, 0x06, 0x8516); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x7dd1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x8516); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x7dee); ++ mdio_write(tp, 0x06, 0x8ac2); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x0413); ++ mdio_write(tp, 0x06, 0xa38b); ++ mdio_write(tp, 0x06, 0xb4d3); ++ mdio_write(tp, 0x06, 0x8012); ++ mdio_write(tp, 0x06, 0x17a2); ++ mdio_write(tp, 0x06, 0x04ad); ++ mdio_write(tp, 0x06, 0xffef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfdfc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xf9e0); ++ mdio_write(tp, 0x06, 0x8b85); ++ mdio_write(tp, 0x06, 0xad25); ++ mdio_write(tp, 0x06, 0x48e0); ++ mdio_write(tp, 0x06, 0x8a96); ++ mdio_write(tp, 0x06, 0xe18a); ++ mdio_write(tp, 0x06, 0x977c); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x9e35); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0x9600); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0x9700); ++ mdio_write(tp, 0x06, 0xe08a); ++ mdio_write(tp, 0x06, 0xbee1); ++ mdio_write(tp, 0x06, 0x8abf); ++ mdio_write(tp, 0x06, 0xe28a); ++ mdio_write(tp, 0x06, 0xc0e3); ++ mdio_write(tp, 0x06, 0x8ac1); ++ mdio_write(tp, 0x06, 0x0237); ++ mdio_write(tp, 0x06, 0x74ad); ++ mdio_write(tp, 0x06, 0x2012); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0x9603); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0x97b7); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0xc000); ++ mdio_write(tp, 0x06, 0xee8a); ++ mdio_write(tp, 0x06, 0xc100); ++ mdio_write(tp, 0x06, 0xae11); ++ mdio_write(tp, 0x06, 0x15e6); ++ mdio_write(tp, 0x06, 0x8ac0); ++ mdio_write(tp, 0x06, 0xe78a); ++ mdio_write(tp, 0x06, 0xc1ae); ++ mdio_write(tp, 0x06, 0x08ee); ++ mdio_write(tp, 0x06, 0x8ac0); ++ mdio_write(tp, 0x06, 0x00ee); ++ mdio_write(tp, 0x06, 0x8ac1); ++ mdio_write(tp, 0x06, 0x00fd); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0xae20); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x00e1); ++ mdio_write(tp, 0x06, 0xe001); ++ mdio_write(tp, 0x06, 0xad27); ++ mdio_write(tp, 0x06, 0x32e0); ++ mdio_write(tp, 0x06, 0x8b40); ++ mdio_write(tp, 0x06, 0xf720); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x40bf); ++ mdio_write(tp, 0x06, 0x3230); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x50ad); ++ mdio_write(tp, 0x06, 0x2821); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x20e1); ++ mdio_write(tp, 0x06, 0xe021); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x18e0); ++ mdio_write(tp, 0x06, 0x8b40); ++ mdio_write(tp, 0x06, 0xf620); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x40ee); ++ mdio_write(tp, 0x06, 0x8b3b); ++ mdio_write(tp, 0x06, 0xffe0); ++ mdio_write(tp, 0x06, 0x8a8a); ++ mdio_write(tp, 0x06, 0xe18a); ++ mdio_write(tp, 0x06, 0x8be4); ++ mdio_write(tp, 0x06, 0xe000); ++ mdio_write(tp, 0x06, 0xe5e0); ++ mdio_write(tp, 0x06, 0x01ef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xface); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69fa); ++ mdio_write(tp, 0x06, 0xd401); ++ mdio_write(tp, 0x06, 0x55b4); ++ mdio_write(tp, 0x06, 0xfebf); ++ mdio_write(tp, 0x06, 0x1c1e); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x50ac); ++ mdio_write(tp, 0x06, 0x280b); ++ mdio_write(tp, 0x06, 0xbf1c); ++ mdio_write(tp, 0x06, 0x1b02); ++ mdio_write(tp, 0x06, 0x3850); ++ mdio_write(tp, 0x06, 0xac28); ++ mdio_write(tp, 0x06, 0x49ae); ++ mdio_write(tp, 0x06, 0x64bf); ++ mdio_write(tp, 0x06, 0x1c1b); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x50ac); ++ mdio_write(tp, 0x06, 0x285b); ++ mdio_write(tp, 0x06, 0xd000); ++ mdio_write(tp, 0x06, 0x0284); ++ mdio_write(tp, 0x06, 0xc4ac); ++ mdio_write(tp, 0x06, 0x2105); ++ mdio_write(tp, 0x06, 0xac22); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x4ebf); ++ mdio_write(tp, 0x06, 0xe0c4); ++ mdio_write(tp, 0x06, 0xbe85); ++ mdio_write(tp, 0x06, 0xf6d2); ++ mdio_write(tp, 0x06, 0x04d8); ++ mdio_write(tp, 0x06, 0x19d9); ++ mdio_write(tp, 0x06, 0x1907); ++ mdio_write(tp, 0x06, 0xdc19); ++ mdio_write(tp, 0x06, 0xdd19); ++ mdio_write(tp, 0x06, 0x0789); ++ mdio_write(tp, 0x06, 0x89ef); ++ mdio_write(tp, 0x06, 0x645e); ++ mdio_write(tp, 0x06, 0x07ff); ++ mdio_write(tp, 0x06, 0x0d65); ++ mdio_write(tp, 0x06, 0x5cf8); ++ mdio_write(tp, 0x06, 0x001e); ++ mdio_write(tp, 0x06, 0x46dc); ++ mdio_write(tp, 0x06, 0x19dd); ++ mdio_write(tp, 0x06, 0x19b2); ++ mdio_write(tp, 0x06, 0xe2d4); ++ mdio_write(tp, 0x06, 0x0001); ++ mdio_write(tp, 0x06, 0xbf1c); ++ mdio_write(tp, 0x06, 0x1b02); ++ mdio_write(tp, 0x06, 0x387d); ++ mdio_write(tp, 0x06, 0xae1d); ++ mdio_write(tp, 0x06, 0xbee0); ++ mdio_write(tp, 0x06, 0xc4bf); ++ mdio_write(tp, 0x06, 0x85f6); ++ mdio_write(tp, 0x06, 0xd204); ++ mdio_write(tp, 0x06, 0xd819); ++ mdio_write(tp, 0x06, 0xd919); ++ mdio_write(tp, 0x06, 0x07dc); ++ mdio_write(tp, 0x06, 0x19dd); ++ mdio_write(tp, 0x06, 0x1907); ++ mdio_write(tp, 0x06, 0xb2f4); ++ mdio_write(tp, 0x06, 0xd400); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x1c1b); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x7dfe); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfec6); ++ mdio_write(tp, 0x06, 0xfefd); ++ mdio_write(tp, 0x06, 0xfc05); ++ mdio_write(tp, 0x06, 0xf9e2); ++ mdio_write(tp, 0x06, 0xe0ea); ++ mdio_write(tp, 0x06, 0xe3e0); ++ mdio_write(tp, 0x06, 0xeb5a); ++ mdio_write(tp, 0x06, 0x070c); ++ mdio_write(tp, 0x06, 0x031e); ++ mdio_write(tp, 0x06, 0x20e6); ++ mdio_write(tp, 0x06, 0xe0ea); ++ mdio_write(tp, 0x06, 0xe7e0); ++ mdio_write(tp, 0x06, 0xebe0); ++ mdio_write(tp, 0x06, 0xe0fc); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0xfdfd); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69e0); ++ mdio_write(tp, 0x06, 0x8b80); ++ mdio_write(tp, 0x06, 0xad27); ++ mdio_write(tp, 0x06, 0x22bf); ++ mdio_write(tp, 0x06, 0x4616); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x50e0); ++ mdio_write(tp, 0x06, 0x8b44); ++ mdio_write(tp, 0x06, 0x1f01); ++ mdio_write(tp, 0x06, 0x9e15); ++ mdio_write(tp, 0x06, 0xe58b); ++ mdio_write(tp, 0x06, 0x44ad); ++ mdio_write(tp, 0x06, 0x2907); ++ mdio_write(tp, 0x06, 0xac28); ++ mdio_write(tp, 0x06, 0x04d1); ++ mdio_write(tp, 0x06, 0x01ae); ++ mdio_write(tp, 0x06, 0x02d1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x851c); ++ mdio_write(tp, 0x06, 0x0238); ++ mdio_write(tp, 0x06, 0x7def); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0x00e1); ++ mdio_write(tp, 0x06, 0x4077); ++ mdio_write(tp, 0x06, 0xe140); ++ mdio_write(tp, 0x06, 0x52e0); ++ mdio_write(tp, 0x06, 0xeed9); ++ mdio_write(tp, 0x06, 0xe04c); ++ mdio_write(tp, 0x06, 0xbbe0); ++ mdio_write(tp, 0x06, 0x2a00); ++ mdio_write(tp, 0x05, 0xe142); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x05, 0xe140); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0005); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x00); ++ if (gphy_val & BIT_7) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ gphy_val = mdio_read(tp, 0x17); ++ gphy_val |= BIT_1; ++ mdio_write(tp, 0x17, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x9200); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8b80); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_2 | BIT_1; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x002D); ++ gphy_val = mdio_read(tp, 0x18); ++ gphy_val |= BIT_4; ++ mdio_write(tp, 0x18, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ gphy_val = mdio_read(tp, 0x14); ++ gphy_val |= BIT_15; ++ mdio_write(tp, 0x14, gphy_val); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B86); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B85); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_14; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x09, 0xA20F); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B55); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x05, 0x8B5E); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x05, 0x8B67); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x05, 0x8B70); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x0078); ++ mdio_write(tp, 0x17, 0x0000); ++ mdio_write(tp, 0x19, 0x00FB); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B79); ++ mdio_write(tp, 0x06, 0xAA00); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1f, 0x0003); ++ mdio_write(tp, 0x01, 0x328A); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1f, 0x0000); ++ gphy_val = mdio_read(tp, 0x15); ++ gphy_val |= BIT_12; ++ mdio_write(tp, 0x15, gphy_val); ++ } else if (tp->mcfg == CFG_METHOD_19) { ++ RTL_W8(0x6E, RTL_R8(0x6E) | BIT_6); ++ rtl8168_eri_write(ioaddr, 0x1AE, 2, 0x0403, ERIAR_ExGMAC); ++ ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x1800); ++ gphy_val = mdio_read(tp, 0x15); ++ gphy_val &= ~(BIT_12); ++ mdio_write(tp, 0x15, gphy_val); ++ mdio_write(tp, 0x00, 0x9800); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x002f); ++ for (i = 0; i < 1000; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x1c); ++ if (gphy_val & 0x0080) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0307); ++ mdio_write(tp, 0x15, 0x0098); ++ mdio_write(tp, 0x19, 0x7c0b); ++ mdio_write(tp, 0x15, 0x0099); ++ mdio_write(tp, 0x19, 0x6c0b); ++ mdio_write(tp, 0x15, 0x00eb); ++ mdio_write(tp, 0x19, 0x6c0b); ++ mdio_write(tp, 0x15, 0x00f8); ++ mdio_write(tp, 0x19, 0x6f0b); ++ mdio_write(tp, 0x15, 0x00fe); ++ mdio_write(tp, 0x19, 0x6f0f); ++ mdio_write(tp, 0x15, 0x00db); ++ mdio_write(tp, 0x19, 0x6f09); ++ mdio_write(tp, 0x15, 0x00dc); ++ mdio_write(tp, 0x19, 0xaefd); ++ mdio_write(tp, 0x15, 0x00dd); ++ mdio_write(tp, 0x19, 0x6f0b); ++ mdio_write(tp, 0x15, 0x00de); ++ mdio_write(tp, 0x19, 0xc60b); ++ mdio_write(tp, 0x15, 0x00df); ++ mdio_write(tp, 0x19, 0x00fa); ++ mdio_write(tp, 0x15, 0x00e0); ++ mdio_write(tp, 0x19, 0x30e1); ++ mdio_write(tp, 0x15, 0x0000); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0300); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x05, 0x8000); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0x48f7); ++ mdio_write(tp, 0x06, 0x00e0); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0xa080); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0xf602); ++ mdio_write(tp, 0x06, 0x011b); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x2802); ++ mdio_write(tp, 0x06, 0x0135); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x4502); ++ mdio_write(tp, 0x06, 0x015f); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x7602); ++ mdio_write(tp, 0x06, 0x806b); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x88e1); ++ mdio_write(tp, 0x06, 0x8b89); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8a1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8b); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8c1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8e1e); ++ mdio_write(tp, 0x06, 0x01a0); ++ mdio_write(tp, 0x06, 0x00c7); ++ mdio_write(tp, 0x06, 0xaebb); ++ mdio_write(tp, 0x06, 0xbf8b); ++ mdio_write(tp, 0x06, 0x88ec); ++ mdio_write(tp, 0x06, 0x0019); ++ mdio_write(tp, 0x06, 0xa98b); ++ mdio_write(tp, 0x06, 0x90f9); ++ mdio_write(tp, 0x06, 0xeeff); ++ mdio_write(tp, 0x06, 0xf600); ++ mdio_write(tp, 0x06, 0xeeff); ++ mdio_write(tp, 0x06, 0xf7fe); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf81); ++ mdio_write(tp, 0x06, 0x1e02); ++ mdio_write(tp, 0x06, 0x39f3); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xbf81); ++ mdio_write(tp, 0x06, 0x2102); ++ mdio_write(tp, 0x06, 0x39f3); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x201a); ++ mdio_write(tp, 0x06, 0xf620); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x2afe); ++ mdio_write(tp, 0x06, 0x022c); ++ mdio_write(tp, 0x06, 0x5c02); ++ mdio_write(tp, 0x06, 0x03c5); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0xed02); ++ mdio_write(tp, 0x06, 0x2e4f); ++ mdio_write(tp, 0x06, 0x0204); ++ mdio_write(tp, 0x06, 0x8902); ++ mdio_write(tp, 0x06, 0x2f7a); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x210b); ++ mdio_write(tp, 0x06, 0xf621); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x0445); ++ mdio_write(tp, 0x06, 0x021c); ++ mdio_write(tp, 0x06, 0xb8e0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad22); ++ mdio_write(tp, 0x06, 0x08f6); ++ mdio_write(tp, 0x06, 0x22e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x0235); ++ mdio_write(tp, 0x06, 0xd4e0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad23); ++ mdio_write(tp, 0x06, 0x08f6); ++ mdio_write(tp, 0x06, 0x23e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x0231); ++ mdio_write(tp, 0x06, 0xc8e0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad24); ++ mdio_write(tp, 0x06, 0x05f6); ++ mdio_write(tp, 0x06, 0x24e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2505); ++ mdio_write(tp, 0x06, 0xf625); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8ee0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad26); ++ mdio_write(tp, 0x06, 0x08f6); ++ mdio_write(tp, 0x06, 0x26e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x022d); ++ mdio_write(tp, 0x06, 0x6ae0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad27); ++ mdio_write(tp, 0x06, 0x05f6); ++ mdio_write(tp, 0x06, 0x27e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x0203); ++ mdio_write(tp, 0x06, 0x8bfc); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69e0); ++ mdio_write(tp, 0x06, 0x8b80); ++ mdio_write(tp, 0x06, 0xad27); ++ mdio_write(tp, 0x06, 0x22bf); ++ mdio_write(tp, 0x06, 0x479a); ++ mdio_write(tp, 0x06, 0x0239); ++ mdio_write(tp, 0x06, 0xc6e0); ++ mdio_write(tp, 0x06, 0x8b44); ++ mdio_write(tp, 0x06, 0x1f01); ++ mdio_write(tp, 0x06, 0x9e15); ++ mdio_write(tp, 0x06, 0xe58b); ++ mdio_write(tp, 0x06, 0x44ad); ++ mdio_write(tp, 0x06, 0x2907); ++ mdio_write(tp, 0x06, 0xac28); ++ mdio_write(tp, 0x06, 0x04d1); ++ mdio_write(tp, 0x06, 0x01ae); ++ mdio_write(tp, 0x06, 0x02d1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x8124); ++ mdio_write(tp, 0x06, 0x0239); ++ mdio_write(tp, 0x06, 0xf3ef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0x00e1); ++ mdio_write(tp, 0x06, 0x4077); ++ mdio_write(tp, 0x06, 0xe140); ++ mdio_write(tp, 0x06, 0xbbe0); ++ mdio_write(tp, 0x06, 0x2a00); ++ mdio_write(tp, 0x05, 0xe142); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x05, 0xe140); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ gphy_val = mdio_read(tp, 0x17); ++ gphy_val |= BIT_1; ++ mdio_write(tp, 0x17, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x9200); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8b80); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_2 | BIT_1; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x002D); ++ gphy_val = mdio_read(tp, 0x18); ++ gphy_val |= BIT_4; ++ mdio_write(tp, 0x18, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ gphy_val = mdio_read(tp, 0x14); ++ gphy_val |= BIT_15; ++ mdio_write(tp, 0x14, gphy_val); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B86); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1f, 0x0000); ++ gphy_val = mdio_read(tp, 0x15); ++ gphy_val |= BIT_12; ++ mdio_write(tp, 0x15, gphy_val); ++ } else if (tp->mcfg == CFG_METHOD_20) { ++ RTL_W8(0x6E, RTL_R8(0x6E) | BIT_6); ++ rtl8168_eri_write(ioaddr, 0x1AE, 2, 0x0403, ERIAR_ExGMAC); ++ ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x1800); ++ gphy_val = mdio_read(tp, 0x15); ++ gphy_val &= ~(BIT_12); ++ mdio_write(tp, 0x15, gphy_val); ++ mdio_write(tp, 0x00, 0x4800); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x002f); ++ for (i = 0; i < 1000; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x1c); ++ if (gphy_val & 0x0080) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x1800); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x18); ++ if (!(gphy_val & 0x0001)) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0307); ++ mdio_write(tp, 0x15, 0x0098); ++ mdio_write(tp, 0x19, 0x7c0b); ++ mdio_write(tp, 0x15, 0x0099); ++ mdio_write(tp, 0x19, 0x6c0b); ++ mdio_write(tp, 0x15, 0x00eb); ++ mdio_write(tp, 0x19, 0x6c0b); ++ mdio_write(tp, 0x15, 0x00f8); ++ mdio_write(tp, 0x19, 0x6f0b); ++ mdio_write(tp, 0x15, 0x00fe); ++ mdio_write(tp, 0x19, 0x6f0f); ++ mdio_write(tp, 0x15, 0x00db); ++ mdio_write(tp, 0x19, 0x6f09); ++ mdio_write(tp, 0x15, 0x00dc); ++ mdio_write(tp, 0x19, 0xaefd); ++ mdio_write(tp, 0x15, 0x00dd); ++ mdio_write(tp, 0x19, 0x6f0b); ++ mdio_write(tp, 0x15, 0x00de); ++ mdio_write(tp, 0x19, 0xc60b); ++ mdio_write(tp, 0x15, 0x00df); ++ mdio_write(tp, 0x19, 0x00fa); ++ mdio_write(tp, 0x15, 0x00e0); ++ mdio_write(tp, 0x19, 0x30e1); ++ mdio_write(tp, 0x15, 0x0000); ++ mdio_write(tp, 0x16, 0x0306); ++ mdio_write(tp, 0x16, 0x0300); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0005); ++ mdio_write(tp, 0x05, 0xfff6); ++ mdio_write(tp, 0x06, 0x0080); ++ mdio_write(tp, 0x05, 0x8000); ++ mdio_write(tp, 0x06, 0x0280); ++ mdio_write(tp, 0x06, 0x48f7); ++ mdio_write(tp, 0x06, 0x00e0); ++ mdio_write(tp, 0x06, 0xfff7); ++ mdio_write(tp, 0x06, 0xa080); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0xf602); ++ mdio_write(tp, 0x06, 0x011e); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x2b02); ++ mdio_write(tp, 0x06, 0x8077); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x4802); ++ mdio_write(tp, 0x06, 0x0162); ++ mdio_write(tp, 0x06, 0x0201); ++ mdio_write(tp, 0x06, 0x7902); ++ mdio_write(tp, 0x06, 0x8094); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x88e1); ++ mdio_write(tp, 0x06, 0x8b89); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8a1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8b); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8c1e); ++ mdio_write(tp, 0x06, 0x01e1); ++ mdio_write(tp, 0x06, 0x8b8d); ++ mdio_write(tp, 0x06, 0x1e01); ++ mdio_write(tp, 0x06, 0xe18b); ++ mdio_write(tp, 0x06, 0x8e1e); ++ mdio_write(tp, 0x06, 0x01a0); ++ mdio_write(tp, 0x06, 0x00c7); ++ mdio_write(tp, 0x06, 0xaebb); ++ mdio_write(tp, 0x06, 0xd481); ++ mdio_write(tp, 0x06, 0x5ae4); ++ mdio_write(tp, 0x06, 0x8b92); ++ mdio_write(tp, 0x06, 0xe58b); ++ mdio_write(tp, 0x06, 0x9302); ++ mdio_write(tp, 0x06, 0x2e5a); ++ mdio_write(tp, 0x06, 0xbf8b); ++ mdio_write(tp, 0x06, 0x88ec); ++ mdio_write(tp, 0x06, 0x0019); ++ mdio_write(tp, 0x06, 0xa98b); ++ mdio_write(tp, 0x06, 0x90f9); ++ mdio_write(tp, 0x06, 0xeeff); ++ mdio_write(tp, 0x06, 0xf600); ++ mdio_write(tp, 0x06, 0xeeff); ++ mdio_write(tp, 0x06, 0xf7fc); ++ mdio_write(tp, 0x06, 0xd100); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0x3402); ++ mdio_write(tp, 0x06, 0x3a21); ++ mdio_write(tp, 0x06, 0xd101); ++ mdio_write(tp, 0x06, 0xbf82); ++ mdio_write(tp, 0x06, 0x3702); ++ mdio_write(tp, 0x06, 0x3a21); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8aad); ++ mdio_write(tp, 0x06, 0x2014); ++ mdio_write(tp, 0x06, 0xee8b); ++ mdio_write(tp, 0x06, 0x8a00); ++ mdio_write(tp, 0x06, 0x0220); ++ mdio_write(tp, 0x06, 0x8be0); ++ mdio_write(tp, 0x06, 0xe426); ++ mdio_write(tp, 0x06, 0xe1e4); ++ mdio_write(tp, 0x06, 0x27ee); ++ mdio_write(tp, 0x06, 0xe426); ++ mdio_write(tp, 0x06, 0x23e5); ++ mdio_write(tp, 0x06, 0xe427); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8e0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x1af6); ++ mdio_write(tp, 0x06, 0x20e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x022b); ++ mdio_write(tp, 0x06, 0x1e02); ++ mdio_write(tp, 0x06, 0x2c7c); ++ mdio_write(tp, 0x06, 0x0203); ++ mdio_write(tp, 0x06, 0xc002); ++ mdio_write(tp, 0x06, 0x8203); ++ mdio_write(tp, 0x06, 0x022e); ++ mdio_write(tp, 0x06, 0x6f02); ++ mdio_write(tp, 0x06, 0x047b); ++ mdio_write(tp, 0x06, 0x022f); ++ mdio_write(tp, 0x06, 0x9ae0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad21); ++ mdio_write(tp, 0x06, 0x0bf6); ++ mdio_write(tp, 0x06, 0x21e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0x1602); ++ mdio_write(tp, 0x06, 0x1cd9); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2208); ++ mdio_write(tp, 0x06, 0xf622); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x35f4); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2308); ++ mdio_write(tp, 0x06, 0xf623); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x31e8); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2405); ++ mdio_write(tp, 0x06, 0xf624); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8ee0); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xad25); ++ mdio_write(tp, 0x06, 0x05f6); ++ mdio_write(tp, 0x06, 0x25e4); ++ mdio_write(tp, 0x06, 0x8b8e); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2608); ++ mdio_write(tp, 0x06, 0xf626); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x2d8a); ++ mdio_write(tp, 0x06, 0xe08b); ++ mdio_write(tp, 0x06, 0x8ead); ++ mdio_write(tp, 0x06, 0x2705); ++ mdio_write(tp, 0x06, 0xf627); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x8e02); ++ mdio_write(tp, 0x06, 0x0386); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8fa); ++ mdio_write(tp, 0x06, 0xef69); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x00e1); ++ mdio_write(tp, 0x06, 0xe001); ++ mdio_write(tp, 0x06, 0xad27); ++ mdio_write(tp, 0x06, 0x32e0); ++ mdio_write(tp, 0x06, 0x8b40); ++ mdio_write(tp, 0x06, 0xf720); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x40bf); ++ mdio_write(tp, 0x06, 0x32c1); ++ mdio_write(tp, 0x06, 0x0239); ++ mdio_write(tp, 0x06, 0xf4ad); ++ mdio_write(tp, 0x06, 0x2821); ++ mdio_write(tp, 0x06, 0xe0e0); ++ mdio_write(tp, 0x06, 0x20e1); ++ mdio_write(tp, 0x06, 0xe021); ++ mdio_write(tp, 0x06, 0xad20); ++ mdio_write(tp, 0x06, 0x18e0); ++ mdio_write(tp, 0x06, 0x8b40); ++ mdio_write(tp, 0x06, 0xf620); ++ mdio_write(tp, 0x06, 0xe48b); ++ mdio_write(tp, 0x06, 0x40ee); ++ mdio_write(tp, 0x06, 0x8b3b); ++ mdio_write(tp, 0x06, 0xffe0); ++ mdio_write(tp, 0x06, 0x8a8a); ++ mdio_write(tp, 0x06, 0xe18a); ++ mdio_write(tp, 0x06, 0x8be4); ++ mdio_write(tp, 0x06, 0xe000); ++ mdio_write(tp, 0x06, 0xe5e0); ++ mdio_write(tp, 0x06, 0x01ef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0xf8f9); ++ mdio_write(tp, 0x06, 0xface); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69fa); ++ mdio_write(tp, 0x06, 0xd401); ++ mdio_write(tp, 0x06, 0x55b4); ++ mdio_write(tp, 0x06, 0xfebf); ++ mdio_write(tp, 0x06, 0x1c5e); ++ mdio_write(tp, 0x06, 0x0239); ++ mdio_write(tp, 0x06, 0xf4ac); ++ mdio_write(tp, 0x06, 0x280b); ++ mdio_write(tp, 0x06, 0xbf1c); ++ mdio_write(tp, 0x06, 0x5b02); ++ mdio_write(tp, 0x06, 0x39f4); ++ mdio_write(tp, 0x06, 0xac28); ++ mdio_write(tp, 0x06, 0x49ae); ++ mdio_write(tp, 0x06, 0x64bf); ++ mdio_write(tp, 0x06, 0x1c5b); ++ mdio_write(tp, 0x06, 0x0239); ++ mdio_write(tp, 0x06, 0xf4ac); ++ mdio_write(tp, 0x06, 0x285b); ++ mdio_write(tp, 0x06, 0xd000); ++ mdio_write(tp, 0x06, 0x0281); ++ mdio_write(tp, 0x06, 0xe8ac); ++ mdio_write(tp, 0x06, 0x2105); ++ mdio_write(tp, 0x06, 0xac22); ++ mdio_write(tp, 0x06, 0x02ae); ++ mdio_write(tp, 0x06, 0x4ebf); ++ mdio_write(tp, 0x06, 0xe0c4); ++ mdio_write(tp, 0x06, 0xbe85); ++ mdio_write(tp, 0x06, 0xecd2); ++ mdio_write(tp, 0x06, 0x04d8); ++ mdio_write(tp, 0x06, 0x19d9); ++ mdio_write(tp, 0x06, 0x1907); ++ mdio_write(tp, 0x06, 0xdc19); ++ mdio_write(tp, 0x06, 0xdd19); ++ mdio_write(tp, 0x06, 0x0789); ++ mdio_write(tp, 0x06, 0x89ef); ++ mdio_write(tp, 0x06, 0x645e); ++ mdio_write(tp, 0x06, 0x07ff); ++ mdio_write(tp, 0x06, 0x0d65); ++ mdio_write(tp, 0x06, 0x5cf8); ++ mdio_write(tp, 0x06, 0x001e); ++ mdio_write(tp, 0x06, 0x46dc); ++ mdio_write(tp, 0x06, 0x19dd); ++ mdio_write(tp, 0x06, 0x19b2); ++ mdio_write(tp, 0x06, 0xe2d4); ++ mdio_write(tp, 0x06, 0x0001); ++ mdio_write(tp, 0x06, 0xbf1c); ++ mdio_write(tp, 0x06, 0x5b02); ++ mdio_write(tp, 0x06, 0x3a21); ++ mdio_write(tp, 0x06, 0xae1d); ++ mdio_write(tp, 0x06, 0xbee0); ++ mdio_write(tp, 0x06, 0xc4bf); ++ mdio_write(tp, 0x06, 0x85ec); ++ mdio_write(tp, 0x06, 0xd204); ++ mdio_write(tp, 0x06, 0xd819); ++ mdio_write(tp, 0x06, 0xd919); ++ mdio_write(tp, 0x06, 0x07dc); ++ mdio_write(tp, 0x06, 0x19dd); ++ mdio_write(tp, 0x06, 0x1907); ++ mdio_write(tp, 0x06, 0xb2f4); ++ mdio_write(tp, 0x06, 0xd400); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x1c5b); ++ mdio_write(tp, 0x06, 0x023a); ++ mdio_write(tp, 0x06, 0x21fe); ++ mdio_write(tp, 0x06, 0xef96); ++ mdio_write(tp, 0x06, 0xfec6); ++ mdio_write(tp, 0x06, 0xfefd); ++ mdio_write(tp, 0x06, 0xfc05); ++ mdio_write(tp, 0x06, 0xf9e2); ++ mdio_write(tp, 0x06, 0xe0ea); ++ mdio_write(tp, 0x06, 0xe3e0); ++ mdio_write(tp, 0x06, 0xeb5a); ++ mdio_write(tp, 0x06, 0x070c); ++ mdio_write(tp, 0x06, 0x031e); ++ mdio_write(tp, 0x06, 0x20e6); ++ mdio_write(tp, 0x06, 0xe0ea); ++ mdio_write(tp, 0x06, 0xe7e0); ++ mdio_write(tp, 0x06, 0xebe0); ++ mdio_write(tp, 0x06, 0xe0fc); ++ mdio_write(tp, 0x06, 0xe1e0); ++ mdio_write(tp, 0x06, 0xfdfd); ++ mdio_write(tp, 0x06, 0x04f8); ++ mdio_write(tp, 0x06, 0xfaef); ++ mdio_write(tp, 0x06, 0x69e0); ++ mdio_write(tp, 0x06, 0x8b80); ++ mdio_write(tp, 0x06, 0xad27); ++ mdio_write(tp, 0x06, 0x22bf); ++ mdio_write(tp, 0x06, 0x47ba); ++ mdio_write(tp, 0x06, 0x0239); ++ mdio_write(tp, 0x06, 0xf4e0); ++ mdio_write(tp, 0x06, 0x8b44); ++ mdio_write(tp, 0x06, 0x1f01); ++ mdio_write(tp, 0x06, 0x9e15); ++ mdio_write(tp, 0x06, 0xe58b); ++ mdio_write(tp, 0x06, 0x44ad); ++ mdio_write(tp, 0x06, 0x2907); ++ mdio_write(tp, 0x06, 0xac28); ++ mdio_write(tp, 0x06, 0x04d1); ++ mdio_write(tp, 0x06, 0x01ae); ++ mdio_write(tp, 0x06, 0x02d1); ++ mdio_write(tp, 0x06, 0x00bf); ++ mdio_write(tp, 0x06, 0x823a); ++ mdio_write(tp, 0x06, 0x023a); ++ mdio_write(tp, 0x06, 0x21ef); ++ mdio_write(tp, 0x06, 0x96fe); ++ mdio_write(tp, 0x06, 0xfc04); ++ mdio_write(tp, 0x06, 0x00e1); ++ mdio_write(tp, 0x06, 0x4077); ++ mdio_write(tp, 0x06, 0xe140); ++ mdio_write(tp, 0x06, 0xbbe0); ++ mdio_write(tp, 0x06, 0x2a00); ++ mdio_write(tp, 0x05, 0xe142); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x05, 0xe140); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x1f, 0x0005); ++ for (i = 0; i < 200; i++) { ++ udelay(100); ++ gphy_val = mdio_read(tp, 0x00); ++ if (gphy_val & BIT_7) ++ break; ++ } ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x0023); ++ gphy_val = mdio_read(tp, 0x17); ++ gphy_val |= BIT_1; ++ mdio_write(tp, 0x17, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ mdio_write(tp, 0x00, 0x9200); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8b80); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_2 | BIT_1; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1f, 0x0007); ++ mdio_write(tp, 0x1e, 0x002D); ++ gphy_val = mdio_read(tp, 0x18); ++ gphy_val |= BIT_4; ++ mdio_write(tp, 0x18, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ gphy_val = mdio_read(tp, 0x14); ++ gphy_val |= BIT_15; ++ mdio_write(tp, 0x14, gphy_val); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B86); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_0; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B85); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_14; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1f, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0003); ++ mdio_write(tp, 0x09, 0xA20F); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B55); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x05, 0x8B5E); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x05, 0x8B67); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x05, 0x8B70); ++ mdio_write(tp, 0x06, 0x0000); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x0078); ++ mdio_write(tp, 0x17, 0x0000); ++ mdio_write(tp, 0x19, 0x00aa); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B79); ++ mdio_write(tp, 0x06, 0xAA00); ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ mdio_write(tp, 0x1f, 0x0000); ++ gphy_val = mdio_read(tp, 0x15); ++ gphy_val |= BIT_12; ++ mdio_write(tp, 0x15, gphy_val); ++ } ++ ++ mdio_write(tp, 0x1F, 0x0000); ++ ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ rtl8168_green_table(tp); ++ ++ if (eee_enable == 1) ++ rtl8168_enable_EEE(tp); ++ else ++ rtl8168_disable_EEE(tp); ++} ++ ++static inline void rtl8168_delete_esd_timer(struct net_device *dev, struct timer_list *timer) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ spin_lock_irq(&tp->lock); ++ del_timer_sync(timer); ++ spin_unlock_irq(&tp->lock); ++} ++ ++static inline void rtl8168_request_esd_timer(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ struct timer_list *timer = &tp->esd_timer; ++ ++ init_timer(timer); ++ timer->expires = jiffies + RTL8168_ESD_TIMEOUT; ++ timer->data = (unsigned long)(dev); ++ timer->function = rtl8168_esd_timer; ++ add_timer(timer); ++} ++ ++static inline void rtl8168_delete_link_timer(struct net_device *dev, struct timer_list *timer) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ spin_lock_irq(&tp->lock); ++ del_timer_sync(timer); ++ spin_unlock_irq(&tp->lock); ++} ++ ++static inline void rtl8168_request_link_timer(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ struct timer_list *timer = &tp->link_timer; ++ ++ init_timer(timer); ++ timer->expires = jiffies + RTL8168_LINK_TIMEOUT; ++ timer->data = (unsigned long)(dev); ++ timer->function = rtl8168_link_timer; ++ add_timer(timer); ++} ++ ++#ifdef CONFIG_NET_POLL_CONTROLLER ++/* ++ * Polling 'interrupt' - used by things like netconsole to send skbs ++ * without having to re-enable interrupts. It's not called while ++ * the interrupt routine is executing. ++ */ ++static void ++rtl8168_netpoll(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ struct pci_dev *pdev = tp->pci_dev; ++ ++ disable_irq(pdev->irq); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) ++ rtl8168_interrupt(pdev->irq, dev, NULL); ++#else ++ rtl8168_interrupt(pdev->irq, dev); ++#endif ++ enable_irq(pdev->irq); ++} ++#endif ++ ++static void ++rtl8168_release_board(struct pci_dev *pdev, ++ struct net_device *dev, ++ void __iomem *ioaddr) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ rtl8168_phy_power_down(dev); ++ ++ /* restore the original MAC address */ ++ rtl8168_rar_set(tp, tp->org_mac_addr); ++ ++ iounmap(ioaddr); ++ pci_release_regions(pdev); ++ pci_disable_device(pdev); ++ free_netdev(dev); ++} ++ ++/** ++ * rtl8168_set_mac_address - Change the Ethernet Address of the NIC ++ * @dev: network interface device structure ++ * @p: pointer to an address structure ++ * ++ * Return 0 on success, negative on failure ++ **/ ++static int ++rtl8168_set_mac_address(struct net_device *dev, ++ void *p) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ struct sockaddr *addr = p; ++ ++ if (!is_valid_ether_addr(addr->sa_data)) ++ return -EADDRNOTAVAIL; ++ ++ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); ++ ++ rtl8168_rar_set(tp, dev->dev_addr); ++ ++ return 0; ++} ++ ++/****************************************************************************** ++ * rtl8168_rar_set - Puts an ethernet address into a receive address register. ++ * ++ * tp - The private data structure for driver ++ * addr - Address to put into receive address register ++ *****************************************************************************/ ++void ++rtl8168_rar_set(struct rtl8168_private *tp, ++ uint8_t *addr) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ uint32_t rar_low = 0; ++ uint32_t rar_high = 0; ++ ++ rar_low = ((uint32_t) addr[0] | ++ ((uint32_t) addr[1] << 8) | ++ ((uint32_t) addr[2] << 16) | ++ ((uint32_t) addr[3] << 24)); ++ ++ rar_high = ((uint32_t) addr[4] | ++ ((uint32_t) addr[5] << 8)); ++ ++ RTL_W8(Cfg9346, Cfg9346_Unlock); ++ RTL_W32(MAC0, rar_low); ++ RTL_W32(MAC4, rar_high); ++ ++ if (tp->mcfg == CFG_METHOD_17) { ++ rtl8168_eri_write(ioaddr, 0xe0, 4, rar_low, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xe4, 4, rar_high, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xf0, 4, rar_low << 16, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xf4, 4, rar_low >> 16 | rar_high << 16, ERIAR_ExGMAC); ++ } ++ ++ RTL_W8(Cfg9346, Cfg9346_Lock); ++} ++ ++#ifdef ETHTOOL_OPS_COMPAT ++static int ethtool_get_settings(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_cmd cmd = { ETHTOOL_GSET }; ++ int err; ++ ++ if (!ethtool_ops->get_settings) ++ return -EOPNOTSUPP; ++ ++ err = ethtool_ops->get_settings(dev, &cmd); ++ if (err < 0) ++ return err; ++ ++ if (copy_to_user(useraddr, &cmd, sizeof(cmd))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_set_settings(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_cmd cmd; ++ ++ if (!ethtool_ops->set_settings) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&cmd, useraddr, sizeof(cmd))) ++ return -EFAULT; ++ ++ return ethtool_ops->set_settings(dev, &cmd); ++} ++ ++static int ethtool_get_drvinfo(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_drvinfo info; ++ struct ethtool_ops *ops = ethtool_ops; ++ ++ if (!ops->get_drvinfo) ++ return -EOPNOTSUPP; ++ ++ memset(&info, 0, sizeof(info)); ++ info.cmd = ETHTOOL_GDRVINFO; ++ ops->get_drvinfo(dev, &info); ++ ++ if (ops->self_test_count) ++ info.testinfo_len = ops->self_test_count(dev); ++ if (ops->get_stats_count) ++ info.n_stats = ops->get_stats_count(dev); ++ if (ops->get_regs_len) ++ info.regdump_len = ops->get_regs_len(dev); ++ if (ops->get_eeprom_len) ++ info.eedump_len = ops->get_eeprom_len(dev); ++ ++ if (copy_to_user(useraddr, &info, sizeof(info))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_get_regs(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_regs regs; ++ struct ethtool_ops *ops = ethtool_ops; ++ void *regbuf; ++ int reglen, ret; ++ ++ if (!ops->get_regs || !ops->get_regs_len) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(®s, useraddr, sizeof(regs))) ++ return -EFAULT; ++ ++ reglen = ops->get_regs_len(dev); ++ if (regs.len > reglen) ++ regs.len = reglen; ++ ++ regbuf = kmalloc(reglen, GFP_USER); ++ if (!regbuf) ++ return -ENOMEM; ++ ++ ops->get_regs(dev, ®s, regbuf); ++ ++ ret = -EFAULT; ++ if (copy_to_user(useraddr, ®s, sizeof(regs))) ++ goto out; ++ useraddr += offsetof(struct ethtool_regs, data); ++ if (copy_to_user(useraddr, regbuf, reglen)) ++ goto out; ++ ret = 0; ++ ++out: ++ kfree(regbuf); ++ return ret; ++} ++ ++static int ethtool_get_wol(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; ++ ++ if (!ethtool_ops->get_wol) ++ return -EOPNOTSUPP; ++ ++ ethtool_ops->get_wol(dev, &wol); ++ ++ if (copy_to_user(useraddr, &wol, sizeof(wol))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_set_wol(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_wolinfo wol; ++ ++ if (!ethtool_ops->set_wol) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&wol, useraddr, sizeof(wol))) ++ return -EFAULT; ++ ++ return ethtool_ops->set_wol(dev, &wol); ++} ++ ++static int ethtool_get_msglevel(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata = { ETHTOOL_GMSGLVL }; ++ ++ if (!ethtool_ops->get_msglevel) ++ return -EOPNOTSUPP; ++ ++ edata.data = ethtool_ops->get_msglevel(dev); ++ ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_set_msglevel(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata; ++ ++ if (!ethtool_ops->set_msglevel) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&edata, useraddr, sizeof(edata))) ++ return -EFAULT; ++ ++ ethtool_ops->set_msglevel(dev, edata.data); ++ return 0; ++} ++ ++static int ethtool_nway_reset(struct net_device *dev) ++{ ++ if (!ethtool_ops->nway_reset) ++ return -EOPNOTSUPP; ++ ++ return ethtool_ops->nway_reset(dev); ++} ++ ++static int ethtool_get_link(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_value edata = { ETHTOOL_GLINK }; ++ ++ if (!ethtool_ops->get_link) ++ return -EOPNOTSUPP; ++ ++ edata.data = ethtool_ops->get_link(dev); ++ ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_get_eeprom(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_eeprom eeprom; ++ struct ethtool_ops *ops = ethtool_ops; ++ u8 *data; ++ int ret; ++ ++ if (!ops->get_eeprom || !ops->get_eeprom_len) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) ++ return -EFAULT; ++ ++ /* Check for wrap and zero */ ++ if (eeprom.offset + eeprom.len <= eeprom.offset) ++ return -EINVAL; ++ ++ /* Check for exceeding total eeprom len */ ++ if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) ++ return -EINVAL; ++ ++ data = kmalloc(eeprom.len, GFP_USER); ++ if (!data) ++ return -ENOMEM; ++ ++ ret = -EFAULT; ++ if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len)) ++ goto out; ++ ++ ret = ops->get_eeprom(dev, &eeprom, data); ++ if (ret) ++ goto out; ++ ++ ret = -EFAULT; ++ if (copy_to_user(useraddr, &eeprom, sizeof(eeprom))) ++ goto out; ++ if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len)) ++ goto out; ++ ret = 0; ++ ++out: ++ kfree(data); ++ return ret; ++} ++ ++static int ethtool_set_eeprom(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_eeprom eeprom; ++ struct ethtool_ops *ops = ethtool_ops; ++ u8 *data; ++ int ret; ++ ++ if (!ops->set_eeprom || !ops->get_eeprom_len) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) ++ return -EFAULT; ++ ++ /* Check for wrap and zero */ ++ if (eeprom.offset + eeprom.len <= eeprom.offset) ++ return -EINVAL; ++ ++ /* Check for exceeding total eeprom len */ ++ if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) ++ return -EINVAL; ++ ++ data = kmalloc(eeprom.len, GFP_USER); ++ if (!data) ++ return -ENOMEM; ++ ++ ret = -EFAULT; ++ if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len)) ++ goto out; ++ ++ ret = ops->set_eeprom(dev, &eeprom, data); ++ if (ret) ++ goto out; ++ ++ if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len)) ++ ret = -EFAULT; ++ ++out: ++ kfree(data); ++ return ret; ++} ++ ++static int ethtool_get_coalesce(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_coalesce coalesce = { ETHTOOL_GCOALESCE }; ++ ++ if (!ethtool_ops->get_coalesce) ++ return -EOPNOTSUPP; ++ ++ ethtool_ops->get_coalesce(dev, &coalesce); ++ ++ if (copy_to_user(useraddr, &coalesce, sizeof(coalesce))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_set_coalesce(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_coalesce coalesce; ++ ++ if (!ethtool_ops->get_coalesce) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) ++ return -EFAULT; ++ ++ return ethtool_ops->set_coalesce(dev, &coalesce); ++} ++ ++static int ethtool_get_ringparam(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_ringparam ringparam = { ETHTOOL_GRINGPARAM }; ++ ++ if (!ethtool_ops->get_ringparam) ++ return -EOPNOTSUPP; ++ ++ ethtool_ops->get_ringparam(dev, &ringparam); ++ ++ if (copy_to_user(useraddr, &ringparam, sizeof(ringparam))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_set_ringparam(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_ringparam ringparam; ++ ++ if (!ethtool_ops->get_ringparam) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&ringparam, useraddr, sizeof(ringparam))) ++ return -EFAULT; ++ ++ return ethtool_ops->set_ringparam(dev, &ringparam); ++} ++ ++static int ethtool_get_pauseparam(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; ++ ++ if (!ethtool_ops->get_pauseparam) ++ return -EOPNOTSUPP; ++ ++ ethtool_ops->get_pauseparam(dev, &pauseparam); ++ ++ if (copy_to_user(useraddr, &pauseparam, sizeof(pauseparam))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_set_pauseparam(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_pauseparam pauseparam; ++ ++ if (!ethtool_ops->get_pauseparam) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) ++ return -EFAULT; ++ ++ return ethtool_ops->set_pauseparam(dev, &pauseparam); ++} ++ ++static int ethtool_get_rx_csum(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata = { ETHTOOL_GRXCSUM }; ++ ++ if (!ethtool_ops->get_rx_csum) ++ return -EOPNOTSUPP; ++ ++ edata.data = ethtool_ops->get_rx_csum(dev); ++ ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_set_rx_csum(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata; ++ ++ if (!ethtool_ops->set_rx_csum) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&edata, useraddr, sizeof(edata))) ++ return -EFAULT; ++ ++ ethtool_ops->set_rx_csum(dev, edata.data); ++ return 0; ++} ++ ++static int ethtool_get_tx_csum(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata = { ETHTOOL_GTXCSUM }; ++ ++ if (!ethtool_ops->get_tx_csum) ++ return -EOPNOTSUPP; ++ ++ edata.data = ethtool_ops->get_tx_csum(dev); ++ ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_set_tx_csum(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata; ++ ++ if (!ethtool_ops->set_tx_csum) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&edata, useraddr, sizeof(edata))) ++ return -EFAULT; ++ ++ return ethtool_ops->set_tx_csum(dev, edata.data); ++} ++ ++static int ethtool_get_sg(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata = { ETHTOOL_GSG }; ++ ++ if (!ethtool_ops->get_sg) ++ return -EOPNOTSUPP; ++ ++ edata.data = ethtool_ops->get_sg(dev); ++ ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_set_sg(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata; ++ ++ if (!ethtool_ops->set_sg) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&edata, useraddr, sizeof(edata))) ++ return -EFAULT; ++ ++ return ethtool_ops->set_sg(dev, edata.data); ++} ++ ++static int ethtool_get_tso(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata = { ETHTOOL_GTSO }; ++ ++ if (!ethtool_ops->get_tso) ++ return -EOPNOTSUPP; ++ ++ edata.data = ethtool_ops->get_tso(dev); ++ ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; ++} ++ ++static int ethtool_set_tso(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata; ++ ++ if (!ethtool_ops->set_tso) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&edata, useraddr, sizeof(edata))) ++ return -EFAULT; ++ ++ return ethtool_ops->set_tso(dev, edata.data); ++} ++ ++static int ethtool_self_test(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_test test; ++ struct ethtool_ops *ops = ethtool_ops; ++ u64 *data; ++ int ret; ++ ++ if (!ops->self_test || !ops->self_test_count) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&test, useraddr, sizeof(test))) ++ return -EFAULT; ++ ++ test.len = ops->self_test_count(dev); ++ data = kmalloc(test.len * sizeof(u64), GFP_USER); ++ if (!data) ++ return -ENOMEM; ++ ++ ops->self_test(dev, &test, data); ++ ++ ret = -EFAULT; ++ if (copy_to_user(useraddr, &test, sizeof(test))) ++ goto out; ++ useraddr += sizeof(test); ++ if (copy_to_user(useraddr, data, test.len * sizeof(u64))) ++ goto out; ++ ret = 0; ++ ++out: ++ kfree(data); ++ return ret; ++} ++ ++static int ethtool_get_strings(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_gstrings gstrings; ++ struct ethtool_ops *ops = ethtool_ops; ++ u8 *data; ++ int ret; ++ ++ if (!ops->get_strings) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) ++ return -EFAULT; ++ ++ switch (gstrings.string_set) { ++ case ETH_SS_TEST: ++ if (!ops->self_test_count) ++ return -EOPNOTSUPP; ++ gstrings.len = ops->self_test_count(dev); ++ break; ++ case ETH_SS_STATS: ++ if (!ops->get_stats_count) ++ return -EOPNOTSUPP; ++ gstrings.len = ops->get_stats_count(dev); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); ++ if (!data) ++ return -ENOMEM; ++ ++ ops->get_strings(dev, gstrings.string_set, data); ++ ++ ret = -EFAULT; ++ if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) ++ goto out; ++ useraddr += sizeof(gstrings); ++ if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN)) ++ goto out; ++ ret = 0; ++ ++out: ++ kfree(data); ++ return ret; ++} ++ ++static int ethtool_phys_id(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_value id; ++ ++ if (!ethtool_ops->phys_id) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&id, useraddr, sizeof(id))) ++ return -EFAULT; ++ ++ return ethtool_ops->phys_id(dev, id.data); ++} ++ ++static int ethtool_get_stats(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_stats stats; ++ struct ethtool_ops *ops = ethtool_ops; ++ u64 *data; ++ int ret; ++ ++ if (!ops->get_ethtool_stats || !ops->get_stats_count) ++ return -EOPNOTSUPP; ++ ++ if (copy_from_user(&stats, useraddr, sizeof(stats))) ++ return -EFAULT; ++ ++ stats.n_stats = ops->get_stats_count(dev); ++ data = kmalloc(stats.n_stats * sizeof(u64), GFP_USER); ++ if (!data) ++ return -ENOMEM; ++ ++ ops->get_ethtool_stats(dev, &stats, data); ++ ++ ret = -EFAULT; ++ if (copy_to_user(useraddr, &stats, sizeof(stats))) ++ goto out; ++ useraddr += sizeof(stats); ++ if (copy_to_user(useraddr, data, stats.n_stats * sizeof(u64))) ++ goto out; ++ ret = 0; ++ ++out: ++ kfree(data); ++ return ret; ++} ++ ++static int ethtool_ioctl(struct ifreq *ifr) ++{ ++ struct net_device *dev = __dev_get_by_name(ifr->ifr_name); ++ void *useraddr = (void *) ifr->ifr_data; ++ u32 ethcmd; ++ ++ /* ++ * XXX: This can be pushed down into the ethtool_* handlers that ++ * need it. Keep existing behaviour for the moment. ++ */ ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ if (!dev || !netif_device_present(dev)) ++ return -ENODEV; ++ ++ if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd))) ++ return -EFAULT; ++ ++ switch (ethcmd) { ++ case ETHTOOL_GSET: ++ return ethtool_get_settings(dev, useraddr); ++ case ETHTOOL_SSET: ++ return ethtool_set_settings(dev, useraddr); ++ case ETHTOOL_GDRVINFO: ++ return ethtool_get_drvinfo(dev, useraddr); ++ case ETHTOOL_GREGS: ++ return ethtool_get_regs(dev, useraddr); ++ case ETHTOOL_GWOL: ++ return ethtool_get_wol(dev, useraddr); ++ case ETHTOOL_SWOL: ++ return ethtool_set_wol(dev, useraddr); ++ case ETHTOOL_GMSGLVL: ++ return ethtool_get_msglevel(dev, useraddr); ++ case ETHTOOL_SMSGLVL: ++ return ethtool_set_msglevel(dev, useraddr); ++ case ETHTOOL_NWAY_RST: ++ return ethtool_nway_reset(dev); ++ case ETHTOOL_GLINK: ++ return ethtool_get_link(dev, useraddr); ++ case ETHTOOL_GEEPROM: ++ return ethtool_get_eeprom(dev, useraddr); ++ case ETHTOOL_SEEPROM: ++ return ethtool_set_eeprom(dev, useraddr); ++ case ETHTOOL_GCOALESCE: ++ return ethtool_get_coalesce(dev, useraddr); ++ case ETHTOOL_SCOALESCE: ++ return ethtool_set_coalesce(dev, useraddr); ++ case ETHTOOL_GRINGPARAM: ++ return ethtool_get_ringparam(dev, useraddr); ++ case ETHTOOL_SRINGPARAM: ++ return ethtool_set_ringparam(dev, useraddr); ++ case ETHTOOL_GPAUSEPARAM: ++ return ethtool_get_pauseparam(dev, useraddr); ++ case ETHTOOL_SPAUSEPARAM: ++ return ethtool_set_pauseparam(dev, useraddr); ++ case ETHTOOL_GRXCSUM: ++ return ethtool_get_rx_csum(dev, useraddr); ++ case ETHTOOL_SRXCSUM: ++ return ethtool_set_rx_csum(dev, useraddr); ++ case ETHTOOL_GTXCSUM: ++ return ethtool_get_tx_csum(dev, useraddr); ++ case ETHTOOL_STXCSUM: ++ return ethtool_set_tx_csum(dev, useraddr); ++ case ETHTOOL_GSG: ++ return ethtool_get_sg(dev, useraddr); ++ case ETHTOOL_SSG: ++ return ethtool_set_sg(dev, useraddr); ++ case ETHTOOL_GTSO: ++ return ethtool_get_tso(dev, useraddr); ++ case ETHTOOL_STSO: ++ return ethtool_set_tso(dev, useraddr); ++ case ETHTOOL_TEST: ++ return ethtool_self_test(dev, useraddr); ++ case ETHTOOL_GSTRINGS: ++ return ethtool_get_strings(dev, useraddr); ++ case ETHTOOL_PHYS_ID: ++ return ethtool_phys_id(dev, useraddr); ++ case ETHTOOL_GSTATS: ++ return ethtool_get_stats(dev, useraddr); ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return -EOPNOTSUPP; ++} ++#endif //ETHTOOL_OPS_COMPAT ++ ++static int ++rtl8168_do_ioctl(struct net_device *dev, ++ struct ifreq *ifr, ++ int cmd) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ struct mii_ioctl_data *data = if_mii(ifr); ++ unsigned long flags; ++ int ret; ++ ++ ret = 0; ++ switch (cmd) { ++ case SIOCGMIIPHY: ++ data->phy_id = 32; /* Internal PHY */ ++ break; ++ ++ case SIOCGMIIREG: ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0000); ++ data->val_out = mdio_read(tp, data->reg_num); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ break; ++ ++ case SIOCSMIIREG: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, data->reg_num, data->val_in); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ break; ++ ++#ifdef ETHTOOL_OPS_COMPAT ++ case SIOCETHTOOL: ++ ret = ethtool_ioctl(ifr); ++ break; ++#endif ++ case SIOCDEVPRIVATE_RTLASF: ++ if (!netif_running(dev)) ++ { ++ ret = -ENODEV; ++ break; ++ } ++ ++ ret = rtl8168_asf_ioctl(dev, ifr); ++ break; ++ ++ case SIOCRTLTOOL: ++ ret = rtltool_ioctl(tp, ifr); ++ break; ++ ++ default: ++ ret = -EOPNOTSUPP; ++ break; ++ } ++ ++ return ret; ++} ++ ++static void ++rtl8168_phy_power_up (struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0000); ++ switch (tp->mcfg) { ++ case CFG_METHOD_1: ++ case CFG_METHOD_2: ++ case CFG_METHOD_3: ++ case CFG_METHOD_4: ++ case CFG_METHOD_5: ++ case CFG_METHOD_6: ++ case CFG_METHOD_7: ++ case CFG_METHOD_8: ++ case CFG_METHOD_9: ++ case CFG_METHOD_10: ++ case CFG_METHOD_11: ++ case CFG_METHOD_12: ++ case CFG_METHOD_13: ++ mdio_write(tp, 0x0E, 0x0000); ++ break; ++ default: ++ break; ++ } ++ mdio_write(tp, MII_BMCR, BMCR_ANENABLE); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++} ++ ++static void ++rtl8168_phy_power_down (struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0000); ++ switch (tp->mcfg) { ++ case CFG_METHOD_1: ++ case CFG_METHOD_2: ++ case CFG_METHOD_3: ++ case CFG_METHOD_4: ++ case CFG_METHOD_5: ++ case CFG_METHOD_6: ++ case CFG_METHOD_7: ++ case CFG_METHOD_8: ++ case CFG_METHOD_9: ++ case CFG_METHOD_10: ++ case CFG_METHOD_11: ++ case CFG_METHOD_12: ++ case CFG_METHOD_13: ++ mdio_write(tp, 0x0E, 0x0200); ++ mdio_write(tp, MII_BMCR, BMCR_PDOWN); ++ break; ++ case CFG_METHOD_14: ++ case CFG_METHOD_15: ++ mdio_write(tp, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN); ++ break; ++ default: ++ mdio_write(tp, MII_BMCR, BMCR_PDOWN); ++ break; ++ } ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++} ++ ++static int __devinit ++rtl8168_init_board(struct pci_dev *pdev, ++ struct net_device **dev_out, ++ void __iomem **ioaddr_out) ++{ ++ void __iomem *ioaddr; ++ struct net_device *dev; ++ struct rtl8168_private *tp; ++ int rc = -ENOMEM, i, pm_cap; ++ ++ assert(ioaddr_out != NULL); ++ ++ /* dev zeroed in alloc_etherdev */ ++ dev = alloc_etherdev(sizeof (*tp)); ++ if (dev == NULL) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ if (netif_msg_drv(&debug)) ++ dev_err(&pdev->dev, "unable to alloc new ethernet\n"); ++#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ goto err_out; ++ } ++ ++ SET_MODULE_OWNER(dev); ++ SET_NETDEV_DEV(dev, &pdev->dev); ++ tp = netdev_priv(dev); ++ tp->dev = dev; ++ tp->msg_enable = netif_msg_init(debug.msg_enable, R8168_MSG_DEFAULT); ++ ++ /* enable device (incl. PCI PM wakeup and hotplug setup) */ ++ rc = pci_enable_device(pdev); ++ if (rc < 0) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ if (netif_msg_probe(tp)) ++ dev_err(&pdev->dev, "enable failure\n"); ++#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ goto err_out_free_dev; ++ } ++ ++ rc = pci_set_mwi(pdev); ++ if (rc < 0) ++ goto err_out_disable; ++ ++ /* save power state before pci_enable_device overwrites it */ ++ pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); ++ if (pm_cap) { ++ u16 pwr_command; ++ ++ pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command); ++ } else { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ if (netif_msg_probe(tp)) { ++ dev_err(&pdev->dev, "PowerManagement capability not found.\n"); ++ } ++#else ++ printk("PowerManagement capability not found.\n"); ++#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ ++ } ++ ++ /* make sure PCI base addr 1 is MMIO */ ++ if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ if (netif_msg_probe(tp)) ++ dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n"); ++#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ rc = -ENODEV; ++ goto err_out_mwi; ++ } ++ /* check for weird/broken PCI region reporting */ ++ if (pci_resource_len(pdev, 2) < R8168_REGS_SIZE) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ if (netif_msg_probe(tp)) ++ dev_err(&pdev->dev, "Invalid PCI region size(s), aborting\n"); ++#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ rc = -ENODEV; ++ goto err_out_mwi; ++ } ++ ++ rc = pci_request_regions(pdev, MODULENAME); ++ if (rc < 0) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ if (netif_msg_probe(tp)) ++ dev_err(&pdev->dev, "could not request regions.\n"); ++#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ goto err_out_mwi; ++ } ++ ++ if ((sizeof(dma_addr_t) > 4) && ++ !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) { ++ dev->features |= NETIF_F_HIGHDMA; ++ } else { ++ rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); ++ if (rc < 0) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ if (netif_msg_probe(tp)) ++ dev_err(&pdev->dev, "DMA configuration failed.\n"); ++#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ goto err_out_free_res; ++ } ++ } ++ ++ pci_set_master(pdev); ++ ++ /* ioremap MMIO region */ ++ ioaddr = ioremap(pci_resource_start(pdev, 2), R8168_REGS_SIZE); ++ if (ioaddr == NULL) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ if (netif_msg_probe(tp)) ++ dev_err(&pdev->dev, "cannot remap MMIO, aborting\n"); ++#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ rc = -EIO; ++ goto err_out_free_res; ++ } ++ ++ /* Identify chip attached to board */ ++ rtl8168_get_mac_version(tp, ioaddr); ++ ++ rtl8168_print_mac_version(tp); ++ ++ for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) { ++ if (tp->mcfg == rtl_chip_info[i].mcfg) ++ break; ++ } ++ ++ if (i < 0) { ++ /* Unknown chip: assume array element #0, original RTL-8168 */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ if (netif_msg_probe(tp)) { ++ dev_printk(KERN_DEBUG, &pdev->dev, "unknown chip version, assuming %s\n", rtl_chip_info[0].name); ++ } ++#else ++ printk("Realtek unknown chip version, assuming %s\n", rtl_chip_info[0].name); ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ++ i++; ++ } ++ ++ tp->chipset = i; ++ ++// RTL_W8(Cfg9346, Cfg9346_Unlock); ++// RTL_W8(Config1, RTL_R8(Config1) | PMEnable); ++// RTL_W8(Config5, RTL_R8(Config5) & PMEStatus); ++// RTL_W8(Cfg9346, Cfg9346_Lock); ++ ++ *ioaddr_out = ioaddr; ++ *dev_out = dev; ++out: ++ return rc; ++ ++err_out_free_res: ++ pci_release_regions(pdev); ++ ++err_out_mwi: ++ pci_clear_mwi(pdev); ++ ++err_out_disable: ++ pci_disable_device(pdev); ++ ++err_out_free_dev: ++ free_netdev(dev); ++err_out: ++ *ioaddr_out = NULL; ++ *dev_out = NULL; ++ goto out; ++} ++ ++static void ++rtl8168_esd_timer(unsigned long __opaque) ++{ ++ struct net_device *dev = (struct net_device *)__opaque; ++ struct rtl8168_private *tp = netdev_priv(dev); ++ struct pci_dev *pdev = tp->pci_dev; ++ struct timer_list *timer = &tp->esd_timer; ++ unsigned long timeout = RTL8168_ESD_TIMEOUT; ++ u8 cmd; ++ u8 cls; ++ u16 io_base_l; ++ u16 io_base_h; ++ u16 mem_base_l; ++ u16 mem_base_h; ++ u8 ilr; ++ u16 resv_0x20_l; ++ u16 resv_0x20_h; ++ u16 resv_0x24_l; ++ u16 resv_0x24_h; ++ ++ tp->esd_flag = 0; ++ ++ pci_read_config_byte(pdev, PCI_COMMAND, &cmd); ++ if (cmd != tp->pci_cfg_space.cmd) { ++ pci_write_config_byte(pdev, PCI_COMMAND, tp->pci_cfg_space.cmd); ++ tp->esd_flag = 1; ++ } ++ ++ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cls); ++ if (cls != tp->pci_cfg_space.cls) { ++ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, tp->pci_cfg_space.cls); ++ tp->esd_flag = 1; ++ } ++ ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_0, &io_base_l); ++ if (io_base_l != tp->pci_cfg_space.io_base_l) { ++ pci_write_config_word(pdev, PCI_BASE_ADDRESS_0, tp->pci_cfg_space.io_base_l); ++ tp->esd_flag = 1; ++ } ++ ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_0 + 2, &io_base_h); ++ if (io_base_h != tp->pci_cfg_space.io_base_h) { ++ pci_write_config_word(pdev, PCI_BASE_ADDRESS_0 + 2, tp->pci_cfg_space.io_base_h); ++ tp->esd_flag = 1; ++ } ++ ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_2, &mem_base_l); ++ if (mem_base_l != tp->pci_cfg_space.mem_base_l) { ++ pci_write_config_word(pdev, PCI_BASE_ADDRESS_2, tp->pci_cfg_space.mem_base_l); ++ tp->esd_flag = 1; ++ } ++ ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_2 + 2, &mem_base_h); ++ if (mem_base_h != tp->pci_cfg_space.mem_base_h) { ++ pci_write_config_word(pdev, PCI_BASE_ADDRESS_2 + 2, tp->pci_cfg_space.mem_base_h); ++ tp->esd_flag = 1; ++ } ++ ++ pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &ilr); ++ if (ilr != tp->pci_cfg_space.ilr) { ++ pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, tp->pci_cfg_space.ilr); ++ tp->esd_flag = 1; ++ } ++ ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_4, &resv_0x20_l); ++ if (resv_0x20_l != tp->pci_cfg_space.resv_0x20_l) { ++ pci_write_config_word(pdev, PCI_BASE_ADDRESS_4, tp->pci_cfg_space.resv_0x20_l); ++ tp->esd_flag = 1; ++ } ++ ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_4 + 2, &resv_0x20_h); ++ if (resv_0x20_h != tp->pci_cfg_space.resv_0x20_h) { ++ pci_write_config_word(pdev, PCI_BASE_ADDRESS_4 + 2, tp->pci_cfg_space.resv_0x20_h); ++ tp->esd_flag = 1; ++ } ++ ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_5, &resv_0x24_l); ++ if (resv_0x24_l != tp->pci_cfg_space.resv_0x24_l) { ++ pci_write_config_word(pdev, PCI_BASE_ADDRESS_5, tp->pci_cfg_space.resv_0x24_l); ++ tp->esd_flag = 1; ++ } ++ ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_5 + 2, &resv_0x24_h); ++ if (resv_0x24_h != tp->pci_cfg_space.resv_0x24_h) { ++ pci_write_config_word(pdev, PCI_BASE_ADDRESS_5 + 2, tp->pci_cfg_space.resv_0x24_h); ++ tp->esd_flag = 1; ++ } ++ ++ if (tp->esd_flag != 0) { ++ rtl8168_tx_clear(tp); ++ rtl8168_hw_start(dev); ++ tp->esd_flag = 0; ++ } ++ ++ mod_timer(timer, jiffies + timeout); ++} ++ ++static void ++rtl8168_link_timer(unsigned long __opaque) ++{ ++ struct net_device *dev = (struct net_device *)__opaque; ++ struct rtl8168_private *tp = netdev_priv(dev); ++ struct timer_list *timer = &tp->link_timer; ++ ++ if (tp->link_ok(dev) != tp->old_link_status) ++ rtl8168_check_link_status(dev, tp, tp->mmio_addr); ++ ++ tp->old_link_status = tp->link_ok(dev); ++ ++ mod_timer(timer, jiffies + RTL8168_LINK_TIMEOUT); ++} ++ ++/* Cfg9346_Unlock assumed. */ ++static unsigned rtl8168_try_msi(struct pci_dev *pdev, void __iomem *ioaddr) ++{ ++ unsigned msi = 0; ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) ++ if (pci_enable_msi(pdev)) { ++ dev_info(&pdev->dev, "no MSI. Back to INTx.\n"); ++ } else { ++ msi |= RTL_FEATURE_MSI; ++ } ++#endif ++ ++ return msi; ++} ++ ++static void rtl8168_disable_msi(struct pci_dev *pdev, struct rtl8168_private *tp) ++{ ++ if (tp->features & RTL_FEATURE_MSI) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) ++ pci_disable_msi(pdev); ++#endif ++ tp->features &= ~RTL_FEATURE_MSI; ++ } ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) ++static const struct net_device_ops rtl8168_netdev_ops = { ++ .ndo_open = rtl8168_open, ++ .ndo_stop = rtl8168_close, ++ .ndo_get_stats = rtl8168_get_stats, ++ .ndo_start_xmit = rtl8168_start_xmit, ++ .ndo_tx_timeout = rtl8168_tx_timeout, ++ .ndo_change_mtu = rtl8168_change_mtu, ++ .ndo_set_mac_address = rtl8168_set_mac_address, ++ .ndo_do_ioctl = rtl8168_do_ioctl, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) ++ .ndo_set_multicast_list = rtl8168_set_rx_mode, ++#else ++ .ndo_set_rx_mode = rtl8168_set_rx_mode, ++#endif ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) ++#ifdef CONFIG_R8168_VLAN ++ .ndo_vlan_rx_register = rtl8168_vlan_rx_register, ++#endif ++#else ++ .ndo_fix_features = rtl8168_fix_features, ++ .ndo_set_features = rtl8168_set_features, ++#endif ++#ifdef CONFIG_NET_POLL_CONTROLLER ++ .ndo_poll_controller = rtl8168_netpoll, ++#endif ++}; ++#endif ++ ++static int __devinit ++rtl8168_init_one(struct pci_dev *pdev, ++ const struct pci_device_id *ent) ++{ ++ struct net_device *dev = NULL; ++ struct rtl8168_private *tp; ++ void __iomem *ioaddr = NULL; ++ static int board_idx = -1; ++ u8 autoneg, duplex; ++ u16 speed; ++ u16 mac_addr[4]; ++ ++ int i, rc; ++ ++ assert(pdev != NULL); ++ assert(ent != NULL); ++ ++ board_idx++; ++ ++ if (netif_msg_drv(&debug)) { ++ printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", ++ MODULENAME, RTL8168_VERSION); ++ } ++ ++ rc = rtl8168_init_board(pdev, &dev, &ioaddr); ++ if (rc) ++ return rc; ++ ++ tp = netdev_priv(dev); ++ assert(ioaddr != NULL); ++ ++ tp->mmio_addr = ioaddr; ++ tp->set_speed = rtl8168_set_speed_xmii; ++ tp->get_settings = rtl8168_gset_xmii; ++ tp->phy_reset_enable = rtl8168_xmii_reset_enable; ++ tp->phy_reset_pending = rtl8168_xmii_reset_pending; ++ tp->link_ok = rtl8168_xmii_link_ok; ++ ++ tp->features |= rtl8168_try_msi(pdev, ioaddr); ++ ++ if ((tp->mcfg == CFG_METHOD_9) || (tp->mcfg == CFG_METHOD_10)) { ++ RTL_W8(DBG_reg, RTL_R8(DBG_reg) | BIT_1 | BIT_7); ++ } ++ ++ /* Get production from EEPROM */ ++ rtl_eeprom_type(tp); ++ if (tp->eeprom_type != EEPROM_TYPE_NONE) { ++ /* Get MAC address from EEPROM */ ++ if (tp->mcfg == CFG_METHOD_16 || ++ tp->mcfg == CFG_METHOD_17 || ++ tp->mcfg == CFG_METHOD_18 || ++ tp->mcfg == CFG_METHOD_19 || ++ tp->mcfg == CFG_METHOD_20) { ++ mac_addr[0] = rtl_eeprom_read_sc(tp, 1); ++ mac_addr[1] = rtl_eeprom_read_sc(tp, 2); ++ mac_addr[2] = rtl_eeprom_read_sc(tp, 3); ++ } else { ++ mac_addr[0] = rtl_eeprom_read_sc(tp, 7); ++ mac_addr[1] = rtl_eeprom_read_sc(tp, 8); ++ mac_addr[2] = rtl_eeprom_read_sc(tp, 9); ++ } ++ mac_addr[3] = 0; ++ RTL_W8(Cfg9346, Cfg9346_Unlock); ++ RTL_W32(MAC0, (mac_addr[1] << 16) | mac_addr[0]); ++ RTL_W32(MAC4, (mac_addr[3] << 16) | mac_addr[2]); ++ RTL_W8(Cfg9346, Cfg9346_Lock); ++ } ++ ++ for (i = 0; i < MAC_ADDR_LEN; i++) { ++ dev->dev_addr[i] = RTL_R8(MAC0 + i); ++ tp->org_mac_addr[i] = dev->dev_addr[i]; /* keep the original MAC address */ ++ } ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) ++ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); ++#endif ++// memcpy(dev->dev_addr, dev->dev_addr, dev->addr_len); ++ ++ RTL_NET_DEVICE_OPS(rtl8168_netdev_ops); ++ ++ SET_ETHTOOL_OPS(dev, &rtl8168_ethtool_ops); ++ ++ dev->watchdog_timeo = RTL8168_TX_TIMEOUT; ++ dev->irq = pdev->irq; ++ dev->base_addr = (unsigned long) ioaddr; ++ ++#ifdef CONFIG_R8168_NAPI ++ RTL_NAPI_CONFIG(dev, tp, rtl8168_poll, R8168_NAPI_WEIGHT); ++#endif ++ ++#ifdef CONFIG_R8168_VLAN ++ if (tp->mcfg != CFG_METHOD_DEFAULT) { ++ dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ++ dev->vlan_rx_kill_vid = rtl8168_vlan_rx_kill_vid; ++#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ++ } ++#endif ++ ++ tp->cp_cmd |= RTL_R16(CPlusCmd); ++ if (tp->mcfg != CFG_METHOD_DEFAULT) { ++ dev->features |= NETIF_F_IP_CSUM; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) ++ tp->cp_cmd |= RxChkSum; ++#else ++ dev->features |= NETIF_F_RXCSUM; ++ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | ++ NETIF_F_RXCSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; ++ dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | ++ NETIF_F_HIGHDMA; ++#endif ++ } ++ ++ tp->intr_mask = rtl8168_intr_mask; ++ tp->pci_dev = pdev; ++ ++ tp->max_jumbo_frame_size = rtl_chip_info[tp->chipset].jumbo_frame_sz; ++ ++ spin_lock_init(&tp->lock); ++ spin_lock_init(&tp->phy_lock); ++ ++ pci_set_drvdata(pdev, dev); ++ ++ if (netif_msg_probe(tp)) { ++ printk(KERN_INFO "%s: %s at 0x%lx, " ++ "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " ++ "IRQ %d\n", ++ dev->name, ++ rtl_chip_info[tp->chipset].name, ++ dev->base_addr, ++ dev->dev_addr[0], dev->dev_addr[1], ++ dev->dev_addr[2], dev->dev_addr[3], ++ dev->dev_addr[4], dev->dev_addr[5], dev->irq); ++ } ++ ++ if (tp->mcfg == CFG_METHOD_11 || tp->mcfg==CFG_METHOD_12 || ++ tp->mcfg == CFG_METHOD_13) ++ rtl8168_driver_start(tp); ++ rtl8168_phy_power_up (dev); ++ rtl8168_hw_phy_config(dev); ++ ++ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40); ++ ++ rtl8168_link_option(board_idx, &autoneg, &speed, &duplex); ++ ++ rtl8168_set_speed(dev, autoneg, speed, duplex); ++ ++ rc = register_netdev(dev); ++ if (rc) { ++ rtl8168_release_board(pdev, dev, ioaddr); ++ return rc; ++ } ++ ++ printk(KERN_INFO "%s: This product is covered by one or more of the following patents: US5,307,459, US5,434,872, US5,732,094, US6,570,884, US6,115,776, and US6,327,625.\n", MODULENAME); ++ ++ if (netif_msg_probe(tp)) { ++ printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", ++ dev->name, rtl_chip_info[tp->chipset].name); ++ } ++ ++ printk("%s", GPL_CLAIM); ++ ++ return 0; ++} ++ ++static void __devexit ++rtl8168_remove_one(struct pci_dev *pdev) ++{ ++ struct net_device *dev = pci_get_drvdata(pdev); ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ assert(dev != NULL); ++ assert(tp != NULL); ++ ++ if (tp->mcfg == CFG_METHOD_11 || tp->mcfg==CFG_METHOD_12 || ++ tp->mcfg == CFG_METHOD_13) ++ rtl8168_driver_stop(tp); ++ flush_scheduled_work(); ++ ++ unregister_netdev(dev); ++ rtl8168_disable_msi(pdev, tp); ++ rtl8168_release_board(pdev, dev, tp->mmio_addr); ++ pci_set_drvdata(pdev, NULL); ++} ++ ++static void ++rtl8168_set_rxbufsize(struct rtl8168_private *tp, ++ struct net_device *dev) ++{ ++ void __iomem *ioaddr = tp->mmio_addr; ++ unsigned int mtu = dev->mtu; ++ ++ tp->rx_buf_sz = (mtu > ETH_DATA_LEN) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE; ++ ++ RTL_W16(RxMaxSize, tp->rx_buf_sz); ++} ++ ++static int rtl8168_open(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ struct pci_dev *pdev = tp->pci_dev; ++ int retval; ++ ++ rtl8168_set_rxbufsize(tp, dev); ++ ++ retval = -ENOMEM; ++ ++ /* ++ * Rx and Tx desscriptors needs 256 bytes alignment. ++ * pci_alloc_consistent provides more. ++ */ ++ tp->TxDescArray = pci_alloc_consistent(pdev, R8168_TX_RING_BYTES, ++ &tp->TxPhyAddr); ++ if (!tp->TxDescArray) ++ goto out; ++ ++ tp->RxDescArray = pci_alloc_consistent(pdev, R8168_RX_RING_BYTES, ++ &tp->RxPhyAddr); ++ if (!tp->RxDescArray) ++ goto err_free_tx; ++ ++ memset(tp->TxDescArray, 0, R8168_TX_RING_BYTES); ++ memset(tp->RxDescArray, 0, R8168_RX_RING_BYTES); ++ retval = rtl8168_init_ring(dev); ++ if (retval < 0) ++ goto err_free_rx; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ++ INIT_WORK(&tp->task, NULL, dev); ++#else ++ INIT_DELAYED_WORK(&tp->task, NULL); ++#endif ++ ++#ifdef CONFIG_R8168_NAPI ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ RTL_NAPI_ENABLE(dev, &tp->napi); ++#endif ++#endif ++ ++ rtl8168_powerup_pll(dev); ++ rtl8168_hw_start(dev); ++ ++ if (tp->esd_flag == 0) { ++ rtl8168_request_esd_timer(dev); ++ } ++ ++ rtl8168_request_link_timer(dev); ++ ++ rtl8168_dsm(dev, DSM_IF_UP); ++ ++ rtl8168_check_link_status(dev, tp, tp->mmio_addr); ++ ++ retval = request_irq(dev->irq, rtl8168_interrupt, (tp->features & RTL_FEATURE_MSI) ? 0 : SA_SHIRQ, dev->name, dev); ++ if (retval<0) ++ goto err_free_rx; ++ ++out: ++ return retval; ++ ++err_free_rx: ++ pci_free_consistent(pdev, R8168_RX_RING_BYTES, tp->RxDescArray, ++ tp->RxPhyAddr); ++ tp->RxDescArray = NULL; ++err_free_tx: ++ pci_free_consistent(pdev, R8168_TX_RING_BYTES, tp->TxDescArray, ++ tp->TxPhyAddr); ++ tp->TxDescArray = NULL; ++ goto out; ++} ++ ++static void ++rtl8168_hw_reset(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ /* Disable interrupts */ ++ rtl8168_irq_mask_and_ack(ioaddr); ++ ++ rtl8168_nic_reset(dev); ++} ++ ++static void ++rtl8168_dsm(struct net_device *dev, int dev_state) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ switch (dev_state) { ++ case DSM_MAC_INIT: ++ if ((tp->mcfg == CFG_METHOD_5) || (tp->mcfg == CFG_METHOD_6)) { ++ if (RTL_R8(MACDBG) & 0x80) { ++ RTL_W8(GPIO, RTL_R8(GPIO) | GPIO_en); ++ } else { ++ RTL_W8(GPIO, RTL_R8(GPIO) & ~GPIO_en); ++ } ++ } ++ ++ break; ++ case DSM_NIC_GOTO_D3: ++ case DSM_IF_DOWN: ++ if ((tp->mcfg == CFG_METHOD_5) || (tp->mcfg == CFG_METHOD_6)) ++ { ++ if (RTL_R8(MACDBG) & 0x80) ++ RTL_W8(GPIO, RTL_R8(GPIO) & ~GPIO_en); ++ } ++ break; ++ ++ case DSM_NIC_RESUME_D3: ++ case DSM_IF_UP: ++ if ((tp->mcfg == CFG_METHOD_5) || (tp->mcfg == CFG_METHOD_6)) ++ { ++ if (RTL_R8(MACDBG) & 0x80) ++ RTL_W8(GPIO, RTL_R8(GPIO) | GPIO_en); ++ } ++ ++ break; ++ } ++ ++} ++static void ++set_offset70F(struct rtl8168_private *tp, u8 setting) ++{ ++ ++ u32 csi_tmp; ++ u32 temp = (u32)setting; ++ temp = temp << 24; ++ /*set PCI configuration space offset 0x70F to setting*/ ++ /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/ ++ ++ csi_tmp = rtl8168_csi_read(tp, 0x70c) & 0x00ffffff; ++ rtl8168_csi_write(tp, 0x70c, csi_tmp | temp); ++} ++ ++static void ++set_offset79(struct rtl8168_private *tp, u8 setting) ++{ ++ //Set PCI configuration space offset 0x79 to setting ++ ++ struct pci_dev *pdev = tp->pci_dev; ++ u8 device_control; ++ ++ pci_read_config_byte(pdev, 0x79, &device_control); ++ device_control &= ~0x70; ++ device_control |= setting; ++ pci_write_config_byte(pdev, 0x79, device_control); ++ ++} ++static void ++rtl8168_hw_start(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ struct pci_dev *pdev = tp->pci_dev; ++ u8 device_control, options1, options2; ++ u16 ephy_data; ++ u32 csi_tmp; ++ ++ netif_stop_queue(dev); ++ switch (tp->mcfg) { ++ case CFG_METHOD_1: ++ case CFG_METHOD_2: ++ case CFG_METHOD_3: ++ case CFG_METHOD_4: ++ case CFG_METHOD_5: ++ case CFG_METHOD_6: ++ case CFG_METHOD_7: ++ case CFG_METHOD_8: ++ case CFG_METHOD_9: ++ case CFG_METHOD_10: ++ case CFG_METHOD_11: ++ case CFG_METHOD_12: ++ case CFG_METHOD_13: ++ case CFG_METHOD_14: ++ case CFG_METHOD_15: ++ break; ++ default: ++ RTL_W32(RxConfig, RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift)); ++ break; ++ } ++ ++ rtl8168_nic_reset(dev); ++ ++ rtl8168_rx_desc_offset0_init(tp, 1); ++ ++ RTL_W8(Cfg9346, Cfg9346_Unlock); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ ++ tp->cp_cmd |= PktCntrDisable | INTT_1; ++ RTL_W16(CPlusCmd, tp->cp_cmd); ++ ++ RTL_W16(IntrMitigate, 0x5151); ++ ++ //Work around for RxFIFO overflow ++ if (tp->mcfg == CFG_METHOD_1) { ++ rtl8168_intr_mask |= RxFIFOOver | PCSTimeout; ++ rtl8168_intr_mask &= ~RxDescUnavail; ++ } ++ ++ RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_BIT_MASK(32))); ++ RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32)); ++ RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_BIT_MASK(32))); ++ RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32)); ++ ++ /* Set DMA burst size and Interframe Gap Time */ ++ if (tp->mcfg == CFG_METHOD_1) { ++ RTL_W32(TxConfig, (TX_DMA_BURST_512 << TxDMAShift) | ++ (InterFrameGap << TxInterFrameGapShift)); ++ } else { ++ RTL_W32(TxConfig, (TX_DMA_BURST_unlimited << TxDMAShift) | ++ (InterFrameGap << TxInterFrameGapShift)); ++ } ++ ++ /* Clear the interrupt status register. */ ++ RTL_W16(IntrStatus, 0xFFFF); ++ ++ if (tp->mcfg == CFG_METHOD_4) { ++ set_offset70F(tp, 0x27); ++ ++ RTL_W8(DBG_reg, (0x0E << 4) | Fix_Nak_1 | Fix_Nak_2); ++ ++ /*Set EPHY registers begin*/ ++ /*Set EPHY register offset 0x02 bit 11 to 0 and bit 12 to 1*/ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x02); ++ ephy_data &= ~BIT_11; ++ ephy_data |= BIT_12; ++ rtl8168_ephy_write(ioaddr, 0x02, ephy_data); ++ ++ /*Set EPHY register offset 0x03 bit 1 to 1*/ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x03); ++ ephy_data |= (1 << 1); ++ rtl8168_ephy_write(ioaddr, 0x03, ephy_data); ++ ++ /*Set EPHY register offset 0x06 bit 7 to 0*/ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x06); ++ ephy_data &= ~(1 << 7); ++ rtl8168_ephy_write(ioaddr, 0x06, ephy_data); ++ /*Set EPHY registers end*/ ++ ++ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); ++ ++ //disable clock request. ++ pci_write_config_byte(pdev, 0x81, 0x00); ++ ++ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ++ ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en | ++ Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel)); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); ++ ++ set_offset79(tp, 0x20); ++ ++ //tx checksum offload disable ++ dev->features &= ~NETIF_F_IP_CSUM; ++ ++ //rx checksum offload disable ++ } else { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1); ++ ++ set_offset79(tp, 0x50); ++ ++ //tx checksum offload enable ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ //rx checksum offload enable ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) ++ tp->cp_cmd |= RxChkSum; ++ RTL_W16(CPlusCmd, tp->cp_cmd); ++#else ++ dev->features |= NETIF_F_RXCSUM; ++#endif ++ } else if (tp->mcfg == CFG_METHOD_5) { ++ ++ set_offset70F(tp, 0x27); ++ ++ /******set EPHY registers for RTL8168CP begin******/ ++ //Set EPHY register offset 0x01 bit 0 to 1. ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x01); ++ ephy_data |= (1 << 0); ++ rtl8168_ephy_write(ioaddr, 0x01, ephy_data); ++ ++ //Set EPHY register offset 0x03 bit 10 to 0, bit 9 to 1 and bit 5 to 1. ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x03); ++ ephy_data &= ~(1 << 10); ++ ephy_data |= (1 << 9); ++ ephy_data |= (1 << 5); ++ rtl8168_ephy_write(ioaddr, 0x03, ephy_data); ++ /******set EPHY registers for RTL8168CP end******/ ++ ++ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); ++ ++ //disable clock request. ++ pci_write_config_byte(pdev, 0x81, 0x00); ++ ++ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ++ ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en | ++ Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel)); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); ++ ++ set_offset79(tp, 0x20); ++ ++ //tx checksum offload disable ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1); ++ ++ set_offset79(tp, 0x50); ++ ++ //tx checksum offload enable ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ //rx checksum offload enable ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) ++ tp->cp_cmd |= RxChkSum; ++ RTL_W16(CPlusCmd, tp->cp_cmd); ++#else ++ dev->features |= NETIF_F_RXCSUM; ++#endif ++ } else if (tp->mcfg == CFG_METHOD_6) { ++ set_offset70F(tp, 0x27); ++ ++ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); ++ ++ //disable clock request. ++ pci_write_config_byte(pdev, 0x81, 0x00); ++ ++ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ++ ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en | ++ Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel)); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); ++ ++ set_offset79(tp, 0x20); ++ ++ //tx checksum offload disable ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1); ++ ++ set_offset79(tp, 0x50); ++ ++ //tx checksum offload enable ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ //rx checksum offload enable ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) ++ tp->cp_cmd |= RxChkSum; ++ RTL_W16(CPlusCmd, tp->cp_cmd); ++#else ++ dev->features |= NETIF_F_RXCSUM; ++#endif ++ } else if (tp->mcfg == CFG_METHOD_7) { ++ set_offset70F(tp, 0x27); ++ ++ rtl8168_eri_write(ioaddr, 0x1EC, 1, 0x07, ERIAR_ASF); ++ ++ //disable clock request. ++ pci_write_config_byte(pdev, 0x81, 0x00); ++ ++ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ++ ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en | ++ Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel)); ++ ++ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); ++ ++ set_offset79(tp, 0x20); ++ ++ //tx checksum offload disable ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1); ++ ++ ++ set_offset79(tp, 0x50); ++ ++ //tx checksum offload enable ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ } else if (tp->mcfg == CFG_METHOD_8) { ++ ++ set_offset70F(tp, 0x27); ++ ++ rtl8168_eri_write(ioaddr, 0x1EC, 1, 0x07, ERIAR_ASF); ++ ++ //disable clock request. ++ pci_write_config_byte(pdev, 0x81, 0x00); ++ ++ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ++ ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en | ++ Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel)); ++ ++ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); ++ ++ RTL_W8(0xD1, 0x20); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); ++ ++ set_offset79(tp, 0x20); ++ ++ //tx checksum offload disable ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1); ++ ++ ++ set_offset79(tp, 0x50); ++ ++ //tx checksum offload enable ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ } else if (tp->mcfg == CFG_METHOD_9) { ++ set_offset70F(tp, 0x27); ++ ++ /* disable clock request. */ ++ pci_write_config_byte(pdev, 0x81, 0x00); ++ ++ RTL_W8(Config3, RTL_R8(Config3) & ~BIT_4); ++ RTL_W8(DBG_reg, RTL_R8(DBG_reg) | BIT_7 | BIT_1); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); ++ ++ set_offset79(tp, 0x20); ++ ++ /* tx checksum offload disable */ ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1); ++ ++ ++ set_offset79(tp, 0x50); ++ ++ /* tx checksum offload enable */ ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ /* set EPHY registers */ ++ rtl8168_ephy_write(ioaddr, 0x01, 0x7C7D); ++ rtl8168_ephy_write(ioaddr, 0x02, 0x091F); ++ rtl8168_ephy_write(ioaddr, 0x06, 0xB271); ++ rtl8168_ephy_write(ioaddr, 0x07, 0xCE00); ++ } else if (tp->mcfg == CFG_METHOD_10) { ++ set_offset70F(tp, 0x27); ++ ++ RTL_W8(DBG_reg, RTL_R8(DBG_reg) | BIT_7 | BIT_1); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) | Jumbo_En1); ++ ++ set_offset79(tp, 0x20); ++ ++ /* tx checksum offload disable */ ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) & ~Jumbo_En1); ++ ++ ++ ++ set_offset79(tp, 0x50); ++ ++ /* tx checksum offload enable */ ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ RTL_W8(Config1, RTL_R8(Config1) | 0x10); ++ ++ /* set EPHY registers */ ++ rtl8168_ephy_write(ioaddr, 0x01, 0x6C7F); ++ rtl8168_ephy_write(ioaddr, 0x02, 0x011F); ++ rtl8168_ephy_write(ioaddr, 0x03, 0xC1B2); ++ rtl8168_ephy_write(ioaddr, 0x1A, 0x0546); ++ rtl8168_ephy_write(ioaddr, 0x1C, 0x80C4); ++ rtl8168_ephy_write(ioaddr, 0x1D, 0x78E4); ++ rtl8168_ephy_write(ioaddr, 0x0A, 0x8100); ++ ++ /* disable clock request. */ ++ pci_write_config_byte(pdev, 0x81, 0x00); ++ ++ RTL_W8(0xF3, RTL_R8(0xF3) | BIT_2); ++ ++ } else if (tp->mcfg == CFG_METHOD_11 || tp->mcfg == CFG_METHOD_13) { ++ set_offset70F(tp, 0x17); ++ set_offset79(tp, 0x50); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ ++ /* tx checksum offload disable */ ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ ++ /* tx checksum offload enable */ ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ pci_write_config_byte(pdev, 0x81, 0x00); ++ ++ RTL_W8(Config1, RTL_R8(Config1) | 0x10); ++ ++ } else if (tp->mcfg == CFG_METHOD_12) { ++ set_offset70F(tp, 0x17); ++ set_offset79(tp, 0x50); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ ++ /* tx checksum offload disable */ ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ ++ /* tx checksum offload enable */ ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x0B); ++ rtl8168_ephy_write(ioaddr, 0x0B, ephy_data|0x48); ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x19); ++ ephy_data &= ~0x20; ++ rtl8168_ephy_write(ioaddr, 0x19, ephy_data|0x50); ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x0C); ++ ephy_data &= ~0x100; ++ rtl8168_ephy_write(ioaddr, 0x0C, ephy_data|0x20); ++ ++ pci_write_config_byte(pdev, 0x81, 0x01); ++ ++ RTL_W8(Config1, RTL_R8(Config1) | 0x10); ++ ++ } else if (tp->mcfg == CFG_METHOD_14 || tp->mcfg == CFG_METHOD_15) { ++ ++ set_offset70F(tp, 0x27); ++ set_offset79(tp, 0x50); ++ ++ /* set EPHY registers */ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x00) & ~0x0200; ++ ephy_data |= 0x0100; ++ rtl8168_ephy_write(ioaddr, 0x00, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x00); ++ ephy_data |= 0x0004; ++ rtl8168_ephy_write(ioaddr, 0x00, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x06) & ~0x0002; ++ ephy_data |= 0x0001; ++ rtl8168_ephy_write(ioaddr, 0x06, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x06); ++ ephy_data |= 0x0030; ++ rtl8168_ephy_write(ioaddr, 0x06, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x07); ++ ephy_data |= 0x2000; ++ rtl8168_ephy_write(ioaddr, 0x07, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x00); ++ ephy_data |= 0x0020; ++ rtl8168_ephy_write(ioaddr, 0x00, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x03) & ~0x5800; ++ ephy_data |= 0x2000; ++ rtl8168_ephy_write(ioaddr, 0x03, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x03); ++ ephy_data |= 0x0001; ++ rtl8168_ephy_write(ioaddr, 0x03, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x01) & ~0x0800; ++ ephy_data |= 0x1000; ++ rtl8168_ephy_write(ioaddr, 0x01, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x07); ++ ephy_data |= 0x4000; ++ rtl8168_ephy_write(ioaddr, 0x07, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x1E); ++ ephy_data |= 0x2000; ++ rtl8168_ephy_write(ioaddr, 0x1E, ephy_data); ++ ++ rtl8168_ephy_write(ioaddr, 0x19, 0xFE6C); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x0A); ++ ephy_data |= 0x0040; ++ rtl8168_ephy_write(ioaddr, 0x0A, ephy_data); ++ ++ tp->cp_cmd &= 0x2063; ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(MTPS, 0x24); ++ RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) | 0x01); ++ ++ /* tx checksum offload disable */ ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(MTPS, 0x0C); ++ RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); ++ RTL_W8(Config4, RTL_R8(Config4) & ~0x01); ++ ++ /* tx checksum offload enable */ ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ rtl8168_set_rxbufsize(tp, dev); ++ ++ ++// RTL_W8(0xF2, RTL_R8(0xF2) | BIT_0); ++// RTL_W32(CounterAddrLow, RTL_R32(CounterAddrLow) | BIT_0); ++ ++ RTL_W8(0xF3, RTL_R8(0xF3) | BIT_5); ++ RTL_W8(0xF3, RTL_R8(0xF3) & ~BIT_5); ++ ++// RTL_W8(0xD3, RTL_R8(0xD3) | BIT_3 | BIT_2); ++ ++ RTL_W8(0xD0, RTL_R8(0xD0) | BIT_7 | BIT_6); ++ ++ RTL_W8(0xF1, RTL_R8(0xF1) | BIT_7 | BIT_6 | BIT_5 | BIT_4 | BIT_2 | BIT_1); ++ ++ RTL_W8(Config5, (RTL_R8(Config5)&~0x08) | BIT_0); ++ RTL_W8(Config2, RTL_R8(Config2) | BIT_7); ++ ++ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); ++ } else if (tp->mcfg == CFG_METHOD_16 || tp->mcfg == CFG_METHOD_17) { ++ set_offset70F(tp, 0x17); ++ set_offset79(tp, 0x50); ++ ++ rtl8168_eri_write(ioaddr, 0xD5, 1, 0x0000000C, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xC0, 2, 0x00000000, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xB8, 2, 0x00000000, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xC8, 4, 0x00100002, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xE8, 4, 0x00100006, ERIAR_ExGMAC); ++ csi_tmp = rtl8168_eri_read(ioaddr, 0x1D0, 4, ERIAR_ExGMAC); ++ csi_tmp |= BIT_1; ++ rtl8168_eri_write(ioaddr, 0x1D0, 1, csi_tmp, ERIAR_ExGMAC); ++ ++ RTL_W32(TxConfig, RTL_R32(TxConfig) | BIT_7); ++ RTL_W8(0xD3, RTL_R8(0xD3) & ~BIT_7); ++ RTL_W8(0x1B, RTL_R8(0x1B) & ~0x07); ++ ++ if (tp->mcfg == CFG_METHOD_16) { ++ RTL_W32(0xB0, 0xEE480010); ++ RTL_W8(0x1A, RTL_R8(0x1A) & ~(BIT_2|BIT_3)); ++ rtl8168_eri_write(ioaddr, 0x1DC, 1, 0x64, ERIAR_ExGMAC); ++ ++ rtl8168_ephy_write(ioaddr, 0x06, 0xF020); ++ rtl8168_ephy_write(ioaddr, 0x07, 0x01FF); ++ rtl8168_ephy_write(ioaddr, 0x00, 0x5027); ++ rtl8168_ephy_write(ioaddr, 0x01, 0x0003); ++ rtl8168_ephy_write(ioaddr, 0x02, 0x2D16); ++ rtl8168_ephy_write(ioaddr, 0x03, 0x6D49); ++ rtl8168_ephy_write(ioaddr, 0x08, 0x0006); ++ rtl8168_ephy_write(ioaddr, 0x0A, 0x00C8); ++ } else { ++ csi_tmp = rtl8168_eri_read(ioaddr, 0x1B0, 4, ERIAR_ExGMAC); ++ csi_tmp |= BIT_4; ++ rtl8168_eri_write(ioaddr, 0x1B0, 1, csi_tmp, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xCC, 4, 0x00000050, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xd0, 4, 0x07ff0060, ERIAR_ExGMAC); ++ } ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x09); ++ ephy_data |= BIT_7; ++ rtl8168_ephy_write(ioaddr, 0x09, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x19); ++ ephy_data |= (BIT_2 | BIT_5 | BIT_9); ++ rtl8168_ephy_write(ioaddr, 0x19, ephy_data); ++ RTL_W8(Config5, RTL_R8(Config5) | BIT_0); ++ RTL_W8(Config2, RTL_R8(Config2) | BIT_7); ++ ++ ++ RTL_W8(0xD0, RTL_R8(0xD0) | BIT_6); ++ RTL_W8(0xF2, RTL_R8(0xF2) | BIT_6); ++ ++ tp->cp_cmd &= 0x2063; ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(MTPS, 0x27); ++ ++ /* tx checksum offload disable */ ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(MTPS, 0x0C); ++ ++ /* tx checksum offload enable */ ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ rtl8168_set_rxbufsize(tp, dev); ++ ++ /* disable clock request. */ ++ pci_write_config_byte(pdev, 0x81, 0x00); ++ ++ } else if (tp->mcfg == CFG_METHOD_18 || tp->mcfg == CFG_METHOD_19) { ++ set_offset70F(tp, 0x17); ++ set_offset79(tp, 0x50); ++ ++ rtl8168_eri_write(ioaddr, 0xC8, 4, 0x00100002, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xE8, 4, 0x00100006, ERIAR_ExGMAC); ++ RTL_W32(TxConfig, RTL_R32(TxConfig) | BIT_7); ++ RTL_W8(0xD3, RTL_R8(0xD3) & ~BIT_7); ++ csi_tmp = rtl8168_eri_read(ioaddr, 0xDC, 1, ERIAR_ExGMAC); ++ csi_tmp &= ~BIT_0; ++ rtl8168_eri_write(ioaddr, 0xDC, 1, csi_tmp, ERIAR_ExGMAC); ++ csi_tmp |= BIT_0; ++ rtl8168_eri_write(ioaddr, 0xDC, 1, csi_tmp, ERIAR_ExGMAC); ++ ++ if (tp->mcfg == CFG_METHOD_18) { ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x06); ++ ephy_data |= BIT_5; ++ ephy_data &= ~(BIT_7 | BIT_6); ++ rtl8168_ephy_write(ioaddr, 0x06, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x08); ++ ephy_data |= BIT_1; ++ ephy_data &= ~BIT_0; ++ rtl8168_ephy_write(ioaddr, 0x08, ephy_data); ++ } ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x09); ++ ephy_data |= BIT_7; ++ rtl8168_ephy_write(ioaddr, 0x09, ephy_data); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x19); ++ ephy_data |= (BIT_2 | BIT_5 | BIT_9); ++ rtl8168_ephy_write(ioaddr, 0x19, ephy_data); ++ ++ RTL_W8(Config5, RTL_R8(Config5) | BIT_0); ++ RTL_W8(Config2, RTL_R8(Config2) | BIT_7); ++ ++ tp->cp_cmd &= 0x2063; ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(MTPS, 0x27); ++ ++ /* tx checksum offload disable */ ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(MTPS, 0x0C); ++ ++ /* tx checksum offload enable */ ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ rtl8168_set_rxbufsize(tp, dev); ++ ++ RTL_W8(0xD0, RTL_R8(0xD0) | BIT_6); ++ RTL_W8(0xF2, RTL_R8(0xF2) | BIT_6); ++ rtl8168_eri_write(ioaddr, 0xC0, 2, 0x00000000, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xB8, 2, 0x00000000, ERIAR_ExGMAC); ++ csi_tmp = rtl8168_eri_read(ioaddr, 0xD5, 1, ERIAR_ExGMAC); ++ csi_tmp |= BIT_3 | BIT_2; ++ rtl8168_eri_write(ioaddr, 0xD5, 1, csi_tmp, ERIAR_ExGMAC); ++ RTL_W8(0x1B,RTL_R8(0x1B) & ~0x07); ++ ++ csi_tmp = rtl8168_eri_read(ioaddr, 0x1B0, 1, ERIAR_ExGMAC); ++ csi_tmp |= BIT_4; ++ rtl8168_eri_write(ioaddr, 0x1B0, 1, csi_tmp, ERIAR_ExGMAC); ++ csi_tmp = rtl8168_eri_read(ioaddr, 0x1d0, 1, ERIAR_ExGMAC); ++ csi_tmp |= BIT_4 | BIT_1; ++ rtl8168_eri_write(ioaddr, 0x1d0, 1, csi_tmp, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xCC, 4, 0x00000050, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xd0, 4, 0x00000060, ERIAR_ExGMAC); ++ ++ if (RTL_R8(0x8c) & BIT_28) { ++ unsigned long flags; ++ u32 gphy_val; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x002C); ++ gphy_val = mdio_read(tp, 0x16); ++ gphy_val |= BIT_10; ++ mdio_write(tp, 0x16, gphy_val); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B80); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val |= BIT_7; ++ mdio_write(tp, 0x06, gphy_val); ++ mdio_write(tp, 0x1F, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ } ++ } else if (tp->mcfg == CFG_METHOD_20) { ++ set_offset70F(tp, 0x17); ++ set_offset79(tp, 0x50); ++ ++ rtl8168_eri_write(ioaddr, 0xC8, 4, 0x00100002, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xE8, 4, 0x00100006, ERIAR_ExGMAC); ++ RTL_W32(TxConfig, RTL_R32(TxConfig) | BIT_7); ++ RTL_W8(0xD3, RTL_R8(0xD3) & ~BIT_7); ++ csi_tmp = rtl8168_eri_read(ioaddr, 0xDC, 1, ERIAR_ExGMAC); ++ csi_tmp &= ~BIT_0; ++ rtl8168_eri_write(ioaddr, 0xDC, 1, csi_tmp, ERIAR_ExGMAC); ++ csi_tmp |= BIT_0; ++ rtl8168_eri_write(ioaddr, 0xDC, 1, csi_tmp, ERIAR_ExGMAC); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x06); ++ ephy_data |= BIT_5; ++ ephy_data &= ~(BIT_7 | BIT_6); ++ rtl8168_ephy_write(ioaddr, 0x06, ephy_data); ++ ++ rtl8168_ephy_write(ioaddr, 0x0f, 0x5200); ++ ++ ephy_data = rtl8168_ephy_read(ioaddr, 0x19); ++ ephy_data |= (BIT_2 | BIT_5 | BIT_9); ++ rtl8168_ephy_write(ioaddr, 0x19, ephy_data); ++ ++ RTL_W8(Config5, RTL_R8(Config5) | BIT_0); ++ RTL_W8(Config2, RTL_R8(Config2) | BIT_7); ++ ++ tp->cp_cmd &= 0x2063; ++ if (dev->mtu > ETH_DATA_LEN) { ++ RTL_W8(MTPS, 0x27); ++ ++ /* tx checksum offload disable */ ++ dev->features &= ~NETIF_F_IP_CSUM; ++ } else { ++ RTL_W8(MTPS, 0x0C); ++ ++ /* tx checksum offload enable */ ++ dev->features |= NETIF_F_IP_CSUM; ++ } ++ ++ rtl8168_set_rxbufsize(tp, dev); ++ ++ RTL_W8(0xD0, RTL_R8(0xD0) | BIT_6); ++ RTL_W8(0xF2, RTL_R8(0xF2) | BIT_6); ++ rtl8168_eri_write(ioaddr, 0xC0, 2, 0x00000000, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xB8, 2, 0x00000000, ERIAR_ExGMAC); ++ csi_tmp = rtl8168_eri_read(ioaddr, 0xD5, 1, ERIAR_ExGMAC); ++ csi_tmp |= BIT_3 | BIT_2; ++ rtl8168_eri_write(ioaddr, 0xD5, 1, csi_tmp, ERIAR_ExGMAC); ++ ++ csi_tmp = rtl8168_eri_read(ioaddr, 0x1B0, 1, ERIAR_ExGMAC); ++ csi_tmp |= BIT_4; ++ rtl8168_eri_write(ioaddr, 0x1B0, 1, csi_tmp, ERIAR_ExGMAC); ++ csi_tmp = rtl8168_eri_read(ioaddr, 0x1d0, 1, ERIAR_ExGMAC); ++ csi_tmp |= BIT_4 | BIT_1; ++ rtl8168_eri_write(ioaddr, 0x1d0, 1, csi_tmp, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xCC, 4, 0x00000050, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xd0, 4, 0x00000060, ERIAR_ExGMAC); ++ } else if (tp->mcfg == CFG_METHOD_1) { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); ++ ++ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ++ ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en | ++ Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel)); ++ ++ if (dev->mtu > ETH_DATA_LEN) { ++ pci_read_config_byte(pdev, 0x69, &device_control); ++ device_control &= ~0x70; ++ device_control |= 0x28; ++ pci_write_config_byte(pdev, 0x69, device_control); ++ } else { ++ pci_read_config_byte(pdev, 0x69, &device_control); ++ device_control &= ~0x70; ++ device_control |= 0x58; ++ pci_write_config_byte(pdev, 0x69, device_control); ++ } ++ } else if (tp->mcfg == CFG_METHOD_2) { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); ++ ++ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ++ ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en | ++ Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel)); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ if (dev->mtu > ETH_DATA_LEN) { ++ pci_read_config_byte(pdev, 0x69, &device_control); ++ device_control &= ~0x70; ++ device_control |= 0x28; ++ pci_write_config_byte(pdev, 0x69, device_control); ++ ++ RTL_W8(Config4, RTL_R8(Config4) | (1 << 0)); ++ } else { ++ pci_read_config_byte(pdev, 0x69, &device_control); ++ device_control &= ~0x70; ++ device_control |= 0x58; ++ pci_write_config_byte(pdev, 0x69, device_control); ++ ++ RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0)); ++ } ++ } else if (tp->mcfg == CFG_METHOD_3) { ++ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); ++ ++ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ++ ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en | ++ Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel)); ++ ++ RTL_W8(MTPS, Reserved1_data); ++ if (dev->mtu > ETH_DATA_LEN) { ++ pci_read_config_byte(pdev, 0x69, &device_control); ++ device_control &= ~0x70; ++ device_control |= 0x28; ++ pci_write_config_byte(pdev, 0x69, device_control); ++ ++ RTL_W8(Config4, RTL_R8(Config4) | (1 << 0)); ++ } else { ++ pci_read_config_byte(pdev, 0x69, &device_control); ++ device_control &= ~0x70; ++ device_control |= 0x58; ++ pci_write_config_byte(pdev, 0x69, device_control); ++ ++ RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0)); ++ } ++ } else if (tp->mcfg == CFG_METHOD_DEFAULT) { ++ tp->cp_cmd &= 0x2043; ++ RTL_W8(MTPS, 0x0C); ++ ++ dev->features &= ~NETIF_F_IP_CSUM; ++ rtl8168_set_rxbufsize(tp, dev); ++ } ++ ++ if ((tp->mcfg == CFG_METHOD_1) || (tp->mcfg == CFG_METHOD_2) || (tp->mcfg == CFG_METHOD_3)) { ++ /* csum offload command for RTL8168B/8111B */ ++ tp->tx_tcp_csum_cmd = TxIPCS | TxTCPCS; ++ tp->tx_udp_csum_cmd = TxIPCS | TxUDPCS; ++ tp->tx_ip_csum_cmd = TxIPCS; ++ } else { ++ /* csum offload command for RTL8168C/8111C and RTL8168CP/8111CP */ ++ tp->tx_tcp_csum_cmd = TxIPCS_C | TxTCPCS_C; ++ tp->tx_udp_csum_cmd = TxIPCS_C | TxUDPCS_C; ++ tp->tx_ip_csum_cmd = TxIPCS_C; ++ } ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) ++ RTL_W16(CPlusCmd, tp->cp_cmd); ++#else ++ rtl8168_set_features(dev, dev->features); ++#endif ++ ++ RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); ++ ++ if (tp->mcfg == CFG_METHOD_11 || tp->mcfg == CFG_METHOD_12) ++ { ++ rtl8168_mac_loopback_test(tp); ++ } ++ ++ /* Set Rx Config register */ ++ rtl8168_set_rx_mode(dev); ++ ++ if (tp->rx_fifo_overflow == 0) { ++ /* Enable all known interrupts by setting the interrupt mask. */ ++ RTL_W16(IntrMask, rtl8168_intr_mask); ++ netif_start_queue(dev); ++ } ++ ++ RTL_W8(Cfg9346, Cfg9346_Lock); ++ ++ if (!tp->pci_cfg_is_read) { ++ pci_read_config_byte(pdev, PCI_COMMAND, &tp->pci_cfg_space.cmd); ++ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &tp->pci_cfg_space.cls); ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_0, &tp->pci_cfg_space.io_base_l); ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_0 + 2, &tp->pci_cfg_space.io_base_h); ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_2, &tp->pci_cfg_space.mem_base_l); ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_2 + 2, &tp->pci_cfg_space.mem_base_h); ++ pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tp->pci_cfg_space.ilr); ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_4, &tp->pci_cfg_space.resv_0x20_l); ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_4 + 2, &tp->pci_cfg_space.resv_0x20_h); ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_5, &tp->pci_cfg_space.resv_0x24_l); ++ pci_read_config_word(pdev, PCI_BASE_ADDRESS_5 + 2, &tp->pci_cfg_space.resv_0x24_h); ++ ++ tp->pci_cfg_is_read = 1; ++ } ++ ++ rtl8168_dsm(dev, DSM_MAC_INIT); ++ ++ options1 = RTL_R8(Config3); ++ options2 = RTL_R8(Config5); ++ csi_tmp = rtl8168_eri_read(ioaddr, 0xDE, 4, ERIAR_ExGMAC); ++ ++ switch (tp->mcfg) { ++ case CFG_METHOD_16: ++ case CFG_METHOD_17: ++ if ((options1 & LinkUp) || (csi_tmp & BIT_0) || (options2 & UWF) || (options2 & BWF) || (options2 & MWF)) ++ tp->wol_enabled = WOL_ENABLED; ++ else ++ tp->wol_enabled = WOL_DISABLED; ++ break; ++ case CFG_METHOD_DEFAULT: ++ tp->wol_enabled = WOL_DISABLED; ++ break; ++ default: ++ if((options1 & LinkUp) || (options1 & MagicPacket) || (options2 & UWF) || (options2 & BWF) || (options2 & MWF)) ++ tp->wol_enabled = WOL_ENABLED; ++ else ++ tp->wol_enabled = WOL_DISABLED; ++ break; ++ } ++ ++ udelay(10); ++} ++ ++ ++static int ++rtl8168_change_mtu(struct net_device *dev, ++ int new_mtu) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ int max_mtu; ++ int ret = 0; ++ ++ if (tp->mcfg == CFG_METHOD_DEFAULT) ++ max_mtu = ETH_DATA_LEN; ++ else ++ max_mtu = tp->max_jumbo_frame_size - ETH_HLEN - 8; ++ ++ if (new_mtu < ETH_ZLEN) ++ return -EINVAL; ++ else if (new_mtu > max_mtu) ++ new_mtu = max_mtu; ++ ++ if (!netif_running(dev)) ++ goto out; ++ ++ rtl8168_down(dev); ++ ++ dev->mtu = new_mtu; ++ ++ rtl8168_set_rxbufsize(tp, dev); ++ ++ ret = rtl8168_init_ring(dev); ++ ++ if (ret < 0) ++ goto out; ++ ++#ifdef CONFIG_R8168_NAPI ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ RTL_NAPI_ENABLE(dev, &tp->napi); ++#endif ++#endif//CONFIG_R8168_NAPI ++ ++ rtl8168_hw_start(dev); ++ rtl8168_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, AUTONEG_ENABLE); ++ ++out: ++ return ret; ++} ++ ++static inline void ++rtl8168_make_unusable_by_asic(struct RxDesc *desc) ++{ ++ desc->addr = 0x0badbadbadbadbadull; ++ desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask); ++} ++ ++static void ++rtl8168_free_rx_skb(struct rtl8168_private *tp, ++ struct sk_buff **sk_buff, ++ struct RxDesc *desc) ++{ ++ struct pci_dev *pdev = tp->pci_dev; ++ ++ pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->rx_buf_sz, ++ PCI_DMA_FROMDEVICE); ++ dev_kfree_skb(*sk_buff); ++ *sk_buff = NULL; ++ rtl8168_make_unusable_by_asic(desc); ++} ++ ++static inline void ++rtl8168_mark_to_asic(struct RxDesc *desc, ++ u32 rx_buf_sz) ++{ ++ u32 eor = le32_to_cpu(desc->opts1) & RingEnd; ++ ++ desc->opts1 = cpu_to_le32(DescOwn | eor | rx_buf_sz); ++} ++ ++static inline void ++rtl8168_map_to_asic(struct RxDesc *desc, ++ dma_addr_t mapping, ++ u32 rx_buf_sz) ++{ ++ desc->addr = cpu_to_le64(mapping); ++ wmb(); ++ rtl8168_mark_to_asic(desc, rx_buf_sz); ++} ++ ++static int ++rtl8168_alloc_rx_skb(struct pci_dev *pdev, ++ struct sk_buff **sk_buff, ++ struct RxDesc *desc, ++ int rx_buf_sz) ++{ ++ struct sk_buff *skb; ++ dma_addr_t mapping; ++ int ret = 0; ++ ++ skb = dev_alloc_skb(rx_buf_sz + RTK_RX_ALIGN); ++ if (!skb) ++ goto err_out; ++ ++ skb_reserve(skb, RTK_RX_ALIGN); ++ *sk_buff = skb; ++ ++ mapping = pci_map_single(pdev, skb->data, rx_buf_sz, ++ PCI_DMA_FROMDEVICE); ++ ++ rtl8168_map_to_asic(desc, mapping, rx_buf_sz); ++ ++out: ++ return ret; ++ ++err_out: ++ ret = -ENOMEM; ++ rtl8168_make_unusable_by_asic(desc); ++ goto out; ++} ++ ++static void ++rtl8168_rx_clear(struct rtl8168_private *tp) ++{ ++ int i; ++ ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ if (tp->Rx_skbuff[i]) { ++ rtl8168_free_rx_skb(tp, tp->Rx_skbuff + i, ++ tp->RxDescArray + i); ++ } ++ } ++} ++ ++static u32 ++rtl8168_rx_fill(struct rtl8168_private *tp, ++ struct net_device *dev, ++ u32 start, ++ u32 end) ++{ ++ u32 cur; ++ ++ for (cur = start; end - cur > 0; cur++) { ++ int ret, i = cur % NUM_RX_DESC; ++ ++ if (tp->Rx_skbuff[i]) ++ continue; ++ ++ ret = rtl8168_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i, ++ tp->RxDescArray + i, tp->rx_buf_sz); ++ if (ret < 0) ++ break; ++ } ++ return cur - start; ++} ++ ++static inline void ++rtl8168_mark_as_last_descriptor(struct RxDesc *desc) ++{ ++ desc->opts1 |= cpu_to_le32(RingEnd); ++} ++ ++void rtl8168_init_ring_indexes(struct rtl8168_private *tp) ++{ ++ tp->dirty_tx = 0; ++ tp->dirty_rx = 0; ++ tp->cur_tx = 0; ++ tp->cur_rx = 0; ++} ++ ++static void ++rtl8168_tx_desc_init(struct rtl8168_private *tp) ++{ ++ int i = 0; ++ ++ memset(tp->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc)); ++ ++ for (i = 0; i < NUM_TX_DESC; i++) ++ if (i == (NUM_TX_DESC - 1)) ++ tp->TxDescArray[i].opts1 = cpu_to_le32(RingEnd); ++} ++ ++static void ++rtl8168_rx_desc_offset0_init(struct rtl8168_private *tp, int own) ++{ ++ int i = 0; ++ int ownbit = 0; ++ ++ if (own) ++ ownbit = DescOwn; ++ ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ if (i == (NUM_RX_DESC - 1)) ++ tp->RxDescArray[i].opts1 = cpu_to_le32((ownbit | RingEnd) | (unsigned long)tp->rx_buf_sz); ++ else ++ tp->RxDescArray[i].opts1 = cpu_to_le32(ownbit | (unsigned long)tp->rx_buf_sz); ++ } ++} ++ ++static void ++rtl8168_rx_desc_init(struct rtl8168_private *tp) ++{ ++ memset(tp->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc)); ++} ++ ++static int ++rtl8168_init_ring(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ rtl8168_init_ring_indexes(tp); ++ ++ memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info)); ++ memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *)); ++ ++ rtl8168_tx_desc_init(tp); ++ rtl8168_rx_desc_init(tp); ++ ++ if (rtl8168_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC) ++ goto err_out; ++ ++ rtl8168_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); ++ ++ return 0; ++ ++err_out: ++ rtl8168_rx_clear(tp); ++ return -ENOMEM; ++} ++ ++static void ++rtl8168_unmap_tx_skb(struct pci_dev *pdev, ++ struct ring_info *tx_skb, ++ struct TxDesc *desc) ++{ ++ unsigned int len = tx_skb->len; ++ ++ pci_unmap_single(pdev, le64_to_cpu(desc->addr), len, PCI_DMA_TODEVICE); ++ desc->opts1 = 0x00; ++ desc->opts2 = 0x00; ++ desc->addr = 0x00; ++ tx_skb->len = 0; ++} ++ ++static void ++rtl8168_tx_clear(struct rtl8168_private *tp) ++{ ++ unsigned int i; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ struct net_device *dev = tp->dev; ++#endif ++ ++ for (i = tp->dirty_tx; i < tp->dirty_tx + NUM_TX_DESC; i++) { ++ unsigned int entry = i % NUM_TX_DESC; ++ struct ring_info *tx_skb = tp->tx_skb + entry; ++ unsigned int len = tx_skb->len; ++ ++ if (len) { ++ struct sk_buff *skb = tx_skb->skb; ++ ++ rtl8168_unmap_tx_skb(tp->pci_dev, tx_skb, ++ tp->TxDescArray + entry); ++ if (skb) { ++ dev_kfree_skb(skb); ++ tx_skb->skb = NULL; ++ } ++ RTLDEV->stats.tx_dropped++; ++ } ++ } ++ tp->cur_tx = tp->dirty_tx = 0; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ++static void rtl8168_schedule_work(struct net_device *dev, void (*task)(void *)) ++{ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ PREPARE_WORK(&tp->task, task, dev); ++ schedule_delayed_work(&tp->task, 4); ++#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++} ++#else ++static void rtl8168_schedule_work(struct net_device *dev, work_func_t task) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ PREPARE_DELAYED_WORK(&tp->task, task); ++ schedule_delayed_work(&tp->task, 4); ++} ++#endif ++ ++static void ++rtl8168_wait_for_quiescence(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ synchronize_irq(dev->irq); ++ ++ /* Wait for any pending NAPI task to complete */ ++#ifdef CONFIG_R8168_NAPI ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ RTL_NAPI_DISABLE(dev, &tp->napi); ++#endif ++#endif//CONFIG_R8168_NAPI ++ ++ rtl8168_irq_mask_and_ack(ioaddr); ++ ++#ifdef CONFIG_R8168_NAPI ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ RTL_NAPI_ENABLE(dev, &tp->napi); ++#endif ++#endif//CONFIG_R8168_NAPI ++} ++ ++#if 0 ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ++static void rtl8168_reinit_task(void *_data) ++#else ++static void rtl8168_reinit_task(struct work_struct *work) ++#endif ++{ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ++ struct net_device *dev = _data; ++#else ++ struct rtl8168_private *tp = ++ container_of(work, struct rtl8168_private, task.work); ++ struct net_device *dev = tp->dev; ++#endif ++ int ret; ++ ++ if (netif_running(dev)) { ++ rtl8168_wait_for_quiescence(dev); ++ rtl8168_close(dev); ++ } ++ ++ ret = rtl8168_open(dev); ++ if (unlikely(ret < 0)) { ++ if (net_ratelimit()) { ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ if (netif_msg_drv(tp)) { ++ printk(PFX KERN_ERR ++ "%s: reinit failure (status = %d)." ++ " Rescheduling.\n", dev->name, ret); ++ } ++ } ++ rtl8168_schedule_work(dev, rtl8168_reinit_task); ++ } ++} ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ++static void rtl8168_reset_task(void *_data) ++{ ++ struct net_device *dev = _data; ++ struct rtl8168_private *tp = netdev_priv(dev); ++#else ++static void rtl8168_reset_task(struct work_struct *work) ++{ ++ struct rtl8168_private *tp = ++ container_of(work, struct rtl8168_private, task.work); ++ struct net_device *dev = tp->dev; ++#endif ++ ++ if (!netif_running(dev)) ++ return; ++ ++ rtl8168_wait_for_quiescence(dev); ++ ++ rtl8168_rx_interrupt(dev, tp, tp->mmio_addr, ~(u32)0); ++ rtl8168_tx_clear(tp); ++ ++ if (tp->dirty_rx == tp->cur_rx) { ++ rtl8168_init_ring_indexes(tp); ++ rtl8168_hw_start(dev); ++ netif_wake_queue(dev); ++ } else { ++ if (net_ratelimit()) { ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ if (netif_msg_intr(tp)) { ++ printk(PFX KERN_EMERG ++ "%s: Rx buffers shortage\n", dev->name); ++ } ++ } ++ rtl8168_schedule_work(dev, rtl8168_reset_task); ++ } ++} ++ ++static void ++rtl8168_tx_timeout(struct net_device *dev) ++{ ++ rtl8168_hw_reset(dev); ++ ++ /* Let's wait a bit while any (async) irq lands on */ ++ rtl8168_schedule_work(dev, rtl8168_reset_task); ++} ++ ++static int ++rtl8168_xmit_frags(struct rtl8168_private *tp, ++ struct sk_buff *skb, ++ u32 opts1) ++{ ++ struct skb_shared_info *info = skb_shinfo(skb); ++ unsigned int cur_frag, entry; ++ struct TxDesc *txd = NULL; ++ ++ entry = tp->cur_tx; ++ for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) { ++ skb_frag_t *frag = info->frags + cur_frag; ++ dma_addr_t mapping; ++ u32 status, len; ++ void *addr; ++ ++ entry = (entry + 1) % NUM_TX_DESC; ++ ++ txd = tp->TxDescArray + entry; ++ len = frag->size; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) ++ addr = ((void *) page_address(frag->page)) + frag->page_offset; ++#else ++ addr = ((void *) page_address(frag->page.p)) + frag->page_offset; ++#endif ++ mapping = pci_map_single(tp->pci_dev, addr, len, PCI_DMA_TODEVICE); ++ ++ /* anti gcc 2.95.3 bugware (sic) */ ++ status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); ++ ++ txd->opts1 = cpu_to_le32(status); ++ txd->addr = cpu_to_le64(mapping); ++ ++ tp->tx_skb[entry].len = len; ++ } ++ ++ if (cur_frag) { ++ tp->tx_skb[entry].skb = skb; ++ txd->opts1 |= cpu_to_le32(LastFrag); ++ } ++ ++ return cur_frag; ++} ++ ++static inline u32 ++rtl8168_tso(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ if (dev->features & NETIF_F_TSO) { ++ u32 mss = skb_shinfo(skb)->gso_size; ++ ++ if (mss) ++ return LargeSend | ((mss & MSSMask) << MSSShift); ++ } ++#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ ++ return 0; ++} ++ ++static inline u32 ++rtl8168_tx_csum(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ++ const struct iphdr *ip = skb->nh.iph; ++#else ++ const struct iphdr *ip = ip_hdr(skb); ++#endif ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ if (ip->protocol == IPPROTO_TCP) ++ return tp->tx_tcp_csum_cmd; ++ else if (ip->protocol == IPPROTO_UDP) ++ return tp->tx_udp_csum_cmd; ++ else if (ip->protocol == IPPROTO_IP) ++ return tp->tx_ip_csum_cmd; ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ WARN_ON(1); /* we need a WARN() */ ++#endif ++ } ++ ++ return 0; ++} ++ ++static int ++rtl8168_start_xmit(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ unsigned int frags, entry = tp->cur_tx % NUM_TX_DESC; ++ struct TxDesc *txd = tp->TxDescArray + entry; ++ void __iomem *ioaddr = tp->mmio_addr; ++ dma_addr_t mapping; ++ u32 status1, status2, len; ++ u32 opts1 = 0; ++ u32 opts2 = 0; ++ int ret = NETDEV_TX_OK; ++ ++ //Work around for rx fifo overflow ++ if (tp->rx_fifo_overflow == 1) ++ goto err_stop; ++ ++ if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { ++ if (netif_msg_drv(tp)) { ++ printk(KERN_ERR ++ "%s: BUG! Tx Ring full when queue awake!\n", ++ dev->name); ++ } ++ goto err_stop; ++ } ++ ++ if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) ++ goto err_stop; ++ ++ opts1 = DescOwn | rtl8168_tso(skb, dev); ++ ++ if (dev->features & NETIF_F_IP_CSUM) { ++ if ((tp->mcfg == CFG_METHOD_1) || (tp->mcfg == CFG_METHOD_2) || (tp->mcfg == CFG_METHOD_3)) ++ opts1 |= rtl8168_tx_csum(skb, dev); ++ else ++ opts2 = rtl8168_tx_csum(skb, dev); ++ } ++ ++ frags = rtl8168_xmit_frags(tp, skb, opts1); ++ if (frags) { ++ len = skb_headlen(skb); ++ opts1 |= FirstFrag; ++ } else { ++ len = skb->len; ++ opts1 |= FirstFrag | LastFrag; ++ tp->tx_skb[entry].skb = skb; ++ } ++ ++ if ((tp->mcfg == CFG_METHOD_16|| tp->mcfg == CFG_METHOD_17)&& len < 60) { ++ if (opts2 & 0xE0000000) { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++ skb_checksum_help(skb, 0); ++#else ++ skb_checksum_help(skb); ++#endif ++ opts2 &= ~0xE0000000; ++ } ++ len = 60; ++ } ++ ++ mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE); ++ ++ tp->tx_skb[entry].len = len; ++ txd->addr = cpu_to_le64(mapping); ++ txd->opts2 = cpu_to_le32(rtl8168_tx_vlan_tag(tp, skb)); ++ ++ wmb(); ++ ++ /* anti gcc 2.95.3 bugware (sic) */ ++ status1 = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); ++ status2 = opts2; ++ txd->opts1 = cpu_to_le32(status1); ++ txd->opts2 |= cpu_to_le32(status2); ++ ++ dev->trans_start = jiffies; ++ ++ tp->cur_tx += frags + 1; ++ ++ smp_wmb(); ++ ++ RTL_W8(TxPoll, NPQ); /* set polling bit */ ++ ++ if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { ++ netif_stop_queue(dev); ++ smp_rmb(); ++ if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) ++ netif_wake_queue(dev); ++ } ++ ++out: ++ return ret; ++err_stop: ++ netif_stop_queue(dev); ++ ret = NETDEV_TX_BUSY; ++ RTLDEV->stats.tx_dropped++; ++ goto out; ++} ++ ++static void ++rtl8168_pcierr_interrupt(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ struct pci_dev *pdev = tp->pci_dev; ++ u16 pci_status, pci_cmd; ++ ++ pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); ++ pci_read_config_word(pdev, PCI_STATUS, &pci_status); ++ ++ if (netif_msg_intr(tp)) { ++ printk(KERN_ERR ++ "%s: PCI error (cmd = 0x%04x, status = 0x%04x).\n", ++ dev->name, pci_cmd, pci_status); ++ } ++ ++ /* ++ * The recovery sequence below admits a very elaborated explanation: ++ * - it seems to work; ++ * - I did not see what else could be done. ++ * ++ * Feel free to adjust to your needs. ++ */ ++ pci_write_config_word(pdev, PCI_COMMAND, ++ pci_cmd | PCI_COMMAND_SERR | PCI_COMMAND_PARITY); ++ ++ pci_write_config_word(pdev, PCI_STATUS, ++ pci_status & (PCI_STATUS_DETECTED_PARITY | ++ PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_REC_MASTER_ABORT | ++ PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_SIG_TARGET_ABORT)); ++ ++ rtl8168_hw_reset(dev); ++} ++ ++static void ++rtl8168_tx_interrupt(struct net_device *dev, ++ struct rtl8168_private *tp, ++ void __iomem *ioaddr) ++{ ++ unsigned int dirty_tx, tx_left; ++ ++ assert(dev != NULL); ++ assert(tp != NULL); ++ assert(ioaddr != NULL); ++ ++ dirty_tx = tp->dirty_tx; ++ smp_rmb(); ++ tx_left = tp->cur_tx - dirty_tx; ++ ++ while (tx_left > 0) { ++ unsigned int entry = dirty_tx % NUM_TX_DESC; ++ struct ring_info *tx_skb = tp->tx_skb + entry; ++ u32 len = tx_skb->len; ++ u32 status; ++ ++ rmb(); ++ status = le32_to_cpu(tp->TxDescArray[entry].opts1); ++ if (status & DescOwn) ++ break; ++ ++ RTLDEV->stats.tx_bytes += len; ++ RTLDEV->stats.tx_packets++; ++ ++ rtl8168_unmap_tx_skb(tp->pci_dev, ++ tx_skb, ++ tp->TxDescArray + entry); ++ ++ if (status & LastFrag) { ++ dev_kfree_skb_irq(tx_skb->skb); ++ tx_skb->skb = NULL; ++ } ++ dirty_tx++; ++ tx_left--; ++ } ++ ++ if (tp->dirty_tx != dirty_tx) { ++ tp->dirty_tx = dirty_tx; ++ smp_wmb(); ++ if (netif_queue_stopped(dev) && ++ (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { ++ netif_wake_queue(dev); ++ } ++ smp_rmb(); ++ if (tp->cur_tx != dirty_tx) ++ RTL_W8(TxPoll, NPQ); ++ } ++} ++ ++static inline int ++rtl8168_fragmented_frame(u32 status) ++{ ++ return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); ++} ++ ++static inline void ++rtl8168_rx_csum(struct rtl8168_private *tp, ++ struct sk_buff *skb, ++ struct RxDesc *desc) ++{ ++ u32 opts1 = le32_to_cpu(desc->opts1); ++ u32 opts2 = le32_to_cpu(desc->opts2); ++ u32 status = opts1 & RxProtoMask; ++ ++ if ((tp->mcfg == CFG_METHOD_1) || ++ (tp->mcfg == CFG_METHOD_2) || ++ (tp->mcfg == CFG_METHOD_3)) { ++ /* rx csum offload for RTL8168B/8111B */ ++ if (((status == RxProtoTCP) && !(opts1 & RxTCPF)) || ++ ((status == RxProtoUDP) && !(opts1 & RxUDPF)) || ++ ((status == RxProtoIP) && !(opts1 & RxIPF))) ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ else ++ skb->ip_summed = CHECKSUM_NONE; ++ } else { ++ /* rx csum offload for RTL8168C/8111C and RTL8168CP/8111CP */ ++ if (((status == RxTCPT) && !(opts1 & RxTCPF)) || ++ ((status == RxUDPT) && !(opts1 & RxUDPF)) || ++ ((status == 0) && (opts2 & RxV4F) && !(opts1 & RxIPF))) ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ else ++ skb->ip_summed = CHECKSUM_NONE; ++ } ++} ++ ++static inline int ++rtl8168_try_rx_copy(struct sk_buff **sk_buff, ++ int pkt_size, ++ struct RxDesc *desc, ++ int rx_buf_sz) ++{ ++ int ret = -1; ++ ++ if (pkt_size < rx_copybreak) { ++ struct sk_buff *skb; ++ ++ skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); ++ if (skb) { ++ skb_reserve(skb, NET_IP_ALIGN); ++ eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); ++ *sk_buff = skb; ++ rtl8168_mark_to_asic(desc, rx_buf_sz); ++ ret = 0; ++ } ++ } ++ return ret; ++} ++ ++static int ++rtl8168_rx_interrupt(struct net_device *dev, ++ struct rtl8168_private *tp, ++ void __iomem *ioaddr, u32 budget) ++{ ++ unsigned int cur_rx, rx_left; ++ unsigned int delta, count = 0; ++ u32 rx_quota = RTL_RX_QUOTA(dev, budget); ++ ++ assert(dev != NULL); ++ assert(tp != NULL); ++ assert(ioaddr != NULL); ++ ++ cur_rx = tp->cur_rx; ++ rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx; ++ rx_left = rtl8168_rx_quota(rx_left, (u32) rx_quota); ++ ++ if ((tp->RxDescArray == NULL) || (tp->Rx_skbuff == NULL)) { ++ goto rx_out; ++ } ++ ++ for (; rx_left > 0; rx_left--, cur_rx++) { ++ unsigned int entry = cur_rx % NUM_RX_DESC; ++ struct RxDesc *desc = tp->RxDescArray + entry; ++ u32 status; ++ ++ rmb(); ++ status = le32_to_cpu(desc->opts1); ++ ++ if (status & DescOwn) ++ break; ++ if (unlikely(status & RxRES)) { ++ if (netif_msg_rx_err(tp)) { ++ printk(KERN_INFO ++ "%s: Rx ERROR. status = %08x\n", ++ dev->name, status); ++ } ++ ++ RTLDEV->stats.rx_errors++; ++ ++ if (status & (RxRWT | RxRUNT)) ++ RTLDEV->stats.rx_length_errors++; ++ if (status & RxCRC) ++ RTLDEV->stats.rx_crc_errors++; ++ rtl8168_mark_to_asic(desc, tp->rx_buf_sz); ++ } else { ++ struct sk_buff *skb = tp->Rx_skbuff[entry]; ++ int pkt_size = (status & 0x00003FFF) - 4; ++ void (*pci_action)(struct pci_dev *, dma_addr_t, ++ size_t, int) = pci_dma_sync_single_for_device; ++ ++ /* ++ * The driver does not support incoming fragmented ++ * frames. They are seen as a symptom of over-mtu ++ * sized frames. ++ */ ++ if (unlikely(rtl8168_fragmented_frame(status))) { ++ RTLDEV->stats.rx_dropped++; ++ RTLDEV->stats.rx_length_errors++; ++ rtl8168_mark_to_asic(desc, tp->rx_buf_sz); ++ continue; ++ } ++ ++ if (tp->cp_cmd & RxChkSum) ++ rtl8168_rx_csum(tp, skb, desc); ++ ++ pci_dma_sync_single_for_cpu(tp->pci_dev, ++ le64_to_cpu(desc->addr), tp->rx_buf_sz, ++ PCI_DMA_FROMDEVICE); ++ ++ if (rtl8168_try_rx_copy(&skb, pkt_size, desc, ++ tp->rx_buf_sz)) { ++ pci_action = pci_unmap_single; ++ tp->Rx_skbuff[entry] = NULL; ++ } ++ ++ pci_action(tp->pci_dev, le64_to_cpu(desc->addr), ++ tp->rx_buf_sz, PCI_DMA_FROMDEVICE); ++ ++ skb->dev = dev; ++ skb_put(skb, pkt_size); ++ skb->protocol = eth_type_trans(skb, dev); ++ ++ if (rtl8168_rx_vlan_skb(tp, desc, skb) < 0) ++ rtl8168_rx_skb(skb); ++ ++ dev->last_rx = jiffies; ++ RTLDEV->stats.rx_bytes += pkt_size; ++ RTLDEV->stats.rx_packets++; ++ } ++ } ++ ++ count = cur_rx - tp->cur_rx; ++ tp->cur_rx = cur_rx; ++ ++ delta = rtl8168_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx); ++ if (!delta && count && netif_msg_intr(tp)) ++ printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name); ++ tp->dirty_rx += delta; ++ ++ /* ++ * FIXME: until there is periodic timer to try and refill the ring, ++ * a temporary shortage may definitely kill the Rx process. ++ * - disable the asic to try and avoid an overflow and kick it again ++ * after refill ? ++ * - how do others driver handle this condition (Uh oh...). ++ */ ++ if ((tp->dirty_rx + NUM_RX_DESC == tp->cur_rx) && netif_msg_intr(tp)) ++ printk(KERN_EMERG "%s: Rx buffers exhausted\n", dev->name); ++ ++rx_out: ++ return count; ++} ++ ++/* ++ *The interrupt handler does all of the Rx thread work and cleans up after ++ *the Tx thread. ++ */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) ++static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance, struct pt_regs *regs) ++#else ++static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance) ++#endif ++{ ++ struct net_device *dev = (struct net_device *) dev_instance; ++ struct rtl8168_private *tp = netdev_priv(dev); ++ int boguscnt = max_interrupt_work; ++ void __iomem *ioaddr = tp->mmio_addr; ++ int status; ++ int handled = 0; ++ ++ ++ RTL_W16(IntrMask, 0x0000); ++ ++ do { ++ status = RTL_R16(IntrStatus); ++ ++ /* hotplug/major error/no more work/shared irq */ ++ if ((status == 0xFFFF) || !status) ++ break; ++ ++ handled = 1; ++ ++ status &= (tp->intr_mask | TxDescUnavail); ++ RTL_W16(IntrStatus, status); ++ ++ if (unlikely(!netif_running(dev))) ++ { ++ netif_stop_queue(dev); ++ rtl8168_nic_reset(dev); ++ return IRQ_RETVAL(handled); ++ } ++ ++ if (!(status & rtl8168_intr_mask)) ++ break; ++ ++ //Work around for rx fifo overflow ++ if (unlikely(status & RxFIFOOver)) ++ if (tp->mcfg == CFG_METHOD_1) { ++ tp->rx_fifo_overflow = 1; ++ netif_stop_queue(dev); ++ udelay(300); ++ rtl8168_rx_clear(tp); ++ rtl8168_init_ring(dev); ++ rtl8168_hw_start(dev); ++ RTL_W16(IntrStatus, RxFIFOOver); ++ netif_wake_queue(dev); ++ tp->rx_fifo_overflow = 0; ++ } ++ ++ if (unlikely(status & SYSErr)) { ++ rtl8168_pcierr_interrupt(dev); ++ break; ++ } ++ ++ if (status & LinkChg) ++ rtl8168_check_link_status(dev, tp, ioaddr); ++ ++#ifdef CONFIG_R8168_NAPI ++ if (status & rtl8168_napi_event) { ++ tp->intr_mask = rtl8168_intr_mask & ~rtl8168_napi_event; ++ RTL_W16(IntrMask, rtl8168_intr_mask & tp->intr_mask); ++ ++ if (likely(RTL_NETIF_RX_SCHEDULE_PREP(dev, &tp->napi))) ++ __RTL_NETIF_RX_SCHEDULE(dev, &tp->napi); ++ else if (netif_msg_intr(tp)) ++ printk(KERN_INFO "%s: interrupt %04x in poll\n", ++ dev->name, status); ++ } ++ ++#else ++ /* Rx interrupt */ ++ if (status & (RxOK | RxDescUnavail | RxFIFOOver)) { ++ rtl8168_rx_interrupt(dev, tp, tp->mmio_addr, ~(u32)0); ++ } ++ /* Tx interrupt */ ++ if (status & (TxOK | TxErr)) ++ rtl8168_tx_interrupt(dev, tp, ioaddr); ++#endif ++ ++ boguscnt--; ++ } while (boguscnt > 0); ++ ++ if (boguscnt <= 0) { ++ if (netif_msg_intr(tp) && net_ratelimit() ) { ++ printk(KERN_WARNING ++ "%s: Too much work at interrupt!\n", dev->name); ++ } ++ /* Clear all interrupt sources. */ ++ RTL_W16(IntrStatus, 0xffff); ++ } ++ ++ RTL_W16(IntrMask, tp->intr_mask); ++ ++ return IRQ_RETVAL(handled); ++} ++ ++#ifdef CONFIG_R8168_NAPI ++static int rtl8168_poll(napi_ptr napi, napi_budget budget) ++{ ++ struct rtl8168_private *tp = RTL_GET_PRIV(napi, struct rtl8168_private); ++ void __iomem *ioaddr = tp->mmio_addr; ++ RTL_GET_NETDEV(tp) ++ unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev); ++ unsigned int work_done; ++ ++ work_done = rtl8168_rx_interrupt(dev, tp, ioaddr, (u32) budget); ++ rtl8168_tx_interrupt(dev, tp, ioaddr); ++ ++ RTL_NAPI_QUOTA_UPDATE(dev, work_done, budget); ++ ++ if (work_done < work_to_do) { ++ RTL_NETIF_RX_COMPLETE(dev, napi); ++ tp->intr_mask = rtl8168_intr_mask; ++ /* ++ * 20040426: the barrier is not strictly required but the ++ * behavior of the irq handler could be less predictable ++ * without it. Btw, the lack of flush for the posted pci ++ * write is safe - FR ++ */ ++ smp_wmb(); ++ RTL_W16(IntrMask, rtl8168_intr_mask); ++ } ++ ++ return RTL_NAPI_RETURN_VALUE; ++} ++#endif//CONFIG_R8168_NAPI ++ ++static void rtl8168_sleep_rx_enable(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ ++ if ((tp->mcfg == CFG_METHOD_1) || (tp->mcfg == CFG_METHOD_2)) { ++ RTL_W8(ChipCmd, CmdReset); ++ rtl8168_rx_desc_offset0_init(tp, 0); ++ RTL_W8(ChipCmd, CmdRxEnb); ++ } else if (tp->mcfg == CFG_METHOD_14 || tp->mcfg == CFG_METHOD_15) { ++ rtl8168_ephy_write(ioaddr, 0x19, 0xFF64); ++ RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); ++ } else if (tp->mcfg == CFG_METHOD_18 || tp->mcfg == CFG_METHOD_19) { ++ if (RTL_R8(0x8c) & BIT_28) { ++ unsigned long flags; ++ u32 gphy_val; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1F, 0x0000); ++ mdio_write(tp, 0x04, 0x0061); ++ mdio_write(tp, 0x09, 0x0000); ++ mdio_write(tp, 0x00, 0x9200); ++ mdio_write(tp, 0x1F, 0x0005); ++ mdio_write(tp, 0x05, 0x8B80); ++ gphy_val = mdio_read(tp, 0x06); ++ gphy_val &= ~BIT_7; ++ mdio_write(tp, 0x06, gphy_val); ++ mdelay(1); ++ mdio_write(tp, 0x1F, 0x0007); ++ mdio_write(tp, 0x1E, 0x002C); ++ gphy_val = mdio_read(tp, 0x16); ++ gphy_val &= ~BIT_10; ++ mdio_write(tp, 0x16, gphy_val); ++ mdio_write(tp, 0x1F, 0x0000); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ } ++ } ++} ++ ++static void rtl8168_down(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ int count; ++ ++ rtl8168_dsm(dev, DSM_IF_DOWN); ++ ++ netif_stop_queue(dev); ++ ++ rtl8168_delete_esd_timer(dev, &tp->esd_timer); ++ rtl8168_delete_link_timer(dev, &tp->link_timer); ++ ++#ifdef CONFIG_R8168_NAPI ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23) ++ napi_disable(&tp->napi); ++#endif ++#endif//CONFIG_R8168_NAPI ++ ++ for (count=0; count<100; count++) ++ { ++ spin_lock_irq(&tp->lock); ++ ++ rtl8168_asic_down(dev); ++ ++ rtl8168_sleep_rx_enable(dev); ++ ++ spin_unlock_irq(&tp->lock); ++ ++ synchronize_irq(dev->irq); ++ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) ++ if (count==0) { ++#ifdef CONFIG_R8169_NAPI ++ netif_poll_disable(dev); ++#endif ++ } ++#endif ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11) ++ /* Give a racing hard_start_xmit a few cycles to complete. */ ++ synchronize_sched(); /* FIXME: should this be synchronize_irq()? */ ++#endif ++ ++ /* ++ * And now for the 50k$ question: are IRQ disabled or not ? ++ * ++ * Two paths lead here: ++ * 1) dev->close ++ * -> netif_running() is available to sync the current code and the ++ * IRQ handler. See rtl8168_interrupt for details. ++ * 2) dev->change_mtu ++ * -> rtl8168_poll can not be issued again and re-enable the ++ * interruptions. Let's simply issue the IRQ down sequence again. ++ */ ++ if (RTL_R16(IntrMask)==0) ++ break; ++ } ++ ++ rtl8168_tx_clear(tp); ++ ++ rtl8168_rx_clear(tp); ++ ++ rtl8168_powerdown_pll(dev); ++} ++ ++static int rtl8168_close(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ struct pci_dev *pdev = tp->pci_dev; ++ ++ if (tp->TxDescArray!=NULL && tp->RxDescArray!=NULL) ++ { ++ rtl8168_down(dev); ++ ++ free_irq(dev->irq, dev); ++ ++ pci_free_consistent(pdev, R8168_RX_RING_BYTES, tp->RxDescArray, ++ tp->RxPhyAddr); ++ pci_free_consistent(pdev, R8168_TX_RING_BYTES, tp->TxDescArray, ++ tp->TxPhyAddr); ++ tp->TxDescArray = NULL; ++ tp->RxDescArray = NULL; ++ } ++ ++ return 0; ++} ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11) ++static void rtl8168_shutdown(struct pci_dev *pdev) ++{ ++ struct net_device *dev = pci_get_drvdata(pdev); ++ struct rtl8168_private *tp = netdev_priv(dev); ++ ++ /* restore the original MAC address */ ++ rtl8168_rar_set(tp, tp->org_mac_addr); ++ ++ rtl8168_close(dev); ++ rtl8168_disable_msi(pdev, tp); ++} ++#endif ++ ++static void ++rtl8168_set_rx_mode(struct net_device *dev) ++{ ++ struct rtl8168_private *tp = netdev_priv(dev); ++ void __iomem *ioaddr = tp->mmio_addr; ++ unsigned long flags; ++ u32 mc_filter[2]; /* Multicast hash filter */ ++ int rx_mode; ++ u32 tmp = 0; ++ ++ if (dev->flags & IFF_PROMISC) { ++ /* Unconditionally log net taps. */ ++ if (netif_msg_link(tp)) { ++ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", ++ dev->name); ++ } ++ rx_mode = ++ AcceptBroadcast | AcceptMulticast | AcceptMyPhys | ++ AcceptAllPhys; ++ mc_filter[1] = mc_filter[0] = 0xffffffff; ++ } else if ((netdev_mc_count(dev) > multicast_filter_limit) ++ || (dev->flags & IFF_ALLMULTI)) { ++ /* Too many to filter perfectly -- accept all multicasts. */ ++ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; ++ mc_filter[1] = mc_filter[0] = 0xffffffff; ++ } else { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++ struct dev_mc_list *mclist; ++ unsigned int i; ++ ++ rx_mode = AcceptBroadcast | AcceptMyPhys; ++ mc_filter[1] = mc_filter[0] = 0; ++ for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; ++ i++, mclist = mclist->next) { ++ int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; ++ mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); ++ rx_mode |= AcceptMulticast; ++ } ++#else ++ struct netdev_hw_addr *ha; ++ ++ rx_mode = AcceptBroadcast | AcceptMyPhys; ++ mc_filter[1] = mc_filter[0] = 0; ++ netdev_for_each_mc_addr(ha, dev) { ++ int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; ++ mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); ++ rx_mode |= AcceptMulticast; ++ } ++#endif ++ } ++ ++ spin_lock_irqsave(&tp->lock, flags); ++ ++ tmp = mc_filter[0]; ++ mc_filter[0] = swab32(mc_filter[1]); ++ mc_filter[1] = swab32(tmp); ++ ++ tp->rtl8168_rx_config = rtl_chip_info[tp->chipset].RCR_Cfg; ++ tmp = tp->rtl8168_rx_config | rx_mode | (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); ++ ++ RTL_W32(RxConfig, tmp); ++ RTL_W32(MAR0 + 0, mc_filter[0]); ++ RTL_W32(MAR0 + 4, mc_filter[1]); ++ ++ spin_unlock_irqrestore(&tp->lock, flags); ++} ++ ++/** ++ * rtl8168_get_stats - Get rtl8168 read/write statistics ++ * @dev: The Ethernet Device to get statistics for ++ * ++ * Get TX/RX statistics for rtl8168 ++ */ ++static struct ++net_device_stats *rtl8168_get_stats(struct net_device *dev) ++{ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ++ struct rtl8168_private *tp = netdev_priv(dev); ++#endif ++// unsigned long flags; ++ ++ if (netif_running(dev)) { ++// spin_lock_irqsave(&tp->lock, flags); ++// spin_unlock_irqrestore(&tp->lock, flags); ++ } ++ ++ return &RTLDEV->stats; ++} ++ ++#ifdef CONFIG_PM ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) ++static int ++rtl8168_suspend(struct pci_dev *pdev, u32 state) ++#else ++static int ++rtl8168_suspend(struct pci_dev *pdev, pm_message_t state) ++#endif ++{ ++ struct net_device *dev = pci_get_drvdata(pdev); ++ struct rtl8168_private *tp = netdev_priv(dev); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) ++ u32 pci_pm_state = pci_choose_state(pdev, state); ++#endif ++ ++ if (!netif_running(dev)) ++ goto out; ++ ++ netif_stop_queue(dev); ++ ++ del_timer_sync(&tp->esd_timer); ++ ++ rtl8168_dsm(dev, DSM_NIC_GOTO_D3); ++ ++ netif_device_detach(dev); ++ ++ spin_lock_irq(&tp->lock); ++ ++ rtl8168_asic_down(dev); ++ ++ rtl8168_sleep_rx_enable(dev); ++ ++ spin_unlock_irq(&tp->lock); ++ ++ rtl8168_powerdown_pll(dev); ++ ++out: ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) ++ pci_save_state(pdev, &pci_pm_state); ++#else ++ pci_save_state(pdev); ++#endif ++ pci_enable_wake(pdev, pci_choose_state(pdev, state), tp->wol_enabled); ++// pci_set_power_state(pdev, pci_choose_state(pdev, state)); ++ ++ return 0; ++} ++ ++static int ++rtl8168_resume(struct pci_dev *pdev) ++{ ++ struct net_device *dev = pci_get_drvdata(pdev); ++ struct rtl8168_private *tp = netdev_priv(dev); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) ++ u32 pci_pm_state = PCI_D0; ++#endif ++ ++ pci_set_power_state(pdev, PCI_D0); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) ++ pci_restore_state(pdev, &pci_pm_state); ++#else ++ pci_restore_state(pdev); ++#endif ++ pci_enable_wake(pdev, PCI_D0, 0); ++ ++ /* restore last modified mac address */ ++ rtl8168_rar_set(tp, dev->dev_addr); ++ ++ if (!netif_running(dev)) ++ goto out; ++ ++ rtl8168_rx_desc_offset0_init(tp, 1); ++ ++ rtl8168_dsm(dev, DSM_NIC_RESUME_D3); ++ ++ rtl8168_powerup_pll(dev); ++ ++ rtl8168_schedule_work(dev, rtl8168_reset_task); ++ ++ netif_device_attach(dev); ++ ++ mod_timer(&tp->esd_timer, jiffies + RTL8168_ESD_TIMEOUT); ++out: ++ return 0; ++} ++ ++#endif /* CONFIG_PM */ ++ ++static struct pci_driver rtl8168_pci_driver = { ++ .name = MODULENAME, ++ .id_table = rtl8168_pci_tbl, ++ .probe = rtl8168_init_one, ++ .remove = __devexit_p(rtl8168_remove_one), ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11) ++ .shutdown = rtl8168_shutdown, ++#endif ++#ifdef CONFIG_PM ++ .suspend = rtl8168_suspend, ++ .resume = rtl8168_resume, ++#endif ++}; ++ ++static int __init ++rtl8168_init_module(void) ++{ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++ return pci_register_driver(&rtl8168_pci_driver); ++#else ++ return pci_module_init(&rtl8168_pci_driver); ++#endif ++} ++ ++static void __exit ++rtl8168_cleanup_module(void) ++{ ++ pci_unregister_driver(&rtl8168_pci_driver); ++} ++ ++module_init(rtl8168_init_module); ++module_exit(rtl8168_cleanup_module); +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index 0cf2351..eabb87f 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -266,7 +266,6 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, RTL_CFG_2 }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_0 }, +- { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302), 0, 0, RTL_CFG_0 }, +diff --git a/drivers/net/ethernet/realtek/rtl_eeprom.c b/drivers/net/ethernet/realtek/rtl_eeprom.c +new file mode 100644 +index 0000000..29caa79 +--- /dev/null ++++ b/drivers/net/ethernet/realtek/rtl_eeprom.c +@@ -0,0 +1,290 @@ ++/* ++################################################################################ ++# ++# r8101 is the Linux device driver released for RealTek RTL8101E, RTL8102E, ++# and RTL8103E Fast Ethernet controllers with PCI-Express interface. ++# ++# Copyright(c) 2012 Realtek Semiconductor Corp. All rights reserved. ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the Free ++# Software Foundation; either version 2 of the License, or (at your option) ++# any later version. ++# ++# This program 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 ++# this program; if not, see . ++# ++# Author: ++# Realtek NIC software team ++# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan ++# ++################################################################################ ++*/ ++ ++/* ++ * This product is covered by one or more of the following patents: ++ * US5,307,459, US5,434,872, US5,732,094, US6,570,884, US6,115,776, and US6,327,625. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "r8168.h" ++#include "rtl_eeprom.h" ++ ++//------------------------------------------------------------------- ++//rtl_eeprom_type(): ++// tell the eeprom type ++//return value: ++// 0: the eeprom type is 93C46 ++// 1: the eeprom type is 93C56 or 93C66 ++//------------------------------------------------------------------- ++void rtl_eeprom_type(struct rtl8168_private *tp) ++{ ++ void __iomem *ioaddr=tp->mmio_addr; ++ u16 magic = 0; ++ ++ if (tp->mcfg == CFG_METHOD_DEFAULT) ++ goto out_no_eeprom; ++ ++ if(RTL_R8(0xD2)&0x04) ++ { ++ tp->eeprom_type = EEPROM_TWSI; ++ tp->eeprom_len = 256; ++ } ++ else if(RTL_R32(RxConfig) & RxCfg_9356SEL) ++ { ++ tp->eeprom_type = EEPROM_TYPE_93C56; ++ tp->eeprom_len = 256; ++ } ++ else ++ { ++ tp->eeprom_type = EEPROM_TYPE_93C46; ++ tp->eeprom_len = 128; ++ } ++ ++ magic = rtl_eeprom_read_sc(tp, 0); ++ ++out_no_eeprom: ++ if ((magic != 0x8129) && (magic != 0x8128)) ++ { ++ tp->eeprom_type = EEPROM_TYPE_NONE; ++ tp->eeprom_len = 0; ++ } ++} ++ ++void rtl_eeprom_cleanup(void __iomem *ioaddr) ++{ ++ u8 x; ++ ++ x = RTL_R8(Cfg9346); ++ x &= ~(Cfg9346_EEDI | Cfg9346_EECS); ++ ++ RTL_W8(Cfg9346, x); ++ ++ rtl_raise_clock(&x, ioaddr); ++ rtl_lower_clock(&x, ioaddr); ++} ++ ++int rtl_eeprom_cmd_done(void __iomem *ioaddr) ++{ ++ u8 x; ++ int i; ++ ++ rtl_stand_by(ioaddr); ++ ++ for (i = 0; i < 50000; i++) { ++ x = RTL_R8(Cfg9346); ++ ++ if (x & Cfg9346_EEDO) { ++ udelay(RTL_CLOCK_RATE * 2 * 3); ++ return 0; ++ } ++ udelay(1); ++ } ++ ++ return -1; ++} ++ ++//------------------------------------------------------------------- ++//rtl_eeprom_read_sc(): ++// read one word from eeprom ++//------------------------------------------------------------------- ++u16 rtl_eeprom_read_sc(struct rtl8168_private *tp, u16 reg) ++{ ++ void __iomem *ioaddr=tp->mmio_addr; ++ int addr_sz = 6; ++ u8 x; ++ u16 data; ++ ++ if(tp->eeprom_type == EEPROM_TYPE_NONE) ++ { ++ return -1; ++ } ++ ++ if (tp->eeprom_type==EEPROM_TYPE_93C46) ++ addr_sz = 6; ++ else if (tp->eeprom_type==EEPROM_TYPE_93C56) ++ addr_sz = 8; ++ ++ x = Cfg9346_EEM1 | Cfg9346_EECS; ++ RTL_W8(Cfg9346, x); ++ ++ rtl_shift_out_bits(RTL_EEPROM_READ_OPCODE, 3, ioaddr); ++ rtl_shift_out_bits(reg, addr_sz, ioaddr); ++ ++ data = rtl_shift_in_bits(ioaddr); ++ ++ rtl_eeprom_cleanup(ioaddr); ++ ++ RTL_W8(Cfg9346, 0); ++ ++ return data; ++} ++ ++//------------------------------------------------------------------- ++//rtl_eeprom_write_sc(): ++// write one word to a specific address in the eeprom ++//------------------------------------------------------------------- ++void rtl_eeprom_write_sc(struct rtl8168_private *tp, u16 reg, u16 data) ++{ ++ void __iomem *ioaddr=tp->mmio_addr; ++ u8 x; ++ int addr_sz = 6; ++ int w_dummy_addr = 4; ++ ++ if(tp->eeprom_type == EEPROM_TYPE_NONE) ++ { ++ return ; ++ } ++ ++ if (tp->eeprom_type==EEPROM_TYPE_93C46) ++ { ++ addr_sz = 6; ++ w_dummy_addr = 4; ++ } ++ else if (tp->eeprom_type==EEPROM_TYPE_93C56) ++ { ++ addr_sz = 8; ++ w_dummy_addr = 6; ++ } ++ ++ x = Cfg9346_EEM1 | Cfg9346_EECS; ++ RTL_W8(Cfg9346, x); ++ ++ rtl_shift_out_bits(RTL_EEPROM_EWEN_OPCODE, 5, ioaddr); ++ rtl_shift_out_bits(reg, w_dummy_addr, ioaddr); ++ rtl_stand_by(ioaddr); ++ ++ rtl_shift_out_bits(RTL_EEPROM_ERASE_OPCODE, 3, ioaddr); ++ rtl_shift_out_bits(reg, addr_sz, ioaddr); ++ if (rtl_eeprom_cmd_done(ioaddr) < 0) { ++ return; ++ } ++ rtl_stand_by(ioaddr); ++ ++ rtl_shift_out_bits(RTL_EEPROM_WRITE_OPCODE, 3, ioaddr); ++ rtl_shift_out_bits(reg, addr_sz, ioaddr); ++ rtl_shift_out_bits(data, 16, ioaddr); ++ if (rtl_eeprom_cmd_done(ioaddr) < 0) { ++ return; ++ } ++ rtl_stand_by(ioaddr); ++ ++ rtl_shift_out_bits(RTL_EEPROM_EWDS_OPCODE, 5, ioaddr); ++ rtl_shift_out_bits(reg, w_dummy_addr, ioaddr); ++ ++ rtl_eeprom_cleanup(ioaddr); ++ RTL_W8(Cfg9346, 0); ++} ++ ++void rtl_raise_clock(u8 *x, void __iomem *ioaddr) ++{ ++ *x = *x | Cfg9346_EESK; ++ RTL_W8(Cfg9346, *x); ++ udelay(RTL_CLOCK_RATE); ++} ++ ++void rtl_lower_clock(u8 *x, void __iomem *ioaddr) ++{ ++ ++ *x = *x & ~Cfg9346_EESK; ++ RTL_W8(Cfg9346, *x); ++ udelay(RTL_CLOCK_RATE); ++} ++ ++void rtl_shift_out_bits(int data, int count, void __iomem *ioaddr) ++{ ++ u8 x; ++ int mask; ++ ++ mask = 0x01 << (count - 1); ++ x = RTL_R8(Cfg9346); ++ x &= ~(Cfg9346_EEDI | Cfg9346_EEDO); ++ ++ do { ++ if (data & mask) ++ x |= Cfg9346_EEDI; ++ else ++ x &= ~Cfg9346_EEDI; ++ ++ RTL_W8(Cfg9346, x); ++ udelay(RTL_CLOCK_RATE); ++ rtl_raise_clock(&x, ioaddr); ++ rtl_lower_clock(&x, ioaddr); ++ mask = mask >> 1; ++ } while(mask); ++ ++ x &= ~Cfg9346_EEDI; ++ RTL_W8(Cfg9346, x); ++} ++ ++u16 rtl_shift_in_bits(void __iomem *ioaddr) ++{ ++ u8 x; ++ u16 d, i; ++ ++ x = RTL_R8(Cfg9346); ++ x &= ~(Cfg9346_EEDI | Cfg9346_EEDO); ++ ++ d = 0; ++ ++ for (i = 0; i < 16; i++) { ++ d = d << 1; ++ rtl_raise_clock(&x, ioaddr); ++ ++ x = RTL_R8(Cfg9346); ++ x &= ~Cfg9346_EEDI; ++ ++ if (x & Cfg9346_EEDO) ++ d |= 1; ++ ++ rtl_lower_clock(&x, ioaddr); ++ } ++ ++ return d; ++} ++ ++void rtl_stand_by(void __iomem *ioaddr) ++{ ++ u8 x; ++ ++ x = RTL_R8(Cfg9346); ++ x &= ~(Cfg9346_EECS | Cfg9346_EESK); ++ RTL_W8(Cfg9346, x); ++ udelay(RTL_CLOCK_RATE); ++ ++ x |= Cfg9346_EECS; ++ RTL_W8(Cfg9346, x); ++} +diff --git a/drivers/net/ethernet/realtek/rtl_eeprom.h b/drivers/net/ethernet/realtek/rtl_eeprom.h +new file mode 100644 +index 0000000..863a1a9 +--- /dev/null ++++ b/drivers/net/ethernet/realtek/rtl_eeprom.h +@@ -0,0 +1,55 @@ ++/* ++################################################################################ ++# ++# r8101 is the Linux device driver released for RealTek RTL8101E, RTL8102E, ++# and RTL8103E Fast Ethernet controllers with PCI-Express interface. ++# ++# Copyright(c) 2012 Realtek Semiconductor Corp. All rights reserved. ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the Free ++# Software Foundation; either version 2 of the License, or (at your option) ++# any later version. ++# ++# This program 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 ++# this program; if not, see . ++# ++# Author: ++# Realtek NIC software team ++# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan ++# ++################################################################################ ++*/ ++ ++/* ++ * This product is covered by one or more of the following patents: ++ * US5,307,459, US5,434,872, US5,732,094, US6,570,884, US6,115,776, and US6,327,625. ++ */ ++ ++//EEPROM opcodes ++#define RTL_EEPROM_READ_OPCODE 06 ++#define RTL_EEPROM_WRITE_OPCODE 05 ++#define RTL_EEPROM_ERASE_OPCODE 07 ++#define RTL_EEPROM_EWEN_OPCODE 19 ++#define RTL_EEPROM_EWDS_OPCODE 16 ++ ++#define RTL_CLOCK_RATE 3 ++ ++void rtl_eeprom_type(struct rtl8168_private *tp); ++void rtl_eeprom_cleanup(void __iomem *ioaddr); ++u16 rtl_eeprom_read_sc(struct rtl8168_private *tp, u16 reg); ++void rtl_eeprom_write_sc(struct rtl8168_private *tp, u16 reg, u16 data); ++void rtl_shift_out_bits(int data, int count, void __iomem *ioaddr); ++u16 rtl_shift_in_bits(void __iomem *ioaddr); ++void rtl_raise_clock(u8 *x, void __iomem *ioaddr); ++void rtl_lower_clock(u8 *x, void __iomem *ioaddr); ++void rtl_stand_by(void __iomem *ioaddr); ++ ++ ++ ++ +diff --git a/drivers/net/ethernet/realtek/rtltool.c b/drivers/net/ethernet/realtek/rtltool.c +new file mode 100644 +index 0000000..fd86772 +--- /dev/null ++++ b/drivers/net/ethernet/realtek/rtltool.c +@@ -0,0 +1,338 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "r8168.h" ++#include "rtl_eeprom.h" ++#include "rtltool.h" ++ ++static int ++OOB_set_ip_mac(struct rtl8168_private *tp, struct sockaddr_in *sa, u8 *mac) ++{ ++ u32 data; ++ ++ if (tp->mcfg == CFG_METHOD_13) { ++ OCP_write(tp, 0xF, 0xd0, be32_to_cpu(sa->sin_addr.s_addr)); ++ ++ memcpy(&data, mac, 4); ++ OCP_write(tp, 0xF, 0x00, le32_to_cpu(data)); ++ data = 0; ++ memcpy(&data, mac + 4, 2); ++ OCP_write(tp, 0x3, 0x04, le32_to_cpu(data)); ++ ++ OOB_notify(tp, OOB_CMD_SET_IPMAC); ++ } else if (tp->mcfg == CFG_METHOD_17) { ++ void __iomem *ioaddr = tp->mmio_addr; ++ struct net_device *dev = tp->dev; ++ u32 rx_mode; ++ ++ rx_mode = RTL_R32(RxConfig); ++ if (netif_running(dev)) { ++ netif_stop_queue(dev); ++ RTL_W32(RxConfig, rx_mode & ~0x3f); ++ while ((RTL_R8(0xd3) & (BIT_5 | BIT_4)) != ((BIT_5 | BIT_4))) ++ udelay(20); ++ RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); ++/* } else { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, 0x1f, 0x0000); ++ data = mdio_read(tp, MII_CTRL1000); ++ data &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); ++ mdio_write(tp, MII_CTRL1000, data); ++ mdio_write(tp, 0x00, 0x9200); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ ssleep(3); ++ RTL_W16(IntrStatus, RTL_R16(IntrStatus)); ++ ++ RTL_W32(MAR0, 0); ++ RTL_W32(MAR0 + 4, 0); ++ RTL_W16(RxMaxSize, 0x05f3);*/ ++ } ++ RTL_W8(0xD3, RTL_R8(0xD3) & ~BIT_7); ++ rtl8168_eri_write(ioaddr, 0x180, 4, 0x06080888, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0x184, 4, 0xdd860008, ERIAR_ExGMAC); ++ ++ memcpy(&data, mac, 2); ++ rtl8168_eri_write(ioaddr, 0xf0, 4, (le32_to_cpu(data) << 16), ERIAR_ExGMAC); ++ memcpy(&data, mac + 2, 4); ++ rtl8168_eri_write(ioaddr, 0xf4, 4, le32_to_cpu(data), ERIAR_ExGMAC); ++ ++ rtl8168_eri_write(ioaddr, 0x190, 4, 0x3c110600, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0x194, 4, 0x2c32332b, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0x198, 4, 0x003a0201, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0x19c, 4, 0x00000000, ERIAR_ExGMAC); ++ ++ rtl8168_eri_write(ioaddr, 0x1f0, 4, cpu_to_le32(sa->sin_addr.s_addr), ERIAR_ExGMAC); ++ ++ memcpy(&data, mac, 4); ++ rtl8168_eri_write(ioaddr, 0x258, 4, le32_to_cpu(data), ERIAR_ExGMAC); ++ memcpy(&data, mac + 4, 2); ++ rtl8168_eri_write(ioaddr, 0x25c, 2, le32_to_cpu(data), ERIAR_ExGMAC); ++ ++ RTL_W8(0xe0, RTL_R8(0xe0) | BIT_6); ++ while (!(RTL_R8(0xd3) & BIT_1)) ++ udelay(20); ++ ++ RTL_W32(0xb0, 0x9800e035); ++ RTL_W32(0xb0, 0x9801e034); ++ RTL_W32(0xb0, 0x9802e019); ++ RTL_W32(0xb0, 0x98039918); ++ RTL_W32(0xb0, 0x9804c011); ++ RTL_W32(0xb0, 0x98057100); ++ RTL_W32(0xb0, 0x9806499f); ++ RTL_W32(0xb0, 0x9807f011); ++ RTL_W32(0xb0, 0x9808c00e); ++ RTL_W32(0xb0, 0x98097100); ++ RTL_W32(0xb0, 0x980A4995); ++ RTL_W32(0xb0, 0x980Bf00d); ++ RTL_W32(0xb0, 0x980C4895); ++ RTL_W32(0xb0, 0x980D9900); ++ RTL_W32(0xb0, 0x980Ec009); ++ RTL_W32(0xb0, 0x980F7100); ++ RTL_W32(0xb0, 0x98104890); ++ RTL_W32(0xb0, 0x98119900); ++ RTL_W32(0xb0, 0x98124810); ++ RTL_W32(0xb0, 0x98139900); ++ RTL_W32(0xb0, 0x9814e004); ++ RTL_W32(0xb0, 0x9815d44e); ++ RTL_W32(0xb0, 0x9816d506); ++ RTL_W32(0xb0, 0x9817c0b4); ++ RTL_W32(0xb0, 0x9818c002); ++ RTL_W32(0xb0, 0x9819b800); ++ RTL_W32(0xb0, 0x981A0500); ++ RTL_W32(0xb0, 0x981B1a26); ++ RTL_W32(0xb0, 0x981Ca4ca); ++ RTL_W32(0xb0, 0x981D21bc); ++ RTL_W32(0xb0, 0x981E25bc); ++ RTL_W32(0xb0, 0x981F1305); ++ RTL_W32(0xb0, 0x9820f00d); ++ RTL_W32(0xb0, 0x9821c213); ++ RTL_W32(0xb0, 0x98227340); ++ RTL_W32(0xb0, 0x982349b0); ++ RTL_W32(0xb0, 0x9824f009); ++ RTL_W32(0xb0, 0x98251a3a); ++ RTL_W32(0xb0, 0x9826a4ca); ++ RTL_W32(0xb0, 0x982721b9); ++ RTL_W32(0xb0, 0x982825b9); ++ RTL_W32(0xb0, 0x98291303); ++ RTL_W32(0xb0, 0x982Af006); ++ RTL_W32(0xb0, 0x982B1309); ++ RTL_W32(0xb0, 0x982Cf004); ++ RTL_W32(0xb0, 0x982Dc306); ++ RTL_W32(0xb0, 0x982E1a26); ++ RTL_W32(0xb0, 0x982Fbb00); ++ RTL_W32(0xb0, 0x9830c302); ++ RTL_W32(0xb0, 0x9831bb00); ++ RTL_W32(0xb0, 0x98320f3e); ++ RTL_W32(0xb0, 0x98330f4e); ++ RTL_W32(0xb0, 0x9834c0ae); ++ RTL_W32(0xb0, 0x98351800); ++ RTL_W32(0xb0, 0x9836b800); ++ RTL_W32(0xb0, 0xfe173000); ++ RTL_W32(0xb0, 0xfe1604ff); ++ RTL_W32(0xb0, 0xfe150f4d); ++ data = rtl8168_eri_read(ioaddr, 0xd6, 1, ERIAR_ExGMAC); ++ rtl8168_eri_write(ioaddr, 0xd6, 1, data | BIT_0, ERIAR_ExGMAC); ++ ++ if (netif_running(dev)) { ++ rtl8168_init_ring_indexes(tp); ++ RTL_W8(ChipCmd, CmdRxEnb | CmdTxEnb); ++ RTL_W32(RxConfig, rx_mode); ++ netif_wake_queue(dev); ++ } else { ++ RTL_W8(0xD3, RTL_R8(0xD3) | BIT_7); ++ ++// data = rtl8168_eri_read(ioaddr, 0xDC, 1, ERIAR_ExGMAC); ++// data &= ~BIT_0; ++// rtl8168_eri_write( ioaddr, 0xDC, 1, data, ERIAR_ExGMAC); ++// data |= BIT_0; ++// rtl8168_eri_write( ioaddr, 0xDC, 1, data, ERIAR_ExGMAC); ++ ++ RTL_W32(RxConfig, rx_mode | 0x0e); ++ } ++ } else { ++ return -EFAULT; ++ } ++ return 0; ++} ++ ++int rtltool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr) ++{ ++ struct rtltool_cmd my_cmd; ++ unsigned long flags; ++ int ret; ++ ++ if (copy_from_user(&my_cmd, ifr->ifr_data, sizeof(my_cmd))) ++ return -EFAULT; ++ ++ ret = 0; ++ switch (my_cmd.cmd) { ++ case RTLTOOL_READ_MAC: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ if (my_cmd.len==1) ++ my_cmd.data = readb(tp->mmio_addr+my_cmd.offset); ++ else if (my_cmd.len==2) ++ my_cmd.data = readw(tp->mmio_addr+(my_cmd.offset&~1)); ++ else if (my_cmd.len==4) ++ my_cmd.data = readl(tp->mmio_addr+(my_cmd.offset&~3)); ++ else { ++ ret = -EOPNOTSUPP; ++ break; ++ } ++ ++ if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { ++ ret = -EFAULT; ++ break; ++ } ++ break; ++ ++ case RTLTOOL_WRITE_MAC: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ if (my_cmd.len==1) ++ writeb(my_cmd.data, tp->mmio_addr+my_cmd.offset); ++ else if (my_cmd.len==2) ++ writew(my_cmd.data, tp->mmio_addr+(my_cmd.offset&~1)); ++ else if (my_cmd.len==4) ++ writel(my_cmd.data, tp->mmio_addr+(my_cmd.offset&~3)); ++ else { ++ ret = -EOPNOTSUPP; ++ break; ++ } ++ ++ break; ++ ++ case RTLTOOL_READ_PHY: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ my_cmd.data = mdio_read(tp, my_cmd.offset); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ ++ if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { ++ ret = -EFAULT; ++ break; ++ } ++ ++ break; ++ ++ case RTLTOOL_WRITE_PHY: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ spin_lock_irqsave(&tp->phy_lock, flags); ++ mdio_write(tp, my_cmd.offset, my_cmd.data); ++ spin_unlock_irqrestore(&tp->phy_lock, flags); ++ break; ++ ++ case RTLTOOL_READ_EPHY: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ my_cmd.data = rtl8168_ephy_read(tp->mmio_addr, my_cmd.offset); ++ ++ if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { ++ ret = -EFAULT; ++ break; ++ } ++ ++ break; ++ ++ case RTLTOOL_WRITE_EPHY: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ rtl8168_ephy_write(tp->mmio_addr, my_cmd.offset, my_cmd.data); ++ break; ++ ++ case RTLTOOL_READ_PCI: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ my_cmd.data = 0; ++ if (my_cmd.len==1) ++ pci_read_config_byte(tp->pci_dev, my_cmd.offset, ++ (u8 *)&my_cmd.data); ++ else if (my_cmd.len==2) ++ pci_read_config_word(tp->pci_dev, my_cmd.offset, ++ (u16 *)&my_cmd.data); ++ else if (my_cmd.len==4) ++ pci_read_config_dword(tp->pci_dev, my_cmd.offset, ++ &my_cmd.data); ++ else { ++ ret = -EOPNOTSUPP; ++ break; ++ } ++ ++ if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { ++ ret = -EFAULT; ++ break; ++ } ++ break; ++ ++ case RTLTOOL_WRITE_PCI: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ if (my_cmd.len==1) ++ pci_write_config_byte(tp->pci_dev, my_cmd.offset, ++ my_cmd.data); ++ else if (my_cmd.len==2) ++ pci_write_config_word(tp->pci_dev, my_cmd.offset, ++ my_cmd.data); ++ else if (my_cmd.len==4) ++ pci_write_config_dword(tp->pci_dev, my_cmd.offset, ++ my_cmd.data); ++ else { ++ ret = -EOPNOTSUPP; ++ break; ++ } ++ ++ break; ++ ++ case RTLTOOL_READ_EEPROM: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ my_cmd.data = rtl_eeprom_read_sc(tp, my_cmd.offset); ++ ++ if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { ++ ret = -EFAULT; ++ break; ++ } ++ ++ break; ++ ++ case RTLTOOL_WRITE_EEPROM: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ ++ rtl_eeprom_write_sc(tp->mmio_addr, my_cmd.offset, my_cmd.data); ++ break; ++ ++ case RTL_ARP_NS_OFFLOAD: ++ break; ++ ++ case RTL_SET_OOB_IPMAC: ++ ret = OOB_set_ip_mac(tp, ++ (struct sockaddr_in *)&my_cmd.ifru_addr, ++ my_cmd.ifru_hwaddr.sa_data); ++ break; ++ ++ default: ++ ret = -EOPNOTSUPP; ++ break; ++ } ++ ++ return ret; ++} +diff --git a/drivers/net/ethernet/realtek/rtltool.h b/drivers/net/ethernet/realtek/rtltool.h +new file mode 100644 +index 0000000..5a2cdc9 +--- /dev/null ++++ b/drivers/net/ethernet/realtek/rtltool.h +@@ -0,0 +1,44 @@ ++#ifndef _LINUX_RTLTOOL_H ++#define _LINUX_RTLTOOL_H ++ ++#define SIOCRTLTOOL SIOCDEVPRIVATE+1 ++ ++enum rtl_cmd { ++ RTLTOOL_READ_MAC=0, ++ RTLTOOL_WRITE_MAC, ++ RTLTOOL_READ_PHY, ++ RTLTOOL_WRITE_PHY, ++ RTLTOOL_READ_EPHY, ++ RTLTOOL_WRITE_EPHY, ++ RTLTOOL_READ_PCI, ++ RTLTOOL_WRITE_PCI, ++ RTLTOOL_READ_EEPROM, ++ RTLTOOL_WRITE_EEPROM, ++ ++ RTL_ARP_NS_OFFLOAD, ++ RTL_SET_OOB_IPMAC, ++ ++ RTLTOOL_INVALID ++}; ++ ++struct rtltool_cmd { ++ __u32 cmd; ++ __u32 offset; ++ __u32 len; ++ __u32 data; ++ struct sockaddr ifru_addr; ++ struct sockaddr ifru_netmask; ++ struct sockaddr ifru_hwaddr; ++}; ++ ++enum mode_access { ++ MODE_NONE=0, ++ MODE_READ, ++ MODE_WRITE ++}; ++ ++#ifdef __KERNEL__ ++int rtltool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr); ++#endif ++ ++#endif /* _LINUX_RTLTOOL_H */ diff --git a/packages/linux/patches/linux-3.2.30-990-xc5000_add_support_for_get_if_frequency.patch b/packages/linux/patches/linux-3.2.30-990-xc5000_add_support_for_get_if_frequency.patch new file mode 100644 index 0000000000..6f5c3dcb22 --- /dev/null +++ b/packages/linux/patches/linux-3.2.30-990-xc5000_add_support_for_get_if_frequency.patch @@ -0,0 +1,45 @@ +From 35621030c0bd5cb4f1a345cf2b4a97e290bc244a Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 23 Sep 2011 13:03:42 -0300 +Subject: [PATCH] [media] xc5000: Add support for get_if_frequency + +This is needed for devices with DRX-K and xc5000. + +Tested with a HVR 930C hardware. + +Signed-off-by: Mauro Carvalho Chehab +--- + drivers/media/common/tuners/xc5000.c | 9 +++++++++ + 1 files changed, 9 insertions(+), 0 deletions(-) + +diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c +index 88b329c..ecd1f95 100644 +--- a/drivers/media/common/tuners/xc5000.c ++++ b/drivers/media/common/tuners/xc5000.c +@@ -968,6 +968,14 @@ static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq) + return 0; + } + ++static int xc5000_get_if_frequency(struct dvb_frontend *fe, u32 *freq) ++{ ++ struct xc5000_priv *priv = fe->tuner_priv; ++ dprintk(1, "%s()\n", __func__); ++ *freq = priv->if_khz * 1000; ++ return 0; ++} ++ + static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw) + { + struct xc5000_priv *priv = fe->tuner_priv; +@@ -1108,6 +1116,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = { + .set_params = xc5000_set_params, + .set_analog_params = xc5000_set_analog_params, + .get_frequency = xc5000_get_frequency, ++ .get_if_frequency = xc5000_get_if_frequency, + .get_bandwidth = xc5000_get_bandwidth, + .get_status = xc5000_get_status + }; +-- +1.7.2.5 + + diff --git a/packages/linux/patches/linux-3.2.28-999-fix-iMon-Knob-event-interpretation-issues.patch b/packages/linux/patches/linux-3.2.30-999-fix-iMon-Knob-event-interpretation-issues.patch similarity index 100% rename from packages/linux/patches/linux-3.2.28-999-fix-iMon-Knob-event-interpretation-issues.patch rename to packages/linux/patches/linux-3.2.30-999-fix-iMon-Knob-event-interpretation-issues.patch diff --git a/packages/mediacenter/xbmc-frodo-theme-Confluence/meta b/packages/mediacenter/xbmc-frodo-theme-Confluence/meta index 750ab78f10..6facd0394d 100644 --- a/packages/mediacenter/xbmc-frodo-theme-Confluence/meta +++ b/packages/mediacenter/xbmc-frodo-theme-Confluence/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xbmc-frodo-theme-Confluence" -PKG_VERSION="ba2c709" +PKG_VERSION="a642b33" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/mediacenter/xbmc-frodo/init.d/93_xbmc b/packages/mediacenter/xbmc-frodo/init.d/93_xbmc index d33fb5ff40..164310c603 100644 --- a/packages/mediacenter/xbmc-frodo/init.d/93_xbmc +++ b/packages/mediacenter/xbmc-frodo/init.d/93_xbmc @@ -54,8 +54,8 @@ fi # set cpu's to 'conservative' ( usleep 15000000 - progress "set cpu's to 'conservative'" - cpupower frequency-set -g conservative > /dev/null 2>&1 + progress "set cpu's to 'ondemand'" + cpupower frequency-set -g ondemand > /dev/null 2>&1 )& # prevent restrating XBMC at reboot or shutdown diff --git a/packages/mediacenter/xbmc-frodo/meta b/packages/mediacenter/xbmc-frodo/meta index 9a34c11c0a..65bdda4631 100644 --- a/packages/mediacenter/xbmc-frodo/meta +++ b/packages/mediacenter/xbmc-frodo/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xbmc-frodo" -PKG_VERSION="ba2c709" +PKG_VERSION="a642b33" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-001-add_support_to_specify_GIT_REV-0.1.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-001-add_support_to_specify_GIT_REV-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-001-add_support_to_specify_GIT_REV-0.1.patch rename to packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-001-add_support_to_specify_GIT_REV-0.1.patch diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-303-fix_libdvd_xFLAGS-0.1.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-303-fix_libdvd_xFLAGS-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-303-fix_libdvd_xFLAGS-0.1.patch rename to packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-303-fix_libdvd_xFLAGS-0.1.patch diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-311-fix_rsxs_build-0.1.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-311-fix_rsxs_build-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-311-fix_rsxs_build-0.1.patch rename to packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-311-fix_rsxs_build-0.1.patch diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-321-texturepacker-hostflags-and-rework.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-321-texturepacker-hostflags-and-rework.patch similarity index 85% rename from packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-321-texturepacker-hostflags-and-rework.patch rename to packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-321-texturepacker-hostflags-and-rework.patch index db7d6f6c61..4d54002c02 100644 --- a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-321-texturepacker-hostflags-and-rework.patch +++ b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-321-texturepacker-hostflags-and-rework.patch @@ -1,7 +1,7 @@ -diff -Naur xbmc-frodo-5ea1d22/configure.in xbmc-frodo-5ea1d22.patch/configure.in ---- xbmc-frodo-5ea1d22/configure.in 2012-09-05 13:27:56.000000000 +0200 -+++ xbmc-frodo-5ea1d22.patch/configure.in 2012-09-05 17:55:46.727316107 +0200 -@@ -437,6 +437,12 @@ +diff -Naur xbmc-frodo-a642b33/configure.in xbmc-frodo-a642b33.patch/configure.in +--- xbmc-frodo-a642b33/configure.in 2012-09-25 15:44:35.000000000 +0200 ++++ xbmc-frodo-a642b33.patch/configure.in 2012-09-25 16:17:31.666076439 +0200 +@@ -445,6 +445,12 @@ [use_texturepacker=$enableval], [use_texturepacker=auto]) @@ -14,7 +14,7 @@ diff -Naur xbmc-frodo-5ea1d22/configure.in xbmc-frodo-5ea1d22.patch/configure.in AC_ARG_WITH([lirc-device], [AS_HELP_STRING([--with-lirc-device=file], [specify the default LIRC device (default is /dev/lircd)])], -@@ -570,8 +576,7 @@ +@@ -584,8 +590,7 @@ use_cpu=cortex-a8 check_sdl_arch=[`file /opt/local/lib/libSDL_image.dylib | awk '{V=7; print $V}'`] if test "x$check_sdl_arch" = "xi386"; then @@ -24,7 +24,7 @@ diff -Naur xbmc-frodo-5ea1d22/configure.in xbmc-frodo-5ea1d22.patch/configure.in else use_texturepacker=no fi -@@ -587,8 +592,6 @@ +@@ -601,8 +606,6 @@ *86*-apple-darwin*) use_joystick=no use_vtbdecoder=no @@ -33,7 +33,7 @@ diff -Naur xbmc-frodo-5ea1d22/configure.in xbmc-frodo-5ea1d22.patch/configure.in ARCH="x86-osx" AC_SUBST(ARCH_DEFINES, "-DTARGET_POSIX -DTARGET_DARWIN -DTARGET_DARWIN_OSX -D_LINUX") ;; -@@ -1938,13 +1941,13 @@ +@@ -1987,13 +1990,13 @@ USE_TEXTUREPACKER_NATIVE=0 if test "x$use_texturepacker" != "xno"; then @@ -52,9 +52,9 @@ diff -Naur xbmc-frodo-5ea1d22/configure.in xbmc-frodo-5ea1d22.patch/configure.in fi else final_message="$final_message\n TexturePacker:No" -diff -Naur xbmc-frodo-5ea1d22/lib/libsquish/Makefile.in xbmc-frodo-5ea1d22.patch/lib/libsquish/Makefile.in ---- xbmc-frodo-5ea1d22/lib/libsquish/Makefile.in 2012-09-05 13:28:31.000000000 +0200 -+++ xbmc-frodo-5ea1d22.patch/lib/libsquish/Makefile.in 2012-09-05 17:56:05.017178267 +0200 +diff -Naur xbmc-frodo-a642b33/lib/libsquish/Makefile.in xbmc-frodo-a642b33.patch/lib/libsquish/Makefile.in +--- xbmc-frodo-a642b33/lib/libsquish/Makefile.in 2012-09-25 15:45:45.000000000 +0200 ++++ xbmc-frodo-a642b33.patch/lib/libsquish/Makefile.in 2012-09-25 16:17:31.666076439 +0200 @@ -11,26 +11,25 @@ singlecolourfit.cpp \ squish.cpp @@ -93,9 +93,9 @@ diff -Naur xbmc-frodo-5ea1d22/lib/libsquish/Makefile.in xbmc-frodo-5ea1d22.patch endif include ../../Makefile.include -diff -Naur xbmc-frodo-5ea1d22/tools/TexturePacker/Makefile.in xbmc-frodo-5ea1d22.patch/tools/TexturePacker/Makefile.in ---- xbmc-frodo-5ea1d22/tools/TexturePacker/Makefile.in 2012-09-05 13:28:16.000000000 +0200 -+++ xbmc-frodo-5ea1d22.patch/tools/TexturePacker/Makefile.in 2012-09-05 17:55:49.927291649 +0200 +diff -Naur xbmc-frodo-a642b33/tools/TexturePacker/Makefile.in xbmc-frodo-a642b33.patch/tools/TexturePacker/Makefile.in +--- xbmc-frodo-a642b33/tools/TexturePacker/Makefile.in 2012-09-25 15:44:57.000000000 +0200 ++++ xbmc-frodo-a642b33.patch/tools/TexturePacker/Makefile.in 2012-09-25 16:19:08.889015705 +0200 @@ -1,56 +1,54 @@ -DEFINES += -D_LINUX -DUSE_LZO_PACKING +DEFINES += -D_LINUX -DUSE_LZO_PACKING @@ -179,7 +179,7 @@ diff -Naur xbmc-frodo-5ea1d22/tools/TexturePacker/Makefile.in xbmc-frodo-5ea1d22 ifeq (@USE_TEXTUREPACKER_NATIVE@,1) # TexturePacker run native on build system, build it with native tools - $(TARGET): $(SRCS) + $(TARGET): $(SRCS) @abs_top_srcdir@/xbmc/guilib/XBTF.h - g++ $(DEFINES) $(NATIVE_ARCH) $(NATIVE_CXXFLAGS) $(SRCS) $(NATIVE_LIBS) $(RPATH) -o $(TARGET) + make -C @abs_top_srcdir@/lib/libsquish libsquish-native.so + $(HOST_CXX) $(DEFINES) $(NATIVE_ARCH) $(HOST_CXXFLAGS) $(SRCS) $(HOST_LIBS) $(RPATH) -o $(TARGET) diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch rename to packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-408-enable_PYTHONOPTIMIZE_with_external_Python-0.1.patch diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-452-change_lcd_content-0.1.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-452-change_lcd_content-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-452-change_lcd_content-0.1.patch rename to packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-452-change_lcd_content-0.1.patch diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-453-add_openelec.tv_RSS_news-0.1.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-453-add_openelec.tv_RSS_news-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-453-add_openelec.tv_RSS_news-0.1.patch rename to packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-453-add_openelec.tv_RSS_news-0.1.patch diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-454-disable_backslash-0.1.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-454-disable_backslash-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-454-disable_backslash-0.1.patch rename to packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-454-disable_backslash-0.1.patch diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-457-fix_connection_check-0.1.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-457-fix_connection_check-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-457-fix_connection_check-0.1.patch rename to packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-457-fix_connection_check-0.1.patch diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-463-add_remote_devinput-0.1.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-463-add_remote_devinput-0.1.patch similarity index 100% rename from packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-463-add_remote_devinput-0.1.patch rename to packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-463-add_remote_devinput-0.1.patch diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-901-PR1426.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-901-PR1426.patch new file mode 100644 index 0000000000..bd103a4c90 --- /dev/null +++ b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-901-PR1426.patch @@ -0,0 +1,38 @@ +From 735e49e62dc07cbe94cb75e9069a01b1b985f70f Mon Sep 17 00:00:00 2001 +From: Cory Fields +Date: Fri, 14 Sep 2012 15:35:32 -0400 +Subject: [PATCH] d-r: enable dirty-regions by default + +This enables the all-or-nothing mode, which means that we repaint the entire +screen if there's a single dirty region. + +Also, nofliptimeout=0 is set to ensure that we never flip without rendering. + +With these combined, this should be universally safe (and within spec) for all +gfx cards/drivers. + +The main possible side-effect is the slow-motion effect brought about on slower +cpus that can't keep up at times and produce wild timestamps. With our improved +decoding and caching, this is now quite rare. +--- + xbmc/settings/AdvancedSettings.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp +index 47aaf7e..6f75227 100644 +--- a/xbmc/settings/AdvancedSettings.cpp ++++ b/xbmc/settings/AdvancedSettings.cpp +@@ -306,8 +306,8 @@ void CAdvancedSettings::Initialize() + + m_canWindowed = true; + m_guiVisualizeDirtyRegions = false; +- m_guiAlgorithmDirtyRegions = 0; +- m_guiDirtyRegionNoFlipTimeout = -1; ++ m_guiAlgorithmDirtyRegions = 3; ++ m_guiDirtyRegionNoFlipTimeout = 0; + m_logEnableAirtunes = false; + m_airTunesPort = 36666; + m_airPlayPort = 36667; +-- +1.7.10 + diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-901-PR1435.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-901-PR1435.patch new file mode 100644 index 0000000000..190c9533fe --- /dev/null +++ b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-901-PR1435.patch @@ -0,0 +1,28 @@ +From 7c5b281bf4403de8a02a3793188a4d735efafe9a Mon Sep 17 00:00:00 2001 +From: epideme +Date: Sun, 16 Sep 2012 19:57:52 +0300 +Subject: [PATCH] [rbp] Allow OMXPlayer to try playing DVD/BD-iso + +Now that scaling is fixed and overlays behave better, and license for MPG2 codec is available, allow iso playback with a warning in the debug log. +--- + xbmc/cores/omxplayer/OMXPlayer.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp +index a3736df..1fc32b4 100644 +--- a/xbmc/cores/omxplayer/OMXPlayer.cpp ++++ b/xbmc/cores/omxplayer/OMXPlayer.cpp +@@ -590,8 +590,8 @@ bool COMXPlayer::OpenInputStream() + if (m_pInputStream && ( m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD) + || m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY) ) ) + { +- CLog::Log(LOGINFO, "COMXPlayer::OpenInputStream - DVD/BD not supported"); +- return false; ++ CLog::Log(LOGINFO, "COMXPlayer::OpenInputStream - DVD/BD not supported - Will try..."); ++ // return false; + } + + // find any available external subtitles for non dvd files +-- +1.7.10 + diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-901-PR1467.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-901-PR1467.patch new file mode 100644 index 0000000000..406ec3af31 --- /dev/null +++ b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-a642b33-901-PR1467.patch @@ -0,0 +1,477 @@ +From 7d692ff576d0a713891908b5630ce2b8d0128f2e Mon Sep 17 00:00:00 2001 +From: davilla +Date: Sat, 22 Sep 2012 20:10:33 -0400 +Subject: [PATCH] add the ability to run a split gui/display resolution for + embedded platforms + +--- + xbmc/Application.cpp | 2 +- + xbmc/GUIInfoManager.cpp | 12 +++---- + xbmc/guilib/GraphicContext.cpp | 2 ++ + xbmc/guilib/Resolution.h | 5 +++ + xbmc/settings/GUISettings.cpp | 6 ++-- + xbmc/settings/GUIWindowSettingsCategory.cpp | 10 +++--- + .../GUIWindowSettingsScreenCalibration.cpp | 8 ++--- + xbmc/video/windows/GUIWindowFullScreen.cpp | 8 ++--- + xbmc/windowing/WinSystem.cpp | 14 ++++++--- + xbmc/windowing/X11/WinSystemX11.cpp | 2 ++ + xbmc/windowing/X11/WinSystemX11GLES.cpp | 2 ++ + xbmc/windowing/egl/WinEGLPlatformGeneric.cpp | 11 +++---- + xbmc/windowing/egl/WinEGLPlatformRaspberryPI.cpp | 10 +++--- + xbmc/windowing/egl/WinSystemGLES.cpp | 33 +++++++++++++------- + xbmc/windowing/egl/WinSystemGLES.h | 2 ++ + xbmc/windowing/windows/WinSystemWin32.cpp | 2 ++ + 16 files changed, 80 insertions(+), 49 deletions(-) + +diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp +index 961e8f9..cd9fc9f 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -890,7 +890,7 @@ bool CApplication::CreateGUI() + return false; + + int iResolution = g_graphicsContext.GetVideoResolution(); +- CLog::Log(LOGINFO, "GUI format %ix%i %s", ++ CLog::Log(LOGINFO, "GUI format %ix%i, Display %s", + g_settings.m_ResInfo[iResolution].iWidth, + g_settings.m_ResInfo[iResolution].iHeight, + g_settings.m_ResInfo[iResolution].strMode.c_str()); +diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp +index fb6292d..c4ecd0a 100644 +--- a/xbmc/GUIInfoManager.cpp ++++ b/xbmc/GUIInfoManager.cpp +@@ -1493,14 +1493,14 @@ CStdString CGUIInfoManager::GetLabel(int info, int contextWindow, CStdString *fa + case SYSTEM_SCREEN_RESOLUTION: + if(g_Windowing.IsFullScreen()) + strLabel.Format("%ix%i@%.2fHz - %s (%02.2f fps)", +- g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iWidth, +- g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iHeight, ++ g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iScreenWidth, ++ g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iScreenHeight, + g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].fRefreshRate, + g_localizeStrings.Get(244), GetFPS()); + else + strLabel.Format("%ix%i - %s (%02.2f fps)", +- g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iWidth, +- g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iHeight, ++ g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iScreenWidth, ++ g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iScreenHeight, + g_localizeStrings.Get(242), GetFPS()); + return strLabel; + break; +@@ -1620,10 +1620,10 @@ CStdString CGUIInfoManager::GetLabel(int info, int contextWindow, CStdString *fa + strLabel = g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()].strMode; + break; + case SYSTEM_SCREEN_WIDTH: +- strLabel.Format("%i", g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()].iWidth); ++ strLabel.Format("%i", g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()].iScreenWidth); + break; + case SYSTEM_SCREEN_HEIGHT: +- strLabel.Format("%i", g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()].iHeight); ++ strLabel.Format("%i", g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()].iScreenHeight); + break; + case SYSTEM_CURRENT_WINDOW: + return g_localizeStrings.Get(g_windowManager.GetFocusedWindow()); +diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp +index 31bfdbf..94f248b 100644 +--- a/xbmc/guilib/GraphicContext.cpp ++++ b/xbmc/guilib/GraphicContext.cpp +@@ -580,6 +580,8 @@ void CGraphicContext::ResetScreenParameters(RESOLUTION res) + default: + break; + } ++ g_settings.m_ResInfo[res].iScreenWidth = g_settings.m_ResInfo[res].iWidth; ++ g_settings.m_ResInfo[res].iScreenHeight = g_settings.m_ResInfo[res].iHeight; + ResetOverscan(res, g_settings.m_ResInfo[res].Overscan); + } + +diff --git a/xbmc/guilib/Resolution.h b/xbmc/guilib/Resolution.h +index ede938d..20864e2 100644 +--- a/xbmc/guilib/Resolution.h ++++ b/xbmc/guilib/Resolution.h +@@ -88,6 +88,8 @@ struct RESOLUTION_INFO + int iScreen; + int iWidth; + int iHeight; ++ int iScreenWidth; ++ int iScreenHeight; + int iSubtitles; + uint32_t dwFlags; + float fPixelRatio; +@@ -100,6 +102,8 @@ struct RESOLUTION_INFO + { + iWidth = width; + iHeight = height; ++ iScreenWidth = width; ++ iScreenHeight = height; + fPixelRatio = aspect ? ((float)width)/height / aspect : 1.0f; + strMode = mode; + bFullScreen = true; +@@ -114,6 +118,7 @@ struct RESOLUTION_INFO + { + Overscan = res.Overscan; bFullScreen = res.bFullScreen; + iScreen = res.iScreen; iWidth = res.iWidth; iHeight = res.iHeight; ++ iScreenWidth = res.iScreenWidth; iScreenHeight = res.iScreenHeight; + iSubtitles = res.iSubtitles; dwFlags = res.dwFlags; + fPixelRatio = res.fPixelRatio; fRefreshRate = res.fRefreshRate; + strMode = res.strMode; strOutput = res.strOutput; strId = res.strId; +diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp +index da2a78b..ec24ad5 100644 +--- a/xbmc/settings/GUISettings.cpp ++++ b/xbmc/settings/GUISettings.cpp +@@ -1526,8 +1526,8 @@ RESOLUTION CGUISettings::GetResFromString(const CStdString &res) + const RESOLUTION_INFO &info = g_settings.m_ResInfo[i]; + if (info.iScreen != screen) + continue; +- float score = 10 * (square_error((float)info.iWidth, (float)width) + +- square_error((float)info.iHeight, (float)height) + ++ float score = 10 * (square_error((float)info.iScreenWidth, (float)width) + ++ square_error((float)info.iScreenHeight, (float)height) + + square_error(info.fRefreshRate, refresh) + + square_error((float)((info.dwFlags & D3DPRESENTFLAG_INTERLACED) ? 100:200), interlaced)); + if (score < bestScore) +@@ -1552,7 +1552,7 @@ void CGUISettings::SetResolution(RESOLUTION res) + { + const RESOLUTION_INFO &info = g_settings.m_ResInfo[res]; + mode.Format("%1i%05i%05i%09.5f%s", info.iScreen, +- info.iWidth, info.iHeight, info.fRefreshRate, ++ info.iScreenWidth, info.iScreenHeight, info.fRefreshRate, + (info.dwFlags & D3DPRESENTFLAG_INTERLACED) ? "i":"p"); + } + else +diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp +index b436b98..ce517bb 100644 +--- a/xbmc/settings/GUIWindowSettingsCategory.cpp ++++ b/xbmc/settings/GUIWindowSettingsCategory.cpp +@@ -2392,8 +2392,8 @@ void CGUIWindowSettingsCategory::FillInResolutions(CStdString strSetting, Displa + RESOLUTION_INFO res1 = g_settings.m_ResInfo[res]; + RESOLUTION_INFO res2 = g_settings.m_ResInfo[resolutions[idx].ResInfo_Index]; + if ( res1.iScreen == res2.iScreen +- && res1.iWidth == res2.iWidth +- && res1.iHeight == res2.iHeight ++ && res1.iScreenWidth == res2.iScreenWidth ++ && res1.iScreenHeight == res2.iScreenHeight + && (res1.dwFlags & D3DPRESENTFLAG_INTERLACED) == (res2.dwFlags & D3DPRESENTFLAG_INTERLACED)) + spinres = (RESOLUTION) resolutions[idx].ResInfo_Index; + } +@@ -2430,13 +2430,13 @@ void CGUIWindowSettingsCategory::FillInResolutions(CStdString strSetting, Displa + + void CGUIWindowSettingsCategory::FillInRefreshRates(CStdString strSetting, RESOLUTION res, bool UserChange) + { +- // The only meaningful parts of res here are iScreen, iWidth, iHeight ++ // The only meaningful parts of res here are iScreen, iScreenWidth, iScreenHeight + + vector refreshrates; + if (res > RES_WINDOW) + refreshrates = g_Windowing.RefreshRates(g_settings.m_ResInfo[res].iScreen, +- g_settings.m_ResInfo[res].iWidth, +- g_settings.m_ResInfo[res].iHeight, ++ g_settings.m_ResInfo[res].iScreenWidth, ++ g_settings.m_ResInfo[res].iScreenHeight, + g_settings.m_ResInfo[res].dwFlags); + + // The control setting doesn't exist when not in standalone mode, don't manipulate it +diff --git a/xbmc/settings/GUIWindowSettingsScreenCalibration.cpp b/xbmc/settings/GUIWindowSettingsScreenCalibration.cpp +index b2430bc..3e6ba83 100644 +--- a/xbmc/settings/GUIWindowSettingsScreenCalibration.cpp ++++ b/xbmc/settings/GUIWindowSettingsScreenCalibration.cpp +@@ -352,12 +352,12 @@ void CGUIWindowSettingsScreenCalibration::UpdateFromControl(int iControl) + // set the label control correctly + CStdString strText; + if (g_Windowing.IsFullScreen()) +- strText.Format("%ix%i@%.2f - %s | %s", g_settings.m_ResInfo[m_Res[m_iCurRes]].iWidth, +- g_settings.m_ResInfo[m_Res[m_iCurRes]].iHeight, g_settings.m_ResInfo[m_Res[m_iCurRes]].fRefreshRate, ++ strText.Format("%ix%i@%.2f - %s | %s", g_settings.m_ResInfo[m_Res[m_iCurRes]].iScreenWidth, ++ g_settings.m_ResInfo[m_Res[m_iCurRes]].iScreenHeight, g_settings.m_ResInfo[m_Res[m_iCurRes]].fRefreshRate, + g_localizeStrings.Get(244).c_str(), strStatus.c_str()); + else +- strText.Format("%ix%i - %s | %s", g_settings.m_ResInfo[m_Res[m_iCurRes]].iWidth, +- g_settings.m_ResInfo[m_Res[m_iCurRes]].iHeight, ++ strText.Format("%ix%i - %s | %s", g_settings.m_ResInfo[m_Res[m_iCurRes]].iScreenWidth, ++ g_settings.m_ResInfo[m_Res[m_iCurRes]].iScreenHeight, + g_localizeStrings.Get(242).c_str(), strStatus.c_str()); + + SET_CONTROL_LABEL(CONTROL_LABEL_ROW1, strText); +diff --git a/xbmc/video/windows/GUIWindowFullScreen.cpp b/xbmc/video/windows/GUIWindowFullScreen.cpp +index 22a5c35..1bba604 100644 +--- a/xbmc/video/windows/GUIWindowFullScreen.cpp ++++ b/xbmc/video/windows/GUIWindowFullScreen.cpp +@@ -1008,13 +1008,13 @@ void CGUIWindowFullScreen::FrameMove() + CStdString strStatus; + if (g_Windowing.IsFullScreen()) + strStatus.Format("%s %ix%i@%.2fHz - %s", +- g_localizeStrings.Get(13287), g_settings.m_ResInfo[iResolution].iWidth, +- g_settings.m_ResInfo[iResolution].iHeight, g_settings.m_ResInfo[iResolution].fRefreshRate, ++ g_localizeStrings.Get(13287), g_settings.m_ResInfo[iResolution].iScreenWidth, ++ g_settings.m_ResInfo[iResolution].iScreenHeight, g_settings.m_ResInfo[iResolution].fRefreshRate, + g_localizeStrings.Get(244)); + else + strStatus.Format("%s %ix%i - %s", +- g_localizeStrings.Get(13287), g_settings.m_ResInfo[iResolution].iWidth, +- g_settings.m_ResInfo[iResolution].iHeight, g_localizeStrings.Get(242)); ++ g_localizeStrings.Get(13287), g_settings.m_ResInfo[iResolution].iScreenWidth, ++ g_settings.m_ResInfo[iResolution].iScreenHeight, g_localizeStrings.Get(242)); + + CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW3); + msg.SetLabel(strStatus); +diff --git a/xbmc/windowing/WinSystem.cpp b/xbmc/windowing/WinSystem.cpp +index 9882161..6a17586 100644 +--- a/xbmc/windowing/WinSystem.cpp ++++ b/xbmc/windowing/WinSystem.cpp +@@ -63,6 +63,8 @@ void CWinSystemBase::UpdateDesktopResolution(RESOLUTION_INFO& newRes, int screen + newRes.fPixelRatio = 1.0f; + newRes.iWidth = width; + newRes.iHeight = height; ++ newRes.iScreenWidth = width; ++ newRes.iScreenHeight = height; + newRes.strMode.Format("%dx%d", width, height); + if (refreshRate > 1) + newRes.strMode.Format("%s @ %.2f%s - Full Screen", newRes.strMode, refreshRate, dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : ""); +@@ -79,6 +81,8 @@ void CWinSystemBase::UpdateResolutions() + window.iWidth = 720; + if (window.iHeight == 0) + window.iHeight = 480; ++ window.iScreenWidth = window.iWidth; ++ window.iScreenHeight = window.iHeight; + if (window.iSubtitles == 0) + window.iSubtitles = (int)(0.965 * window.iHeight); + window.fPixelRatio = 1.0f; +@@ -90,6 +94,8 @@ void CWinSystemBase::SetWindowResolution(int width, int height) + RESOLUTION_INFO& window = g_settings.m_ResInfo[RES_WINDOW]; + window.iWidth = width; + window.iHeight = height; ++ window.iScreenWidth = width; ++ window.iScreenHeight = height; + window.iSubtitles = (int)(0.965 * window.iHeight); + g_graphicsContext.ResetOverscan(window); + } +@@ -105,8 +111,8 @@ int CWinSystemBase::DesktopResolution(int screen) + + static void AddResolution(vector &resolutions, unsigned int addindex) + { +- int width = g_settings.m_ResInfo[addindex].iWidth; +- int height = g_settings.m_ResInfo[addindex].iHeight; ++ int width = g_settings.m_ResInfo[addindex].iScreenWidth; ++ int height = g_settings.m_ResInfo[addindex].iScreenHeight; + int interlaced = g_settings.m_ResInfo[addindex].dwFlags & D3DPRESENTFLAG_INTERLACED; + + for (unsigned int idx = 0; idx < resolutions.size(); idx++) +@@ -163,8 +169,8 @@ static bool rrSortPredicate(REFRESHRATE i, REFRESHRATE j) + + for (unsigned int idx = RES_DESKTOP; idx < g_settings.m_ResInfo.size(); idx++) + if ( g_settings.m_ResInfo[idx].iScreen == screen +- && g_settings.m_ResInfo[idx].iWidth == width +- && g_settings.m_ResInfo[idx].iHeight == height ++ && g_settings.m_ResInfo[idx].iScreenWidth == width ++ && g_settings.m_ResInfo[idx].iScreenHeight == height + && (g_settings.m_ResInfo[idx].dwFlags & D3DPRESENTFLAG_INTERLACED) == (dwFlags & D3DPRESENTFLAG_INTERLACED)) + AddRefreshRate(refreshrates, idx); + +diff --git a/xbmc/windowing/X11/WinSystemX11.cpp b/xbmc/windowing/X11/WinSystemX11.cpp +index 889c445..a839709 100644 +--- a/xbmc/windowing/X11/WinSystemX11.cpp ++++ b/xbmc/windowing/X11/WinSystemX11.cpp +@@ -269,6 +269,8 @@ void CWinSystemX11::UpdateResolutions() + RESOLUTION_INFO res; + res.iWidth = mode.w; + res.iHeight = mode.h; ++ res.iScreenWidth = mode.w; ++ res.iScreenHeight = mode.h; + if (mode.h>0 && mode.w>0 && out.hmm>0 && out.wmm>0) + res.fPixelRatio = ((float)out.wmm/(float)mode.w) / (((float)out.hmm/(float)mode.h)); + else +diff --git a/xbmc/windowing/X11/WinSystemX11GLES.cpp b/xbmc/windowing/X11/WinSystemX11GLES.cpp +index 2b67e37..50185f9 100644 +--- a/xbmc/windowing/X11/WinSystemX11GLES.cpp ++++ b/xbmc/windowing/X11/WinSystemX11GLES.cpp +@@ -292,6 +292,8 @@ void CWinSystemX11GLES::UpdateResolutions() + RESOLUTION_INFO res; + res.iWidth = mode.w; + res.iHeight = mode.h; ++ res.iScreenWidth = mode.w; ++ res.iScreenHeight = mode.h; + if (mode.h>0 && mode.w>0 && out.hmm>0 && out.wmm>0) + res.fPixelRatio = ((float)out.wmm/(float)mode.w) / (((float)out.hmm/(float)mode.h)); + else +diff --git a/xbmc/windowing/egl/WinEGLPlatformGeneric.cpp b/xbmc/windowing/egl/WinEGLPlatformGeneric.cpp +index 9febe15..b6dec7e 100644 +--- a/xbmc/windowing/egl/WinEGLPlatformGeneric.cpp ++++ b/xbmc/windowing/egl/WinEGLPlatformGeneric.cpp +@@ -43,8 +43,8 @@ + m_desktopRes.iScreen = 0; + m_desktopRes.iWidth = 1280; + m_desktopRes.iHeight = 720; +- //m_desktopRes.iScreenWidth = 1280; +- //m_desktopRes.iScreenHeight = 720; ++ m_desktopRes.iScreenWidth = 1280; ++ m_desktopRes.iScreenHeight = 720; + m_desktopRes.fRefreshRate = 60.0f; + m_desktopRes.bFullScreen = true; + m_desktopRes.iSubtitles = (int)(0.965 * 720); +@@ -101,12 +101,9 @@ bool CWinEGLPlatformGeneric::ProbeDisplayResolutions(std::vector 1) + { +@@ -687,8 +689,8 @@ void CWinEGLPlatformRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std:: + res.fPixelRatio = 1.0f; + res.iWidth = width; + res.iHeight = tv->height; +- //res.iScreenWidth = width; +- //res.iScreenHeight = tv->height; ++ res.iScreenWidth = width; ++ res.iScreenHeight = tv->height; + res.strMode.Format("%dx%d", width, tv->height); + if((float)tv->frame_rate > 1) + { +diff --git a/xbmc/windowing/egl/WinSystemGLES.cpp b/xbmc/windowing/egl/WinSystemGLES.cpp +index d4f1f04..eb78f74 100644 +--- a/xbmc/windowing/egl/WinSystemGLES.cpp ++++ b/xbmc/windowing/egl/WinSystemGLES.cpp +@@ -78,7 +78,11 @@ bool CWinSystemGLES::DestroyWindowSystem() + + bool CWinSystemGLES::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction) + { +- if (m_bWindowCreated && m_nWidth == res.iWidth && m_nHeight == res.iHeight && m_fRefreshRate == res.fRefreshRate && m_bFullScreen == fullScreen) ++ if (m_bWindowCreated && ++ m_nWidth == res.iWidth && m_nHeight == res.iHeight && ++ m_nScreenWidth == res.iScreenWidth && m_nScreenHeight == res.iScreenHeight && ++ m_bFullScreen == fullScreen && ++ m_fRefreshRate == res.fRefreshRate) + { + CLog::Log(LOGDEBUG, "CWinSystemGLES::CreateNewWindow: No need to create a new window"); + return true; +@@ -86,8 +90,10 @@ bool CWinSystemGLES::CreateNewWindow(const CStdString& name, bool fullScreen, RE + + m_nWidth = res.iWidth; + m_nHeight = res.iHeight; +- m_bFullScreen = fullScreen; +- m_fRefreshRate = res.fRefreshRate; ++ m_nScreenWidth = res.iScreenWidth; ++ m_nScreenHeight = res.iScreenHeight; ++ m_bFullScreen = fullScreen; ++ m_fRefreshRate = res.fRefreshRate; + + // Destroy any existing window + if (m_bWindowCreated) +@@ -138,7 +144,6 @@ void CWinSystemGLES::UpdateResolutions() + { + CWinSystemBase::UpdateResolutions(); + +- //std::vector resolutions; + std::vector resolutions; + + m_eglplatform->ProbeDisplayResolutions(resolutions); +@@ -148,9 +153,6 @@ void CWinSystemGLES::UpdateResolutions() + RESOLUTION ResDesktop = RES_INVALID; + RESOLUTION res_index = RES_DESKTOP; + +- // Clear old resolutions +- //g_settings.m_ResInfo.clear(); +- + for (size_t i = 0; i < resolutions.size(); i++) + { + int gui_width = resolutions[i].iWidth; +@@ -173,17 +175,23 @@ void CWinSystemGLES::UpdateResolutions() + g_graphicsContext.ResetOverscan(resolutions[i]); + g_settings.m_ResInfo[res_index] = resolutions[i]; + +- CLog::Log(LOGNOTICE, "Found resolution for display %d with %d x %d @ %f Hz\n", ++ CLog::Log(LOGNOTICE, "Found resolution %d x %d for display %d with %d x %d%s @ %f Hz\n", + resolutions[i].iScreen, + resolutions[i].iWidth, + resolutions[i].iHeight, ++ resolutions[i].iScreenWidth, ++ resolutions[i].iScreenHeight, ++ resolutions[i].dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "", + resolutions[i].fRefreshRate); + + if(m_eglplatform->FixedDesktop()) + { + if(resDesktop.iWidth == resolutions[i].iWidth && + resDesktop.iHeight == resolutions[i].iHeight && +- resDesktop.fRefreshRate == resolutions[i].fRefreshRate) ++ resDesktop.iScreenWidth == resolutions[i].iScreenWidth && ++ resDesktop.iScreenHeight == resolutions[i].iScreenHeight && ++ resDesktop.fRefreshRate == resolutions[i].fRefreshRate && ++ resDesktop.dwFlags == resolutions[i].dwFlags) + { + ResDesktop = res_index; + } +@@ -195,8 +203,11 @@ void CWinSystemGLES::UpdateResolutions() + // swap desktop index for desktop res if available + if (ResDesktop != RES_INVALID) + { +- CLog::Log(LOGNOTICE, "Found (%dx%d@%f) at %d, setting to RES_DESKTOP at %d", +- resDesktop.iWidth, resDesktop.iHeight, resDesktop.fRefreshRate, (int)ResDesktop, (int)RES_DESKTOP); ++ CLog::Log(LOGNOTICE, "Found (%dx%d%s@%f) at %d, setting to RES_DESKTOP at %d", ++ resDesktop.iWidth, resDesktop.iHeight, ++ resDesktop.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "", ++ resDesktop.fRefreshRate, ++ (int)ResDesktop, (int)RES_DESKTOP); + + RESOLUTION_INFO desktop = g_settings.m_ResInfo[RES_DESKTOP]; + g_settings.m_ResInfo[RES_DESKTOP] = g_settings.m_ResInfo[ResDesktop]; +diff --git a/xbmc/windowing/egl/WinSystemGLES.h b/xbmc/windowing/egl/WinSystemGLES.h +index d94d24d..72c1eb7 100644 +--- a/xbmc/windowing/egl/WinSystemGLES.h ++++ b/xbmc/windowing/egl/WinSystemGLES.h +@@ -63,6 +63,8 @@ class CWinSystemGLES : public CWinSystemBase, public CRenderSystemGLES + void *m_display; + EGLNativeWindowType m_window; + CWinEGLPlatform *m_eglplatform; ++ int m_nScreenWidth; ++ int m_nScreenHeight; + }; + + XBMC_GLOBAL_REF(CWinSystemGLES,g_Windowing); +diff --git a/xbmc/windowing/windows/WinSystemWin32.cpp b/xbmc/windowing/windows/WinSystemWin32.cpp +index 6a0e335..182b9a2 100644 +--- a/xbmc/windowing/windows/WinSystemWin32.cpp ++++ b/xbmc/windowing/windows/WinSystemWin32.cpp +@@ -541,6 +541,8 @@ void CWinSystemWin32::AddResolution(const RESOLUTION_INFO &res) + if (g_settings.m_ResInfo[i].iScreen == res.iScreen && + g_settings.m_ResInfo[i].iWidth == res.iWidth && + g_settings.m_ResInfo[i].iHeight == res.iHeight && ++ g_settings.m_ResInfo[i].iScreenWidth == res.iScreenWidth && ++ g_settings.m_ResInfo[i].iScreenHeight== res.iScreenHeight && + g_settings.m_ResInfo[i].fRefreshRate == res.fRefreshRate && + g_settings.m_ResInfo[i].dwFlags == res.dwFlags) + return; // already have this resolution +-- +1.7.10 + diff --git a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-901-CEC_add_2548-1002.patch b/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-901-CEC_add_2548-1002.patch deleted file mode 100644 index ac124df53f..0000000000 --- a/packages/mediacenter/xbmc-frodo/patches/xbmc-frodo-ba2c709-901-CEC_add_2548-1002.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 35c9bf5bd0f9d03541280df8d7b9af0bf6ffb1a4 Mon Sep 17 00:00:00 2001 -From: Lars Op den Kamp -Date: Wed, 29 Aug 2012 13:43:55 +0200 -Subject: [PATCH] cec: also match 2548:1002 to the cec adapter - ---- - system/peripherals.xml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/system/peripherals.xml b/system/peripherals.xml -index cf0c6c4..76a1df9 100644 ---- a/system/peripherals.xml -+++ b/system/peripherals.xml -@@ -9,7 +9,7 @@ - - - -- -+ - - - --- -1.7.10 - diff --git a/packages/mediacenter/xbmc/init.d/93_xbmc b/packages/mediacenter/xbmc/init.d/93_xbmc index d33fb5ff40..164310c603 100644 --- a/packages/mediacenter/xbmc/init.d/93_xbmc +++ b/packages/mediacenter/xbmc/init.d/93_xbmc @@ -54,8 +54,8 @@ fi # set cpu's to 'conservative' ( usleep 15000000 - progress "set cpu's to 'conservative'" - cpupower frequency-set -g conservative > /dev/null 2>&1 + progress "set cpu's to 'ondemand'" + cpupower frequency-set -g ondemand > /dev/null 2>&1 )& # prevent restrating XBMC at reboot or shutdown diff --git a/packages/mediacenter/xbmc/patches/xbmc-11.0.2-902.22-videoplayer_fix_calcDropRequirement_for_forced_deinterlacing.patch b/packages/mediacenter/xbmc/patches/xbmc-11.0.2-902.22-videoplayer_fix_calcDropRequirement_for_forced_deinterlacing.patch new file mode 100644 index 0000000000..01043f4e81 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-11.0.2-902.22-videoplayer_fix_calcDropRequirement_for_forced_deinterlacing.patch @@ -0,0 +1,26 @@ +From 66a8245d4e7d02469f03c6a1b3e295dde346645f Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sat, 15 Sep 2012 17:24:30 +0200 +Subject: [PATCH] videoplayer: fix calcDropRequirement for forced + deinterlacing + +--- + xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +index db0fb1f..81e0012 100644 +--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp ++++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +@@ -1702,7 +1702,7 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts) + + bNewFrame = iDecoderPts != m_droppingStats.m_lastDecoderPts; + +- if (interlaced) ++ if (interlaced || iSkippedDeint) + iInterval = 2/m_fFrameRate*(double)DVD_TIME_BASE; + else + iInterval = 1/m_fFrameRate*(double)DVD_TIME_BASE; +-- +1.7.10 + diff --git a/packages/mediacenter/xbmc/patches/xbmc-11.0.2-902.23-vdpau_fix_AutoInterlaceMethod_to_prevent_from_double_de-interlacing.patch b/packages/mediacenter/xbmc/patches/xbmc-11.0.2-902.23-vdpau_fix_AutoInterlaceMethod_to_prevent_from_double_de-interlacing.patch new file mode 100644 index 0000000000..620eb0a651 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-11.0.2-902.23-vdpau_fix_AutoInterlaceMethod_to_prevent_from_double_de-interlacing.patch @@ -0,0 +1,32 @@ +From f0bf2b7dff16ac6ee875770b390accf71660a662 Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 16 Sep 2012 08:27:06 +0200 +Subject: [PATCH] vdpau: fix AutoInterlaceMethod to prevent from double + de-interlacing + +--- + xbmc/cores/VideoRenderers/LinuxRendererGL.cpp | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +index f25252c..374d75d 100644 +--- a/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp ++++ b/xbmc/cores/VideoRenderers/LinuxRendererGL.cpp +@@ -3743,14 +3743,7 @@ EINTERLACEMETHOD CLinuxRendererGL::AutoInterlaceMethod() + return VS_INTERLACEMETHOD_NONE; + + if(m_renderMethod & RENDER_VDPAU) +- { +-#ifdef HAVE_LIBVDPAU +- VDPAU::CVdpauRenderPicture *vdpauPic = m_buffers[m_iYV12RenderBuffer].vdpau; +- if(vdpauPic && vdpauPic->vdpau) +- return vdpauPic->vdpau->AutoInterlaceMethod(); +-#endif + return VS_INTERLACEMETHOD_NONE; +- } + + if(Supports(VS_INTERLACEMETHOD_RENDER_BOB)) + return VS_INTERLACEMETHOD_RENDER_BOB; +-- +1.7.10 + diff --git a/packages/mediacenter/xbmc/patches/xbmc-11.0.2-902.24-xvba_oopsie.patch b/packages/mediacenter/xbmc/patches/xbmc-11.0.2-902.24-xvba_oopsie.patch new file mode 100644 index 0000000000..9139fd4ddc --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-11.0.2-902.24-xvba_oopsie.patch @@ -0,0 +1,25 @@ +From a7d40418f3aaf35f5df1de8987ce14afd59fb04f Mon Sep 17 00:00:00 2001 +From: xbmc +Date: Sun, 16 Sep 2012 12:19:27 +0200 +Subject: [PATCH] xvba: oopsie :) + +--- + xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp +index d4cf6cf..bd7cc3d 100644 +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp ++++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/XVBA.cpp +@@ -768,6 +768,7 @@ void CDecoder::DestroySession() + XVBA_Destroy_Decode_Buffers_Input bufInput; + bufInput.size = sizeof(bufInput); + bufInput.num_of_buffers_in_list = 1; ++ bufInput.session = m_xvbaConfig.xvbaSession; + + for (unsigned int i=0; i +Date: Sun, 16 Sep 2012 18:38:01 +0200 +Subject: [PATCH] vdpau: fix upscaling setting + +--- + xbmc/settings/AdvancedSettings.cpp | 4 ++-- + xbmc/settings/AdvancedSettings.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp +index 61ccf85..3556b7d 100644 +--- a/xbmc/settings/AdvancedSettings.cpp ++++ b/xbmc/settings/AdvancedSettings.cpp +@@ -98,7 +98,7 @@ void CAdvancedSettings::Initialize() + m_videoIgnoreSecondsAtStart = 3*60; + m_videoIgnorePercentAtEnd = 8.0f; + m_videoPlayCountMinimumPercent = 90.0f; +- m_videoVDPAUScaling = false; ++ m_videoVDPAUScaling = -1; + m_videoNonLinStretchRatio = 0.5f; + m_videoEnableHighQualityHwScalers = false; + m_videoAutoScaleMaxFps = 30.0f; +@@ -492,7 +492,7 @@ void CAdvancedSettings::ParseSettingsFile(const CStdString &file) + XMLUtils::GetString(pElement,"cleandatetime", m_videoCleanDateTimeRegExp); + XMLUtils::GetString(pElement,"ppffmpegdeinterlacing",m_videoPPFFmpegDeint); + XMLUtils::GetString(pElement,"ppffmpegpostprocessing",m_videoPPFFmpegPostProc); +- XMLUtils::GetBoolean(pElement,"vdpauscaling",m_videoVDPAUScaling); ++ XMLUtils::GetInt(pElement,"vdpauscaling",m_videoVDPAUScaling); + XMLUtils::GetFloat(pElement, "nonlinearstretchratio", m_videoNonLinStretchRatio, 0.01f, 1.0f); + XMLUtils::GetBoolean(pElement,"enablehighqualityhwscalers", m_videoEnableHighQualityHwScalers); + XMLUtils::GetFloat(pElement,"autoscalemaxfps",m_videoAutoScaleMaxFps, 0.0f, 1000.0f); +diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h +index b3a54ff..f50151a 100644 +--- a/xbmc/settings/AdvancedSettings.h ++++ b/xbmc/settings/AdvancedSettings.h +@@ -152,7 +152,7 @@ class CAdvancedSettings + CStdString m_audioHost; + bool m_audioApplyDrc; + +- bool m_videoVDPAUScaling; ++ int m_videoVDPAUScaling; + float m_videoNonLinStretchRatio; + bool m_videoEnableHighQualityHwScalers; + float m_videoAutoScaleMaxFps; +-- +1.7.10 + diff --git a/packages/multimedia/ffmpeg/build b/packages/multimedia/ffmpeg/build index 96a368d7d2..27022bd66e 100755 --- a/packages/multimedia/ffmpeg/build +++ b/packages/multimedia/ffmpeg/build @@ -61,17 +61,17 @@ fi case "$TARGET_ARCH" in arm) - FFMPEG_CPU="--enable-armv5te --disable-armv6t2 --enable-armv6" + FFMPEG_CPU="" FFMPEG_TABLES="--enable-hardcoded-tables" FFMPEG_PIC="--enable-pic" ;; i?86) - FFMPEG_CPU="--disable-armv5te --disable-armv6t2 --disable-armv6" + FFMPEG_CPU="" FFMPEG_TABLES="--disable-hardcoded-tables" FFMPEG_PIC="--disable-pic" ;; x86_64) - FFMPEG_CPU="--disable-armv5te --disable-armv6t2 --disable-armv6" + FFMPEG_CPU="" FFMPEG_TABLES="--disable-hardcoded-tables" FFMPEG_PIC="--enable-pic" ;; @@ -79,19 +79,19 @@ esac case "$TARGET_FPU" in neon*) - FFMPEG_FPU="--enable-neon --disable-armvfp" + FFMPEG_FPU="--enable-neon" ;; vfp*) - FFMPEG_FPU="--enable-armvfp --disable-neon" + FFMPEG_FPU="" ;; *) - FFMPEG_FPU="--disable-neon --disable-armvfp" + FFMPEG_FPU="" ;; esac export pkg_config="$ROOT/$TOOLCHAIN/bin/pkg-config" -# libav fails building with LTO support +# ffmpeg fails building with LTO support strip_lto #LDFLAGS="$(echo "$LDFLAGS" | sed "s/-Wl,-Bsymbolic-functions//g")" @@ -218,8 +218,5 @@ cd $PKG_BUILD/ --disable-sram \ --disable-symver \ -#sed -i -e "s#define HAVE_SYMVER 1#define HAVE_SYMVER 0#" config.h && -#sed -i -e "s#define HAVE_SYMVER_GNU_ASM 1#define HAVE_SYMVER_GNU_ASM 0#" config.h - make V=1 $MAKEINSTALL diff --git a/packages/multimedia/ffmpeg/meta b/packages/multimedia/ffmpeg/meta index 54368e6df2..1a03c63cfd 100644 --- a/packages/multimedia/ffmpeg/meta +++ b/packages/multimedia/ffmpeg/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="ffmpeg" -PKG_VERSION="0.10.4" +PKG_VERSION="0.10.5" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="LGPL" diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0001-Support-raw-dvdsub-palette-as-stored-on-normal-dvd-s.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0001-Support-raw-dvdsub-palette-as-stored-on-normal-dvd-s.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0001-Support-raw-dvdsub-palette-as-stored-on-normal-dvd-s.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0001-Support-raw-dvdsub-palette-as-stored-on-normal-dvd-s.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0002-Change-fallthrough-logic-for-read_seek-to-be-based-o.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0002-Change-fallthrough-logic-for-read_seek-to-be-based-o.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0002-Change-fallthrough-logic-for-read_seek-to-be-based-o.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0002-Change-fallthrough-logic-for-read_seek-to-be-based-o.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0003-matroska-Check-return-value-of-avio_seek-and-avoid-m.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0003-matroska-Check-return-value-of-avio_seek-and-avoid-m.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0003-matroska-Check-return-value-of-avio_seek-and-avoid-m.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0003-matroska-Check-return-value-of-avio_seek-and-avoid-m.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0004-asf-hacks.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0004-asf-hacks.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0004-asf-hacks.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0004-asf-hacks.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0005-if-av_read_packet-returns-AVERROR_IO-we-are-done.-ff.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0005-if-av_read_packet-returns-AVERROR_IO-we-are-done.-ff.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0005-if-av_read_packet-returns-AVERROR_IO-we-are-done.-ff.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0005-if-av_read_packet-returns-AVERROR_IO-we-are-done.-ff.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0006-added-Ticket-7187-TV-Teletext-support-for-DVB-EBU-Te.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0006-added-Ticket-7187-TV-Teletext-support-for-DVB-EBU-Te.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0006-added-Ticket-7187-TV-Teletext-support-for-DVB-EBU-Te.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0006-added-Ticket-7187-TV-Teletext-support-for-DVB-EBU-Te.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0007-Don-t-accept-mpegts-PMT-that-isn-t-current.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0007-Don-t-accept-mpegts-PMT-that-isn-t-current.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0007-Don-t-accept-mpegts-PMT-that-isn-t-current.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0007-Don-t-accept-mpegts-PMT-that-isn-t-current.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0008-Don-t-reparse-PMT-unless-it-s-version-has-changed.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0008-Don-t-reparse-PMT-unless-it-s-version-has-changed.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0008-Don-t-reparse-PMT-unless-it-s-version-has-changed.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0008-Don-t-reparse-PMT-unless-it-s-version-has-changed.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0009-fixed-compile-with-VDPAU-header-versions-without-MPE.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0009-fixed-compile-with-VDPAU-header-versions-without-MPE.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0009-fixed-compile-with-VDPAU-header-versions-without-MPE.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0009-fixed-compile-with-VDPAU-header-versions-without-MPE.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0010-Read-PID-timestamps-as-well-as-PCR-timestamps-to-fin.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0010-Read-PID-timestamps-as-well-as-PCR-timestamps-to-fin.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0010-Read-PID-timestamps-as-well-as-PCR-timestamps-to-fin.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0010-Read-PID-timestamps-as-well-as-PCR-timestamps-to-fin.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0011-Get-stream-durations-using-read_timestamp.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0011-Get-stream-durations-using-read_timestamp.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0011-Get-stream-durations-using-read_timestamp.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0011-Get-stream-durations-using-read_timestamp.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0012-include-stdint.h.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0012-include-stdint.h.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0012-include-stdint.h.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0012-include-stdint.h.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0013-aacenc-add-recognized-profiles-array.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0013-aacenc-add-recognized-profiles-array.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0013-aacenc-add-recognized-profiles-array.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0013-aacenc-add-recognized-profiles-array.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0014-changed-allow-8-second-skew-between-streams-in-mov-b.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0014-changed-allow-8-second-skew-between-streams-in-mov-b.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0014-changed-allow-8-second-skew-between-streams-in-mov-b.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0014-changed-allow-8-second-skew-between-streams-in-mov-b.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0015-fixed-memleak-in-mpegts-demuxer-on-some-malformed-mp.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0015-fixed-memleak-in-mpegts-demuxer-on-some-malformed-mp.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0015-fixed-memleak-in-mpegts-demuxer-on-some-malformed-mp.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0015-fixed-memleak-in-mpegts-demuxer-on-some-malformed-mp.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0016-Speed-up-mpegts-av_find_stream_info.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0016-Speed-up-mpegts-av_find_stream_info.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0016-Speed-up-mpegts-av_find_stream_info.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0016-Speed-up-mpegts-av_find_stream_info.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0017-allow-customizing-shared-library-soname-name-with-ma.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0017-allow-customizing-shared-library-soname-name-with-ma.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0017-allow-customizing-shared-library-soname-name-with-ma.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0017-allow-customizing-shared-library-soname-name-with-ma.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0018-dxva-mpeg2-Allocate-slices-array-dynamically-fixes-v.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0018-dxva-mpeg2-Allocate-slices-array-dynamically-fixes-v.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0018-dxva-mpeg2-Allocate-slices-array-dynamically-fixes-v.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0018-dxva-mpeg2-Allocate-slices-array-dynamically-fixes-v.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0019-dxva-mpeg2-speed-up-slice-allocation.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0019-dxva-mpeg2-speed-up-slice-allocation.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0019-dxva-mpeg2-speed-up-slice-allocation.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0019-dxva-mpeg2-speed-up-slice-allocation.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0020-dxva-vc1-Take-BI-into-account-for-forward-and-backwa.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0020-dxva-vc1-Take-BI-into-account-for-forward-and-backwa.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0020-dxva-vc1-Take-BI-into-account-for-forward-and-backwa.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0020-dxva-vc1-Take-BI-into-account-for-forward-and-backwa.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0021-dxva-vc1-Pass-overlapping-transforms-hint.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0021-dxva-vc1-Pass-overlapping-transforms-hint.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0021-dxva-vc1-Pass-overlapping-transforms-hint.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0021-dxva-vc1-Pass-overlapping-transforms-hint.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0022-dxva-h264-Fix-dxva-playback-of-streams-that-don-t-st.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0022-dxva-h264-Fix-dxva-playback-of-streams-that-don-t-st.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0022-dxva-h264-Fix-dxva-playback-of-streams-that-don-t-st.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0022-dxva-h264-Fix-dxva-playback-of-streams-that-don-t-st.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0023-Changed-format-string-td-not-supported-by-our-MingW-.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0023-Changed-format-string-td-not-supported-by-our-MingW-.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0023-Changed-format-string-td-not-supported-by-our-MingW-.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0023-Changed-format-string-td-not-supported-by-our-MingW-.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0024-add-public-version-of-ff_read_frame_flush.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0024-add-public-version-of-ff_read_frame_flush.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0024-add-public-version-of-ff_read_frame_flush.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0024-add-public-version-of-ff_read_frame_flush.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0025-dvb-subtitle-decoding-when-display-segment-is-mi.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0025-dvb-subtitle-decoding-when-display-segment-is-mi.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0025-dvb-subtitle-decoding-when-display-segment-is-mi.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0025-dvb-subtitle-decoding-when-display-segment-is-mi.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0026-Handle-return-value-of-BeginFrame-better.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0026-Handle-return-value-of-BeginFrame-better.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0026-Handle-return-value-of-BeginFrame-better.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0026-Handle-return-value-of-BeginFrame-better.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0028-added-support-for-OTF-fonts.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0028-added-support-for-OTF-fonts.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0028-added-support-for-OTF-fonts.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0028-added-support-for-OTF-fonts.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0028-fixed-dvd-still-frames-ended-up-in-internal-lavf.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0028-fixed-dvd-still-frames-ended-up-in-internal-lavf.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0028-fixed-dvd-still-frames-ended-up-in-internal-lavf.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0028-fixed-dvd-still-frames-ended-up-in-internal-lavf.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0029-stop-forcing-gas-preprocessor-for-darwin.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0029-stop-forcing-gas-preprocessor-for-darwin.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0029-stop-forcing-gas-preprocessor-for-darwin.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0029-stop-forcing-gas-preprocessor-for-darwin.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0030-ARM-generate-position-independent-code-to-access-data-symbols.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0030-ARM-generate-position-independent-code-to-access-data-symbols.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0030-ARM-generate-position-independent-code-to-access-data-symbols.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0030-ARM-generate-position-independent-code-to-access-data-symbols.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0031-ARM-vp56-allow-inline-asm-to-build-with-clang.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0031-ARM-vp56-allow-inline-asm-to-build-with-clang.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-0031-ARM-vp56-allow-inline-asm-to-build-with-clang.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-0031-ARM-vp56-allow-inline-asm-to-build-with-clang.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-901.01-add_xvba_support.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-901.01-add_xvba_support.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-901.01-add_xvba_support.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-901.01-add_xvba_support.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-901.02-xvba_adapt_to_new_ffmpeg_fix_artifacts_for_h.264.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-901.02-xvba_adapt_to_new_ffmpeg_fix_artifacts_for_h.264.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-901.02-xvba_adapt_to_new_ffmpeg_fix_artifacts_for_h.264.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-901.02-xvba_adapt_to_new_ffmpeg_fix_artifacts_for_h.264.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-901.03-xvba_xvba_vc-1_new_ffmpeg.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-901.03-xvba_xvba_vc-1_new_ffmpeg.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-901.03-xvba_xvba_vc-1_new_ffmpeg.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-901.03-xvba_xvba_vc-1_new_ffmpeg.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-901.04-xvba_correct_h.264_level_in_case_it_was_encoded_wrongly.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-901.04-xvba_correct_h.264_level_in_case_it_was_encoded_wrongly.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-901.04-xvba_correct_h.264_level_in_case_it_was_encoded_wrongly.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-901.04-xvba_correct_h.264_level_in_case_it_was_encoded_wrongly.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-901.05-xvba_fix_pix_fmt_vda_vld_assert.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-901.05-xvba_fix_pix_fmt_vda_vld_assert.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-901.05-xvba_fix_pix_fmt_vda_vld_assert.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-901.05-xvba_fix_pix_fmt_vda_vld_assert.patch diff --git a/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-911-add-S_DVBSUB-to-list-of-codecs-in-mkv-containers.patch b/packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-911-add-S_DVBSUB-to-list-of-codecs-in-mkv-containers.patch similarity index 100% rename from packages/multimedia/ffmpeg/patches/ffmpeg-0.10.4-911-add-S_DVBSUB-to-list-of-codecs-in-mkv-containers.patch rename to packages/multimedia/ffmpeg/patches/ffmpeg-0.10.5-911-add-S_DVBSUB-to-list-of-codecs-in-mkv-containers.patch diff --git a/packages/multimedia/libvdpau/meta b/packages/multimedia/libvdpau/meta index 6197e5da2f..a9c3707c21 100644 --- a/packages/multimedia/libvdpau/meta +++ b/packages/multimedia/libvdpau/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="libvdpau" -PKG_VERSION="0.4.1" +PKG_VERSION="0.5" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/multimedia/rtmpdump/build b/packages/multimedia/rtmpdump/build index ca31be07eb..6042d21ffe 100755 --- a/packages/multimedia/rtmpdump/build +++ b/packages/multimedia/rtmpdump/build @@ -31,8 +31,10 @@ make prefix=/usr \ CC="$CC" \ LD="$LD" \ AR="$AR" \ - CRYPTO="OPENSSL" \ - XCFLAGS="$CFLAGS $LDFLAGS" + CRYPTO="GNUTLS" \ + OPT="" \ + XCFLAGS="$CFLAGS" \ + XLDFLAGS="$LDFLAGS -lm" $MAKEINSTALL prefix=/usr \ incdir=/usr/include/librtmp \ @@ -41,5 +43,7 @@ $MAKEINSTALL prefix=/usr \ CC="$CC" \ LD="$LD" \ AR="$AR" \ - CRYPTO="OPENSSL" \ - XCFLAGS="$CFLAGS $LDFLAGS" + CRYPTO="GNUTLS" \ + OPT="" \ + XCFLAGS="$CFLAGS" \ + XLDFLAGS="$LDFLAGS -lm" diff --git a/packages/multimedia/rtmpdump/meta b/packages/multimedia/rtmpdump/meta index f9975675e1..b26f7cd7d7 100644 --- a/packages/multimedia/rtmpdump/meta +++ b/packages/multimedia/rtmpdump/meta @@ -19,15 +19,15 @@ ################################################################################ PKG_NAME="rtmpdump" -PKG_VERSION="7340f6d" +PKG_VERSION="e0056c5" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" PKG_SITE="http://rtmpdump.mplayerhq.hu/" #PKG_URL="http://rtmpdump.mplayerhq.hu/download/$PKG_NAME-$PKG_VERSION.tgz" PKG_URL="$DISTRO_SRC/$PKG_NAME-$PKG_VERSION.tar.xz" -PKG_DEPENDS="zlib openssl" -PKG_BUILD_DEPENDS="toolchain zlib openssl" +PKG_DEPENDS="zlib gnutls" +PKG_BUILD_DEPENDS="toolchain zlib gnutls" PKG_PRIORITY="optional" PKG_SECTION="multimedia" PKG_SHORTDESC="rtmpdump: a toolkit for RTMP streams." diff --git a/packages/multimedia/rtmpdump/patches/rtmpdump-e0056c5-60-second-fix.patch b/packages/multimedia/rtmpdump/patches/rtmpdump-e0056c5-60-second-fix.patch new file mode 100644 index 0000000000..2914fc1b8e --- /dev/null +++ b/packages/multimedia/rtmpdump/patches/rtmpdump-e0056c5-60-second-fix.patch @@ -0,0 +1,1913 @@ +diff --git a/librtmp/amf.c b/librtmp/amf.c +index ce84f81..a25bc04 100644 +--- a/librtmp/amf.c ++++ b/librtmp/amf.c +@@ -610,6 +610,9 @@ AMFProp_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize, + return -1; + } + ++ if (*pBuffer == AMF_NULL) ++ bDecodeName = 0; ++ + if (bDecodeName && nSize < 4) + { /* at least name (length + at least 1 byte) and 1 byte of data */ + RTMP_Log(RTMP_LOGDEBUG, +@@ -801,8 +804,8 @@ AMFProp_Dump(AMFObjectProperty *prop) + } + else + { +- name.av_val = "no-name."; +- name.av_len = sizeof("no-name.") - 1; ++ name.av_val = "no-name"; ++ name.av_len = sizeof("no-name") - 1; + } + if (name.av_len > 18) + name.av_len = 18; +diff --git a/librtmp/dh.h b/librtmp/dh.h +index 9959532..e29587b 100644 +--- a/librtmp/dh.h ++++ b/librtmp/dh.h +@@ -61,7 +61,7 @@ static int MDH_generate_key(MDH *dh) + MP_set(&dh->ctx.P, dh->p); + MP_set(&dh->ctx.G, dh->g); + dh->ctx.len = 128; +- dhm_make_public(&dh->ctx, 1024, out, 1, havege_rand, &RTMP_TLS_ctx->hs); ++ dhm_make_public(&dh->ctx, 1024, out, 1, havege_random, &RTMP_TLS_ctx->hs); + MP_new(dh->pub_key); + MP_new(dh->priv_key); + MP_set(dh->pub_key, &dh->ctx.GX); +diff --git a/librtmp/handshake.h b/librtmp/handshake.h +index 0438486..102ba82 100644 +--- a/librtmp/handshake.h ++++ b/librtmp/handshake.h +@@ -965,8 +965,18 @@ HandShake(RTMP * r, int FP9HandShake) + __FUNCTION__); + RTMP_LogHex(RTMP_LOGDEBUG, reply, RTMP_SIG_SIZE); + #endif +- if (!WriteN(r, (char *)reply, RTMP_SIG_SIZE)) +- return FALSE; ++ if (r->Link.CombineConnectPacket) ++ { ++ char *HandshakeResponse = malloc(RTMP_SIG_SIZE); ++ memcpy(HandshakeResponse, (char *) reply, RTMP_SIG_SIZE); ++ r->Link.HandshakeResponse.av_val = HandshakeResponse; ++ r->Link.HandshakeResponse.av_len = RTMP_SIG_SIZE; ++ } ++ else ++ { ++ if (!WriteN(r, (char *) reply, RTMP_SIG_SIZE)) ++ return FALSE; ++ } + + /* 2nd part of handshake */ + if (ReadN(r, (char *)serversig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE) +diff --git a/librtmp/hashswf.c b/librtmp/hashswf.c +index 9f4e2c0..eeed34c 100644 +--- a/librtmp/hashswf.c ++++ b/librtmp/hashswf.c +@@ -70,7 +70,7 @@ extern TLS_CTX RTMP_TLS_ctx; + + #endif /* CRYPTO */ + +-#define AGENT "Mozilla/5.0" ++#define AGENT "Mozilla/5.0 (Windows NT 5.1; rv:8.0) Gecko/20100101 Firefox/8.0" + + HTTPResult + HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb) +@@ -528,7 +528,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash, + + if (strncmp(buf, "url: ", 5)) + continue; +- if (strncmp(buf + 5, url, hlen)) ++ if (strncmp(buf + 5, url, strlen(buf + 5) - 1)) + continue; + r1 = strrchr(buf, '/'); + i = strlen(r1); +diff --git a/librtmp/log.c b/librtmp/log.c +index 0012985..856e3e4 100644 +--- a/librtmp/log.c ++++ b/librtmp/log.c +@@ -52,8 +52,8 @@ static void rtmp_log_default(int level, const char *format, va_list vl) + vsnprintf(str, MAX_PRINT_LEN-1, format, vl); + + /* Filter out 'no-name' */ +- if ( RTMP_debuglevel + #include + #include ++#include + + #include "rtmp_sys.h" + #include "log.h" +@@ -45,6 +46,7 @@ TLS_CTX RTMP_TLS_ctx; + + #define RTMP_SIG_SIZE 1536 + #define RTMP_LARGE_HEADER_SIZE 12 ++#define HEX2BIN(a) (((a)&0x40)?((a)&0xf)+9:((a)&0xf)) + + static const int packetSize[] = { 12, 8, 4, 1 }; + +@@ -97,6 +99,9 @@ static int SendFCSubscribe(RTMP *r, AVal *subscribepath); + static int SendPlay(RTMP *r); + static int SendBytesReceived(RTMP *r); + static int SendUsherToken(RTMP *r, AVal *usherToken); ++static int SendInvoke(RTMP *r, AVal *Command, int queue); ++static int SendGetStreamLength(RTMP *r); ++static int strsplit(char *src, int srclen, char delim, char ***params); + + #if 0 /* unused */ + static int SendBGHasStream(RTMP *r, double dId, AVal *playpath); +@@ -259,6 +264,8 @@ RTMP_Init(RTMP *r) + r->m_fVideoCodecs = 252.0; + r->Link.timeout = 30; + r->Link.swfAge = 30; ++ r->Link.CombineConnectPacket = TRUE; ++ r->Link.ConnectPacket = FALSE; + } + + void +@@ -337,6 +344,7 @@ RTMP_SetupStream(RTMP *r, + AVal *flashVer, + AVal *subscribepath, + AVal *usherToken, ++ AVal *WeebToken, + int dStart, + int dStop, int bLiveStream, long int timeout) + { +@@ -359,6 +367,8 @@ RTMP_SetupStream(RTMP *r, + RTMP_Log(RTMP_LOGDEBUG, "subscribepath : %s", subscribepath->av_val); + if (usherToken && usherToken->av_val) + RTMP_Log(RTMP_LOGDEBUG, "NetStream.Authenticate.UsherToken : %s", usherToken->av_val); ++ if (WeebToken && WeebToken->av_val) ++ RTMP_Log(RTMP_LOGDEBUG, "WeebToken: %s", WeebToken->av_val); + if (flashVer && flashVer->av_val) + RTMP_Log(RTMP_LOGDEBUG, "flashVer : %s", flashVer->av_val); + if (dStart > 0) +@@ -426,6 +436,8 @@ RTMP_SetupStream(RTMP *r, + r->Link.subscribepath = *subscribepath; + if (usherToken && usherToken->av_len) + r->Link.usherToken = *usherToken; ++ if (WeebToken && WeebToken->av_len) ++ r->Link.WeebToken = *WeebToken; + r->Link.seekTime = dStart; + r->Link.stopTime = dStop; + if (bLiveStream) +@@ -483,14 +495,22 @@ static struct urlopt { + "Stream is live, no seeking possible" }, + { AVC("subscribe"), OFF(Link.subscribepath), OPT_STR, 0, + "Stream to subscribe to" }, +- { AVC("jtv"), OFF(Link.usherToken), OPT_STR, 0, +- "Justin.tv authentication token" }, +- { AVC("token"), OFF(Link.token), OPT_STR, 0, ++ { AVC("jtv"), OFF(Link.usherToken), OPT_STR, 0, ++ "Justin.tv authentication token"}, ++ { AVC("weeb"), OFF(Link.WeebToken), OPT_STR, 0, ++ "Weeb.tv authentication token"}, ++ { AVC("token"), OFF(Link.token), OPT_STR, 0, + "Key for SecureToken response" }, + { AVC("swfVfy"), OFF(Link.lFlags), OPT_BOOL, RTMP_LF_SWFV, + "Perform SWF Verification" }, + { AVC("swfAge"), OFF(Link.swfAge), OPT_INT, 0, + "Number of days to use cached SWF hash" }, ++#ifdef CRYPTO ++ { AVC("swfsize"), OFF(Link.swfSize), OPT_INT, 0, ++ "Size of the decompressed SWF file"}, ++ { AVC("swfhash"), OFF(Link.swfHash), OPT_STR, 0, ++ "SHA256 hash of the decompressed SWF file"}, ++#endif + { AVC("start"), OFF(Link.seekTime), OPT_INT, 0, + "Stream start position in milliseconds" }, + { AVC("stop"), OFF(Link.stopTime), OPT_INT, 0, +@@ -751,9 +771,16 @@ int RTMP_SetupURL(RTMP *r, char *url) + } + + #ifdef CRYPTO +- if ((r->Link.lFlags & RTMP_LF_SWFV) && r->Link.swfUrl.av_len) +- RTMP_HashSWF(r->Link.swfUrl.av_val, &r->Link.SWFSize, +- (unsigned char *)r->Link.SWFHash, r->Link.swfAge); ++ RTMP_Log(RTMP_LOGDEBUG, "Khalsa: %d %d %s\n", r->Link.swfSize, r->Link.swfHash.av_len, r->Link.swfHash.av_val); ++ if (r->Link.swfSize && r->Link.swfHash.av_len) ++ { ++ int i, j = 0; ++ for (i = 0; i < r->Link.swfHash.av_len; i += 2) ++ r->Link.SWFHash[j++] = (HEX2BIN(r->Link.swfHash.av_val[i]) << 4) | HEX2BIN(r->Link.swfHash.av_val[i + 1]); ++ r->Link.SWFSize = (uint32_t) r->Link.swfSize; ++ } ++ else if ((r->Link.lFlags & RTMP_LF_SWFV) && r->Link.swfUrl.av_len) ++ RTMP_HashSWF(r->Link.swfUrl.av_val, &r->Link.SWFSize, (unsigned char *) r->Link.SWFHash, r->Link.swfAge); + #endif + + if (r->Link.port == 0) +@@ -854,6 +881,8 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service) + } + + setsockopt(r->m_sb.sb_socket, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)); ++ if (r->Link.protocol & RTMP_FEATURE_HTTP) ++ setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof (on)); + + return TRUE; + } +@@ -1308,8 +1337,24 @@ ReadN(RTMP *r, char *buffer, int n) + return 0; + } + } +- if (r->m_resplen && !r->m_sb.sb_size) +- RTMPSockBuf_Fill(&r->m_sb); ++ ++ // Try to fill the whole buffer. previous buffer needs to be consumed ++ // completely before receiving new data. ++ if (r->m_resplen && (r->m_sb.sb_size <= 0)) ++ { ++ do ++ { ++ nBytes = RTMPSockBuf_Fill(&r->m_sb); ++ if (nBytes == -1) ++ { ++ if (!r->m_sb.sb_timedout) ++ RTMP_Close(r); ++ return 0; ++ } ++ } ++ while (r->m_resplen && (r->m_sb.sb_size < r->m_resplen) && (nBytes > 0)); ++ } ++ + avail = r->m_sb.sb_size; + if (avail > r->m_resplen) + avail = r->m_resplen; +@@ -1336,10 +1381,9 @@ ReadN(RTMP *r, char *buffer, int n) + r->m_sb.sb_size -= nRead; + nBytes = nRead; + r->m_nBytesIn += nRead; +- if (r->m_bSendCounter +- && r->m_nBytesIn > ( r->m_nBytesInSent + r->m_nClientBW / 10)) +- if (!SendBytesReceived(r)) +- return FALSE; ++ if (r->m_bSendCounter && r->m_nBytesIn > (r->m_nBytesInSent + r->m_nClientBW / 10)) ++ if (!SendBytesReceived(r)) ++ return FALSE; + } + /*RTMP_Log(RTMP_LOGDEBUG, "%s: %d bytes\n", __FUNCTION__, nBytes); */ + #ifdef _DEBUG +@@ -1390,6 +1434,16 @@ WriteN(RTMP *r, const char *buffer, int n) + } + #endif + ++ if (r->Link.ConnectPacket) ++ { ++ char *ConnectPacket = malloc(r->Link.HandshakeResponse.av_len + n); ++ memcpy(ConnectPacket, r->Link.HandshakeResponse.av_val, r->Link.HandshakeResponse.av_len); ++ memcpy(ConnectPacket + r->Link.HandshakeResponse.av_len, ptr, n); ++ ptr = ConnectPacket; ++ n += r->Link.HandshakeResponse.av_len; ++ r->Link.ConnectPacket = FALSE; ++ } ++ + while (n > 0) + { + int nBytes; +@@ -1455,6 +1509,9 @@ SendConnectPacket(RTMP *r, RTMPPacket *cp) + char pbuf[4096], *pend = pbuf + sizeof(pbuf); + char *enc; + ++ if (r->Link.CombineConnectPacket) ++ r->Link.ConnectPacket = TRUE; ++ + if (cp) + return RTMP_SendPacket(r, cp, TRUE); + +@@ -1667,7 +1724,7 @@ SendUsherToken(RTMP *r, AVal *usherToken) + packet.m_hasAbsTimestamp = 0; + packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE; + +- RTMP_Log(RTMP_LOGDEBUG, "UsherToken: %s", usherToken->av_val); ++ RTMP_Log(RTMP_LOGDEBUG, "UsherToken: %.*s", usherToken->av_len, usherToken->av_val); + enc = packet.m_body; + enc = AMF_EncodeString(enc, pend, &av_NetStream_Authenticate_UsherToken); + enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes); +@@ -2096,10 +2153,8 @@ SendPlay(RTMP *r) + enc = AMF_EncodeNumber(enc, pend, -1000.0); + else + { +- if (r->Link.seekTime > 0.0) +- enc = AMF_EncodeNumber(enc, pend, r->Link.seekTime); /* resume from here */ +- else +- enc = AMF_EncodeNumber(enc, pend, 0.0); /*-2000.0);*/ /* recorded as default, -2000.0 is not reliable since that freezes the player if the stream is not found */ ++ if (r->Link.seekTime > 0.0 || r->Link.stopTime) ++ enc = AMF_EncodeNumber(enc, pend, r->Link.seekTime); /* resume from here */ + } + if (!enc) + return FALSE; +@@ -2215,7 +2270,7 @@ RTMP_SendCtrl(RTMP *r, short nType, unsigned int nObject, unsigned int nTime) + int nSize; + char *buf; + +- RTMP_Log(RTMP_LOGDEBUG, "sending ctrl. type: 0x%04x", (unsigned short)nType); ++ RTMP_Log(RTMP_LOGDEBUG, "sending ctrl, type: 0x%04x", (unsigned short)nType); + + packet.m_nChannel = 0x02; /* control channel (ping) */ + packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM; +@@ -2247,8 +2302,8 @@ RTMP_SendCtrl(RTMP *r, short nType, unsigned int nObject, unsigned int nTime) + } + else if (nType == 0x1A) + { +- *buf = nObject & 0xff; +- } ++ *buf = nObject & 0xff; ++ } + else + { + if (nSize > 2) +@@ -2305,6 +2360,7 @@ AV_clear(RTMP_METHOD *vals, int num) + free(vals); + } + ++SAVC(onBWCheck); + SAVC(onBWDone); + SAVC(onFCSubscribe); + SAVC(onFCUnsubscribe); +@@ -2314,24 +2370,26 @@ SAVC(_error); + SAVC(close); + SAVC(code); + SAVC(level); ++SAVC(description); + SAVC(onStatus); + SAVC(playlist_ready); + static const AVal av_NetStream_Failed = AVC("NetStream.Failed"); + static const AVal av_NetStream_Play_Failed = AVC("NetStream.Play.Failed"); +-static const AVal av_NetStream_Play_StreamNotFound = +-AVC("NetStream.Play.StreamNotFound"); +-static const AVal av_NetConnection_Connect_InvalidApp = +-AVC("NetConnection.Connect.InvalidApp"); ++static const AVal av_NetStream_Play_StreamNotFound = AVC("NetStream.Play.StreamNotFound"); ++static const AVal av_NetConnection_Connect_InvalidApp = AVC("NetConnection.Connect.InvalidApp"); + static const AVal av_NetStream_Play_Start = AVC("NetStream.Play.Start"); + static const AVal av_NetStream_Play_Complete = AVC("NetStream.Play.Complete"); + static const AVal av_NetStream_Play_Stop = AVC("NetStream.Play.Stop"); + static const AVal av_NetStream_Seek_Notify = AVC("NetStream.Seek.Notify"); + static const AVal av_NetStream_Pause_Notify = AVC("NetStream.Pause.Notify"); +-static const AVal av_NetStream_Play_PublishNotify = +-AVC("NetStream.Play.PublishNotify"); +-static const AVal av_NetStream_Play_UnpublishNotify = +-AVC("NetStream.Play.UnpublishNotify"); ++static const AVal av_NetStream_Play_PublishNotify = AVC("NetStream.Play.PublishNotify"); ++static const AVal av_NetStream_Play_UnpublishNotify = AVC("NetStream.Play.UnpublishNotify"); + static const AVal av_NetStream_Publish_Start = AVC("NetStream.Publish.Start"); ++static const AVal av_NetConnection_confStream = AVC("NetConnection.confStream"); ++static const AVal av_verifyClient = AVC("verifyClient"); ++static const AVal av_sendStatus = AVC("sendStatus"); ++static const AVal av_getStreamLength = AVC("getStreamLength"); ++static const AVal av_ReceiveCheckPublicStatus = AVC("ReceiveCheckPublicStatus"); + + /* Returns 0 for OK/Failed/error, 1 for 'Stop or Complete' */ + static int +@@ -2341,6 +2399,11 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize) + AVal method; + double txn; + int ret = 0, nRes; ++ char pbuf[256], *pend = pbuf + sizeof (pbuf), *enc, **params = NULL; ++ char *host = r->Link.hostname.av_len ? r->Link.hostname.av_val : ""; ++ char *pageUrl = r->Link.pageUrl.av_len ? r->Link.pageUrl.av_val : ""; ++ int param_count; ++ AVal av_Command, av_Response; + if (body[0] != 0x02) /* make sure it is a string method name we start with */ + { + RTMP_Log(RTMP_LOGWARNING, "%s, Sanity failed. no string method in invoke packet", +@@ -2402,23 +2465,137 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize) + RTMP_SendServerBW(r); + RTMP_SendCtrl(r, 3, 0, 300); + } +- RTMP_SendCreateStream(r); +- +- if (!(r->Link.protocol & RTMP_FEATURE_WRITE)) +- { +- /* Authenticate on Justin.tv legacy servers before sending FCSubscribe */ +- if (r->Link.usherToken.av_len) +- SendUsherToken(r, &r->Link.usherToken); +- /* Send the FCSubscribe if live stream or if subscribepath is set */ +- if (r->Link.subscribepath.av_len) +- SendFCSubscribe(r, &r->Link.subscribepath); +- else if (r->Link.lFlags & RTMP_LF_LIVE) +- SendFCSubscribe(r, &r->Link.playpath); +- } +- } ++ if (strstr(host, "tv-stream.to") || strstr(pageUrl, "tv-stream.to")) ++ { ++ static char auth[] = {'h', 0xC2, 0xA7, '4', 'j', 'h', 'H', '4', '3', 'd'}; ++ AVal av_auth; ++ SAVC(requestAccess); ++ av_auth.av_val = auth; ++ av_auth.av_len = sizeof (auth); ++ ++ enc = pbuf; ++ enc = AMF_EncodeString(enc, pend, &av_requestAccess); ++ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes); ++ *enc++ = AMF_NULL; ++ enc = AMF_EncodeString(enc, pend, &av_auth); ++ av_Command.av_val = pbuf; ++ av_Command.av_len = enc - pbuf; ++ SendInvoke(r, &av_Command, FALSE); ++ ++ SAVC(getConnectionCount); ++ enc = pbuf; ++ enc = AMF_EncodeString(enc, pend, &av_getConnectionCount); ++ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes); ++ *enc++ = AMF_NULL; ++ av_Command.av_val = pbuf; ++ av_Command.av_len = enc - pbuf; ++ SendInvoke(r, &av_Command, FALSE); ++ ++ SendGetStreamLength(r); ++ } ++ else if (strstr(host, "jampo.com.ua") || strstr(pageUrl, "jampo.com.ua")) ++ { ++ SendGetStreamLength(r); ++ } ++ else if (strstr(host, "streamscene.cc") || strstr(pageUrl, "streamscene.cc") ++ || strstr(host, "tsboard.tv") || strstr(pageUrl, "teamstream.in")) ++ { ++ SAVC(r); ++ enc = pbuf; ++ enc = AMF_EncodeString(enc, pend, &av_r); ++ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes); ++ *enc++ = AMF_NULL; ++ av_Command.av_val = pbuf; ++ av_Command.av_len = enc - pbuf; ++ SendInvoke(r, &av_Command, FALSE); ++ ++ SendGetStreamLength(r); ++ } ++ else if (strstr(host, "chaturbate.com") || strstr(pageUrl, "chaturbate.com")) ++ { ++ AVal av_ModelName; ++ SAVC(CheckPublicStatus); ++ ++ if (strlen(pageUrl) > 7) ++ { ++ strsplit(pageUrl + 7, FALSE, '/', ¶ms); ++ av_ModelName.av_val = params[1]; ++ av_ModelName.av_len = strlen(params[1]); ++ ++ enc = pbuf; ++ enc = AMF_EncodeString(enc, pend, &av_CheckPublicStatus); ++ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes); ++ *enc++ = AMF_NULL; ++ enc = AMF_EncodeString(enc, pend, &av_ModelName); ++ av_Command.av_val = pbuf; ++ av_Command.av_len = enc - pbuf; ++ ++ SendInvoke(r, &av_Command, FALSE); ++ } ++ else ++ { ++ RTMP_Log(RTMP_LOGERROR, "you must specify the pageUrl"); ++ RTMP_Close(r); ++ } ++ } ++ /* Weeb.tv specific authentication */ ++ else if (r->Link.WeebToken.av_len) ++ { ++ AVal av_Token, av_Username, av_Password; ++ SAVC(determineAccess); ++ ++ param_count = strsplit(r->Link.WeebToken.av_val, FALSE, ';', ¶ms); ++ if (param_count >= 1) ++ { ++ av_Token.av_val = params[0]; ++ av_Token.av_len = strlen(params[0]); ++ } ++ if (param_count >= 2) ++ { ++ av_Username.av_val = params[1]; ++ av_Username.av_len = strlen(params[1]); ++ } ++ if (param_count >= 3) ++ { ++ av_Password.av_val = params[2]; ++ av_Password.av_len = strlen(params[2]); ++ } ++ ++ enc = pbuf; ++ enc = AMF_EncodeString(enc, pend, &av_determineAccess); ++ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes); ++ *enc++ = AMF_NULL; ++ enc = AMF_EncodeString(enc, pend, &av_Token); ++ enc = AMF_EncodeString(enc, pend, &av_Username); ++ enc = AMF_EncodeString(enc, pend, &av_Password); ++ av_Command.av_val = pbuf; ++ av_Command.av_len = enc - pbuf; ++ ++ RTMP_Log(RTMP_LOGDEBUG, "WeebToken: %s", r->Link.WeebToken.av_val); ++ SendInvoke(r, &av_Command, FALSE); ++ } ++ else ++ RTMP_SendCreateStream(r); ++ } ++ else if (AVMATCH(&methodInvoked, &av_getStreamLength)) ++ { ++ RTMP_SendCreateStream(r); ++ } + else if (AVMATCH(&methodInvoked, &av_createStream)) +- { +- r->m_stream_id = (int)AMFProp_GetNumber(AMF_GetProp(&obj, NULL, 3)); ++ { ++ r->m_stream_id = (int) AMFProp_GetNumber(AMF_GetProp(&obj, NULL, 3)); ++ ++ if (!(r->Link.protocol & RTMP_FEATURE_WRITE)) ++ { ++ /* Authenticate on Justin.tv legacy servers before sending FCSubscribe */ ++ if (r->Link.usherToken.av_len) ++ SendUsherToken(r, &r->Link.usherToken); ++ /* Send the FCSubscribe if live stream or if subscribepath is set */ ++ if (r->Link.subscribepath.av_len) ++ SendFCSubscribe(r, &r->Link.subscribepath); ++ else if ((r->Link.lFlags & RTMP_LF_LIVE) && (!r->Link.WeebToken.av_len)) ++ SendFCSubscribe(r, &r->Link.playpath); ++ } + + if (r->Link.protocol & RTMP_FEATURE_WRITE) + { +@@ -2441,7 +2618,7 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize) + } + else if (AVMATCH(&method, &av_onBWDone)) + { +- if (!r->m_nBWCheckCounter) ++ if (!r->m_nBWCheckCounter) + SendCheckBW(r); + } + else if (AVMATCH(&method, &av_onFCSubscribe)) +@@ -2457,7 +2634,7 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize) + { + SendPong(r, txn); + } +- else if (AVMATCH(&method, &av__onbwcheck)) ++ else if (AVMATCH(&method, &av__onbwcheck) || AVMATCH(&method, &av_onBWCheck)) + { + SendCheckBWResult(r, txn); + } +@@ -2473,20 +2650,63 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize) + } + else if (AVMATCH(&method, &av__error)) + { +- RTMP_Log(RTMP_LOGERROR, "rtmp server sent error"); ++ double code = 0; ++ unsigned int parsedPort; ++ AMFObject obj2; ++ AMFObjectProperty p; ++ AVal redirect; ++ SAVC(ex); ++ SAVC(redirect); ++ ++ AMFProp_GetObject(AMF_GetProp(&obj, NULL, 3), &obj2); ++ if (RTMP_FindFirstMatchingProperty(&obj2, &av_ex, &p)) ++ { ++ AMFProp_GetObject(&p, &obj2); ++ if (RTMP_FindFirstMatchingProperty(&obj2, &av_code, &p)) ++ code = AMFProp_GetNumber(&p); ++ if (code == 302 && RTMP_FindFirstMatchingProperty(&obj2, &av_redirect, &p)) ++ { ++ AMFProp_GetString(&p, &redirect); ++ r->Link.redirected = TRUE; ++ ++ char *url = malloc(redirect.av_len + sizeof ("/playpath")); ++ strncpy(url, redirect.av_val, redirect.av_len); ++ url[redirect.av_len] = '\0'; ++ r->Link.tcUrl.av_val = url; ++ r->Link.tcUrl.av_len = redirect.av_len; ++ strcat(url, "/playpath"); ++ RTMP_ParseURL(url, &r->Link.protocol, &r->Link.hostname, &parsedPort, &r->Link.playpath0, &r->Link.app); ++ r->Link.port = parsedPort; ++ } ++ } ++ if (r->Link.redirected) ++ RTMP_Log(RTMP_LOGINFO, "rtmp server sent redirect"); ++ else ++ RTMP_Log(RTMP_LOGERROR, "rtmp server sent error"); + } + else if (AVMATCH(&method, &av_close)) + { +- RTMP_Log(RTMP_LOGERROR, "rtmp server requested close"); +- RTMP_Close(r); ++ if (r->Link.redirected) ++ { ++ RTMP_Log(RTMP_LOGINFO, "trying to connect with redirected url"); ++ RTMP_Close(r); ++ r->Link.redirected = FALSE; ++ RTMP_Connect(r, NULL); ++ } ++ else ++ { ++ RTMP_Log(RTMP_LOGERROR, "rtmp server requested close"); ++ RTMP_Close(r); ++ } + } + else if (AVMATCH(&method, &av_onStatus)) + { + AMFObject obj2; +- AVal code, level; ++ AVal code, level, description; + AMFProp_GetObject(AMF_GetProp(&obj, NULL, 3), &obj2); + AMFProp_GetString(AMF_GetProp(&obj2, &av_code, -1), &code); + AMFProp_GetString(AMF_GetProp(&obj2, &av_level, -1), &level); ++ AMFProp_GetString(AMF_GetProp(&obj2, &av_description, -1), &description); + + RTMP_Log(RTMP_LOGDEBUG, "%s, onStatus: %s", __FUNCTION__, code.av_val); + if (AVMATCH(&code, &av_NetStream_Failed) +@@ -2550,6 +2770,45 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize) + r->m_pausing = 3; + } + } ++ ++ else if (AVMATCH(&code, &av_NetConnection_confStream)) ++ { ++#ifdef CRYPTO ++ static const char hexdig[] = "0123456789abcdef"; ++ SAVC(cf_stream); ++ int i; ++ char hash_hex[33] = {0}; ++ unsigned char hash[16]; ++ AVal auth; ++ param_count = strsplit(description.av_val, description.av_len, ':', ¶ms); ++ if (param_count >= 3) ++ { ++ char *buf = malloc(strlen(params[0]) + r->Link.playpath.av_len + 1); ++ strcpy(buf, params[0]); ++ strncat(buf, r->Link.playpath.av_val, r->Link.playpath.av_len); ++ md5_hash((unsigned char *) buf, strlen(buf), hash); ++ for (i = 0; i < 16; i++) ++ { ++ hash_hex[i * 2] = hexdig[0x0f & (hash[i] >> 4)]; ++ hash_hex[i * 2 + 1] = hexdig[0x0f & (hash[i])]; ++ } ++ auth.av_val = &hash_hex[atoi(params[1]) - 1]; ++ auth.av_len = atoi(params[2]); ++ RTMP_Log(RTMP_LOGDEBUG, "Khalsa: %.*s", auth.av_len, auth.av_val); ++ ++ enc = pbuf; ++ enc = AMF_EncodeString(enc, pend, &av_cf_stream); ++ enc = AMF_EncodeNumber(enc, pend, txn); ++ *enc++ = AMF_NULL; ++ enc = AMF_EncodeString(enc, pend, &auth); ++ av_Command.av_val = pbuf; ++ av_Command.av_len = enc - pbuf; ++ ++ SendInvoke(r, &av_Command, FALSE); ++ free(buf); ++ } ++#endif ++ } + } + else if (AVMATCH(&method, &av_playlist_ready)) + { +@@ -2563,6 +2822,74 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize) + } + } + } ++ else if (AVMATCH(&method, &av_verifyClient)) ++ { ++ double VerificationNumber = AMFProp_GetNumber(AMF_GetProp(&obj, NULL, 3)); ++ RTMP_Log(RTMP_LOGDEBUG, "VerificationNumber: %.2f", VerificationNumber); ++ ++ enc = pbuf; ++ enc = AMF_EncodeString(enc, pend, &av__result); ++ enc = AMF_EncodeNumber(enc, pend, txn); ++ *enc++ = AMF_NULL; ++ enc = AMF_EncodeNumber(enc, pend, exp(atan(sqrt(VerificationNumber))) + 1); ++ av_Response.av_val = pbuf; ++ av_Response.av_len = enc - pbuf; ++ ++ AMF_Decode(&obj, av_Response.av_val, av_Response.av_len, FALSE); ++ AMF_Dump(&obj); ++ SendInvoke(r, &av_Response, FALSE); ++ } ++ else if (AVMATCH(&method, &av_sendStatus)) ++ { ++ if (r->Link.WeebToken.av_len) ++ { ++ AVal av_Authorized = AVC("User.hasAccess"); ++ AVal av_TransferLimit = AVC("User.noPremium.limited"); ++ AVal av_UserLimit = AVC("User.noPremium.tooManyUsers"); ++ AVal av_TimeLeft = AVC("timeLeft"); ++ AVal av_Status, av_ReconnectionTime; ++ ++ AMFObject Status; ++ AMFProp_GetObject(AMF_GetProp(&obj, NULL, 3), &Status); ++ AMFProp_GetString(AMF_GetProp(&Status, &av_code, -1), &av_Status); ++ RTMP_Log(RTMP_LOGINFO, "%.*s", av_Status.av_len, av_Status.av_val); ++ if (AVMATCH(&av_Status, &av_Authorized)) ++ { ++ RTMP_Log(RTMP_LOGINFO, "Weeb.tv authentication successful"); ++ RTMP_SendCreateStream(r); ++ } ++ else if (AVMATCH(&av_Status, &av_UserLimit)) ++ { ++ RTMP_Log(RTMP_LOGINFO, "No free slots available"); ++ RTMP_Close(r); ++ } ++ else if (AVMATCH(&av_Status, &av_TransferLimit)) ++ { ++ AMFProp_GetString(AMF_GetProp(&Status, &av_TimeLeft, -1), &av_ReconnectionTime); ++ RTMP_Log(RTMP_LOGINFO, "Viewing limit exceeded. try again in %.*s minutes.", av_ReconnectionTime.av_len, av_ReconnectionTime.av_val); ++ RTMP_Close(r); ++ } ++ } ++ } ++ else if (AVMATCH(&method, &av_ReceiveCheckPublicStatus)) ++ { ++ AVal Status; ++ AMFProp_GetString(AMF_GetProp(&obj, NULL, 3), &Status); ++ strsplit(Status.av_val, Status.av_len, ',', ¶ms); ++ if (strcmp(params[0], "0") == 0) ++ { ++ RTMP_Log(RTMP_LOGINFO, "Model status is %s", params[1]); ++ RTMP_Close(r); ++ } ++ else ++ { ++ AVal Playpath; ++ Playpath.av_val = params[1]; ++ Playpath.av_len = strlen(params[1]); ++ RTMP_ParsePlaypath(&Playpath, &r->Link.playpath); ++ RTMP_SendCreateStream(r); ++ } ++ } + else + { + +@@ -2748,7 +3075,7 @@ HandleCtrl(RTMP *r, const RTMPPacket *packet) + unsigned int tmp; + if (packet->m_body && packet->m_nBodySize >= 2) + nType = AMF_DecodeInt16(packet->m_body); +- RTMP_Log(RTMP_LOGDEBUG, "%s, received ctrl. type: %d, len: %d", __FUNCTION__, nType, ++ RTMP_Log(RTMP_LOGDEBUG, "%s, received ctrl, type: %d, len: %d", __FUNCTION__, nType, + packet->m_nBodySize); + /*RTMP_LogHex(packet.m_body, packet.m_nBodySize); */ + +@@ -2856,15 +3183,15 @@ HandleCtrl(RTMP *r, const RTMPPacket *packet) + RTMP_Log(RTMP_LOGDEBUG, "%s, SWFVerification ping received: ", __FUNCTION__); + if (packet->m_nBodySize > 2 && packet->m_body[2] > 0x01) + { +- RTMP_Log(RTMP_LOGERROR, +- "%s: SWFVerification Type %d request not supported! Patches welcome...", +- __FUNCTION__, packet->m_body[2]); ++ RTMP_Log(RTMP_LOGERROR, ++ "%s: SWFVerification Type %d request not supported, attempting to use SWFVerification Type 1! Patches welcome...", ++ __FUNCTION__, packet->m_body[2]); + } + #ifdef CRYPTO + /*RTMP_LogHex(packet.m_body, packet.m_nBodySize); */ + + /* respond with HMAC SHA256 of decompressed SWF, key is the 30byte player key, also the last 30 bytes of the server handshake are applied */ +- else if (r->Link.SWFSize) ++ if (r->Link.SWFSize) + { + RTMP_SendCtrl(r, 0x1B, 0, 0); + } +@@ -3142,8 +3469,18 @@ HandShake(RTMP *r, int FP9HandShake) + serversig[4], serversig[5], serversig[6], serversig[7]); + + /* 2nd part of handshake */ +- if (!WriteN(r, serversig, RTMP_SIG_SIZE)) +- return FALSE; ++ if (r->Link.CombineConnectPacket) ++ { ++ char *HandshakeResponse = malloc(RTMP_SIG_SIZE); ++ memcpy(HandshakeResponse, (char *) serversig, RTMP_SIG_SIZE); ++ r->Link.HandshakeResponse.av_val = HandshakeResponse; ++ r->Link.HandshakeResponse.av_len = RTMP_SIG_SIZE; ++ } ++ else ++ { ++ if (!WriteN(r, (char *) serversig, RTMP_SIG_SIZE)) ++ return FALSE; ++ } + + if (ReadN(r, serversig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE) + return FALSE; +@@ -3709,12 +4046,11 @@ HTTP_Post(RTMP *r, RTMPTCmd cmd, const char *buf, int len) + char hbuf[512]; + int hlen = snprintf(hbuf, sizeof(hbuf), "POST /%s%s/%d HTTP/1.1\r\n" + "Host: %.*s:%d\r\n" +- "Accept: */*\r\n" +- "User-Agent: Shockwave Flash\n" +- "Connection: Keep-Alive\n" ++ "User-Agent: Shockwave Flash\r\n" ++ "Connection: Keep-Alive\r\n" + "Cache-Control: no-cache\r\n" +- "Content-type: application/x-fcs\r\n" +- "Content-length: %d\r\n\r\n", RTMPT_cmds[cmd], ++ "Content-Type: application/x-fcs\r\n" ++ "Content-Length: %d\r\n\r\n", RTMPT_cmds[cmd], + r->m_clientID.av_val ? r->m_clientID.av_val : "", + r->m_msgCounter, r->Link.hostname.av_len, r->Link.hostname.av_val, + r->Link.port, len); +@@ -3749,6 +4085,14 @@ HTTP_read(RTMP *r, int fill) + if (!ptr) + return -1; + ptr += 4; ++ int resplen = r->m_sb.sb_size - (ptr - r->m_sb.sb_start); ++ if (hlen < 4096) ++ while (resplen < hlen) ++ { ++ if (RTMPSockBuf_Fill(&r->m_sb) == -1) ++ return -1; ++ resplen = r->m_sb.sb_size - (ptr - r->m_sb.sb_start); ++ } + r->m_sb.sb_size -= ptr - r->m_sb.sb_start; + r->m_sb.sb_start = ptr; + r->m_unackd--; +@@ -4301,13 +4645,21 @@ fail: + r->m_read.status = nRead; + goto fail; + } +- /* buffer overflow, fix buffer and give up */ +- if (r->m_read.buf < mybuf || r->m_read.buf > end) { +- mybuf = realloc(mybuf, cnt + nRead); +- memcpy(mybuf+cnt, r->m_read.buf, nRead); +- r->m_read.buf = mybuf+cnt+nRead; +- break; +- } ++ /* buffer overflow, fix buffer and give up */ ++ if (r->m_read.buf < mybuf || r->m_read.buf > end) ++ { ++ if (!cnt) ++ { ++ mybuf = realloc(mybuf, sizeof (flvHeader) + cnt + nRead); ++ memcpy(mybuf, flvHeader, sizeof (flvHeader)); ++ cnt += sizeof (flvHeader); ++ } ++ else ++ mybuf = realloc(mybuf, cnt + nRead); ++ memcpy(mybuf + cnt, r->m_read.buf, nRead); ++ r->m_read.buf = mybuf + cnt + nRead; ++ break; ++ } + cnt += nRead; + r->m_read.buf += nRead; + r->m_read.buflen -= nRead; +@@ -4458,3 +4810,90 @@ RTMP_Write(RTMP *r, const char *buf, int size) + } + return size+s2; + } ++ ++static int ++SendInvoke(RTMP *r, AVal *Command, int queue) ++{ ++ RTMPPacket packet; ++ char pbuf[512], *enc; ++ ++ packet.m_nChannel = 0x03; /* control channel (invoke) */ ++ packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM; ++ packet.m_packetType = RTMP_PACKET_TYPE_INVOKE; ++ packet.m_nTimeStamp = 0; ++ packet.m_nInfoField2 = 0; ++ packet.m_hasAbsTimestamp = 0; ++ packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE; ++ ++ enc = packet.m_body; ++ if (Command->av_len) ++ { ++ memcpy(enc, Command->av_val, Command->av_len); ++ enc += Command->av_len; ++ } ++ else ++ return FALSE; ++ packet.m_nBodySize = enc - packet.m_body; ++ ++ return RTMP_SendPacket(r, &packet, queue); ++} ++ ++static int ++strsplit(char *src, int srclen, char delim, char ***params) ++{ ++ char *sptr, *srcbeg, *srcend, *dstr; ++ int count = 1, i = 0, len = 0; ++ ++ if (src == NULL) ++ return 0; ++ if (!srclen) ++ srclen = strlen(src); ++ srcbeg = src; ++ srcend = srcbeg + srclen; ++ sptr = srcbeg; ++ ++ /* count the delimiters */ ++ while (sptr < srcend) ++ { ++ if (*sptr++ == delim) ++ count++; ++ } ++ sptr = srcbeg; ++ *params = calloc(count, sizeof (size_t)); ++ char **param = *params; ++ ++ for (i = 0; i < (count - 1); i++) ++ { ++ dstr = strchr(sptr, delim); ++ len = dstr - sptr; ++ param[i] = calloc(len + 1, sizeof (char)); ++ strncpy(param[i], sptr, len); ++ sptr += len + 1; ++ } ++ ++ /* copy the last string */ ++ if (sptr <= srcend) ++ { ++ len = srclen - (sptr - srcbeg); ++ param[i] = calloc(len + 1, sizeof (char)); ++ strncpy(param[i], sptr, len); ++ } ++ return count; ++} ++ ++static int ++SendGetStreamLength(RTMP *r) ++{ ++ char pbuf[256], *pend = pbuf + sizeof (pbuf), *enc; ++ AVal av_Command; ++ ++ enc = pbuf; ++ enc = AMF_EncodeString(enc, pend, &av_getStreamLength); ++ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes); ++ *enc++ = AMF_NULL; ++ enc = AMF_EncodeString(enc, pend, &r->Link.playpath); ++ av_Command.av_val = pbuf; ++ av_Command.av_len = enc - pbuf; ++ ++ return SendInvoke(r, &av_Command, TRUE); ++} +diff --git a/librtmp/rtmp.h b/librtmp/rtmp.h +index 6b2ae5b..411b488 100644 +--- a/librtmp/rtmp.h ++++ b/librtmp/rtmp.h +@@ -150,12 +150,14 @@ extern "C" + AVal playpath; /* passed in explicitly */ + AVal tcUrl; + AVal swfUrl; ++ AVal swfHash; + AVal pageUrl; + AVal app; + AVal auth; + AVal flashVer; + AVal subscribepath; + AVal usherToken; ++ AVal WeebToken; + AVal token; + AMFObject extras; + int edepth; +@@ -172,9 +174,15 @@ extern "C" + int lFlags; + + int swfAge; ++ int swfSize; + + int protocol; ++ int ConnectPacket; ++ int CombineConnectPacket; ++ int redirected; + int timeout; /* connection timeout in seconds */ ++ AVal Extras; ++ AVal HandshakeResponse; + + unsigned short socksport; + unsigned short port; +@@ -299,6 +307,7 @@ extern "C" + AVal *flashVer, + AVal *subscribepath, + AVal *usherToken, ++ AVal *WeebToken, + int dStart, + int dStop, int bLiveStream, long int timeout); + +diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h +index c3fd4a6..1bfb562 100644 +--- a/librtmp/rtmp_sys.h ++++ b/librtmp/rtmp_sys.h +@@ -64,6 +64,7 @@ + #include + #include + #include ++#include + typedef struct tls_ctx { + havege_state hs; + ssl_session ssn; +@@ -71,7 +72,7 @@ typedef struct tls_ctx { + #define TLS_CTX tls_ctx * + #define TLS_client(ctx,s) s = malloc(sizeof(ssl_context)); ssl_init(s);\ + ssl_set_endpoint(s, SSL_IS_CLIENT); ssl_set_authmode(s, SSL_VERIFY_NONE);\ +- ssl_set_rng(s, havege_rand, &ctx->hs);\ ++ ssl_set_rng(s, havege_random, &ctx->hs);\ + ssl_set_ciphersuites(s, ssl_default_ciphersuites);\ + ssl_set_session(s, 1, 600, &ctx->ssn) + #define TLS_setfd(s,fd) ssl_set_bio(s, net_recv, &fd, net_send, &fd) +@@ -80,6 +81,7 @@ typedef struct tls_ctx { + #define TLS_write(s,b,l) ssl_write(s,(unsigned char *)b,l) + #define TLS_shutdown(s) ssl_close_notify(s) + #define TLS_close(s) ssl_free(s); free(s) ++#define md5_hash(i, ilen, o) md5(i, ilen, o) + + #elif defined(USE_GNUTLS) + #include +@@ -95,6 +97,8 @@ typedef struct tls_ctx { + #define TLS_write(s,b,l) gnutls_record_send(s,b,l) + #define TLS_shutdown(s) gnutls_bye(s, GNUTLS_SHUT_RDWR) + #define TLS_close(s) gnutls_deinit(s) ++#define md5_hash(i, ilen, o) gnutls_digest_algorithm_t algorithm = GNUTLS_DIG_MD5;\ ++ gnutls_hash_fast(algorithm, i, ilen, o); + + #else /* USE_OPENSSL */ + #define TLS_CTX SSL_CTX * +@@ -105,6 +109,7 @@ typedef struct tls_ctx { + #define TLS_write(s,b,l) SSL_write(s,b,l) + #define TLS_shutdown(s) SSL_shutdown(s) + #define TLS_close(s) SSL_free(s) ++#define md5_hash(i, ilen, o) MD5(i, ilen, o) + + #endif + #endif +diff --git a/rtmpdump.c b/rtmpdump.c +index e52f7d4..7bb0890 100644 +--- a/rtmpdump.c ++++ b/rtmpdump.c +@@ -701,6 +701,8 @@ void usage(char *prog) + RTMP_LogPrintf + ("--jtv|-j JSON Authentication token for Justin.tv legacy servers\n"); + RTMP_LogPrintf ++ ("--weeb|-J string Authentication token for weeb.tv servers\n"); ++ RTMP_LogPrintf + ("--hashes|-# Display progress with hashes, not with the byte counter\n"); + RTMP_LogPrintf + ("--buffer|-b Buffer time in milliseconds (default: %u)\n", +@@ -747,7 +749,8 @@ main(int argc, char **argv) + AVal hostname = { 0, 0 }; + AVal playpath = { 0, 0 }; + AVal subscribepath = { 0, 0 }; +- AVal usherToken = { 0, 0 }; //Justin.tv auth token ++ AVal usherToken = { 0, 0 }; // Justin.tv auth token ++ AVal WeebToken = { 0, 0 }; // Weeb.tv auth token + int port = -1; + int protocol = RTMP_PROTOCOL_UNDEFINED; + int retries = 0; +@@ -852,12 +855,13 @@ main(int argc, char **argv) + {"quiet", 0, NULL, 'q'}, + {"verbose", 0, NULL, 'V'}, + {"jtv", 1, NULL, 'j'}, ++ {"weeb", 1, NULL, 'J'}, + {0, 0, 0, 0} + }; + + while ((opt = + getopt_long(argc, argv, +- "hVveqzRr:s:t:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#j:", ++ "hVveqzr:s:t:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#j:J:", + longopts, NULL)) != -1) + { + switch (opt) +@@ -1070,6 +1074,9 @@ main(int argc, char **argv) + case 'j': + STR2AVAL(usherToken, optarg); + break; ++ case 'J': ++ STR2AVAL(WeebToken, optarg); ++ break; + default: + RTMP_LogPrintf("unknown option: %c\n", opt); + usage(argv[0]); +@@ -1161,14 +1168,14 @@ main(int argc, char **argv) + + if (tcUrl.av_len == 0) + { +- tcUrl.av_len = strlen(RTMPProtocolStringsLower[protocol]) + +- hostname.av_len + app.av_len + sizeof("://:65535/"); ++ tcUrl.av_len = strlen(RTMPProtocolStringsLower[protocol]) + ++ hostname.av_len + app.av_len + sizeof ("://:65535/"); + tcUrl.av_val = (char *) malloc(tcUrl.av_len); +- if (!tcUrl.av_val) +- return RD_FAILED; ++ if (!tcUrl.av_val) ++ return RD_FAILED; + tcUrl.av_len = snprintf(tcUrl.av_val, tcUrl.av_len, "%s://%.*s:%d/%.*s", +- RTMPProtocolStringsLower[protocol], hostname.av_len, +- hostname.av_val, port, app.av_len, app.av_val); ++ RTMPProtocolStringsLower[protocol], hostname.av_len, ++ hostname.av_val, port, app.av_len, app.av_val); + } + + int first = 1; +@@ -1187,7 +1194,7 @@ main(int argc, char **argv) + + RTMP_SetupStream(&rtmp, protocol, &hostname, port, &sockshost, &playpath, + &tcUrl, &swfUrl, &pageUrl, &app, &auth, &swfHash, swfSize, +- &flashVer, &subscribepath, &usherToken, dSeek, dStopOffset, bLiveStream, timeout); ++ &flashVer, &subscribepath, &usherToken, &WeebToken, dSeek, dStopOffset, bLiveStream, timeout); + + /* Try to keep the stream moving if it pauses on us */ + if (!bLiveStream && !bRealtimeStream && !(protocol & RTMP_FEATURE_HTTP)) +diff --git a/rtmpgw.c b/rtmpgw.c +index 0cf56bb..cd4396d 100644 +--- a/rtmpgw.c ++++ b/rtmpgw.c +@@ -95,7 +95,8 @@ typedef struct + AVal flashVer; + AVal token; + AVal subscribepath; +- AVal usherToken; //Justin.tv auth token ++ AVal usherToken; // Justin.tv auth token ++ AVal WeebToken; // Weeb.tv auth token + AVal sockshost; + AMFObject extras; + int edepth; +@@ -553,7 +554,7 @@ void processTCPrequest(STREAMING_SERVER * server, // server socket and state (ou + RTMP_Init(&rtmp); + RTMP_SetBufferMS(&rtmp, req.bufferTime); + RTMP_SetupStream(&rtmp, req.protocol, &req.hostname, req.rtmpport, &req.sockshost, +- &req.playpath, &req.tcUrl, &req.swfUrl, &req.pageUrl, &req.app, &req.auth, &req.swfHash, req.swfSize, &req.flashVer, &req.subscribepath, &req.usherToken, dSeek, req.dStopOffset, ++ &req.playpath, &req.tcUrl, &req.swfUrl, &req.pageUrl, &req.app, &req.auth, &req.swfHash, req.swfSize, &req.flashVer, &req.subscribepath, &req.usherToken, &req.WeebToken, dSeek, req.dStopOffset, + req.bLiveStream, req.timeout); + /* backward compatibility, we always sent this as true before */ + if (req.auth.av_len) +@@ -957,6 +958,9 @@ ParseOption(char opt, char *arg, RTMP_REQUEST * req) + case 'j': + STR2AVAL(req->usherToken, arg); + break; ++ case 'J': ++ STR2AVAL(req->WeebToken, arg); ++ break; + default: + RTMP_LogPrintf("unknown option: %c, arg: %s\n", opt, arg); + return FALSE; +@@ -1028,6 +1032,7 @@ main(int argc, char **argv) + {"quiet", 0, NULL, 'q'}, + {"verbose", 0, NULL, 'V'}, + {"jtv", 1, NULL, 'j'}, ++ {"weeb", 1, NULL, 'J'}, + {0, 0, 0, 0} + }; + +@@ -1040,7 +1045,7 @@ main(int argc, char **argv) + + while ((opt = + getopt_long(argc, argv, +- "hvqVzr:s:t:p:a:f:u:n:c:l:y:m:d:D:A:B:T:g:w:x:W:X:S:j:", longopts, ++ "hvqVzr:s:t:p:a:f:u:n:c:l:y:m:d:D:A:B:T:g:w:x:W:X:S:j:J:", longopts, + NULL)) != -1) + { + switch (opt) +@@ -1103,6 +1108,8 @@ main(int argc, char **argv) + RTMP_LogPrintf + ("--jtv|-j JSON Authentication token for Justin.tv legacy servers\n"); + RTMP_LogPrintf ++ ("--weeb|-J string Authentication token for weeb.tv servers\n"); ++ RTMP_LogPrintf + ("--buffer|-b Buffer time in milliseconds (default: %u)\n\n", + defaultRTMPRequest.bufferTime); + +diff --git a/rtmpsrv.c b/rtmpsrv.c +index 9aa62f3..9ec8f23 100644 +--- a/rtmpsrv.c ++++ b/rtmpsrv.c +@@ -96,9 +96,20 @@ STREAMING_SERVER *rtmpServer = 0; // server structure pointer + STREAMING_SERVER *startStreaming(const char *address, int port); + void stopStreaming(STREAMING_SERVER * server); + void AVreplace(AVal *src, const AVal *orig, const AVal *repl); ++char *strreplace(char *srcstr, int srclen, char *orig, char *repl); ++int file_exists(const char *fname); ++int SendCheckBWResponse(RTMP *r, int oldMethodType, int onBWDoneInit); ++AVal AVcopy(AVal src); ++AVal StripParams(AVal *src); + + static const AVal av_dquote = AVC("\""); + static const AVal av_escdquote = AVC("\\\""); ++#ifdef WIN32 ++static const AVal av_caret = AVC("^"); ++static const AVal av_esccaret = AVC("^^"); ++static const AVal av_pipe = AVC("|"); ++static const AVal av_escpipe = AVC("^|"); ++#endif + + typedef struct + { +@@ -167,6 +178,10 @@ SAVC(level); + SAVC(code); + SAVC(description); + SAVC(secureToken); ++SAVC(_checkbw); ++SAVC(_onbwdone); ++SAVC(checkBandwidth); ++SAVC(onBWDone); + + static int + SendConnectResult(RTMP *r, double txn) +@@ -190,7 +205,7 @@ SendConnectResult(RTMP *r, double txn) + enc = AMF_EncodeNumber(enc, pend, txn); + *enc++ = AMF_OBJECT; + +- STR2AVAL(av, "FMS/3,5,1,525"); ++ STR2AVAL(av, "FMS/3,5,7,7009"); + enc = AMF_EncodeNamedString(enc, pend, &av_fmsVer, &av); + enc = AMF_EncodeNamedNumber(enc, pend, &av_capabilities, 31.0); + enc = AMF_EncodeNamedNumber(enc, pend, &av_mode, 1.0); +@@ -212,7 +227,7 @@ SendConnectResult(RTMP *r, double txn) + enc = AMF_EncodeNamedString(enc, pend, &av_secureToken, &av); + #endif + STR2AVAL(p.p_name, "version"); +- STR2AVAL(p.p_vu.p_aval, "3,5,1,525"); ++ STR2AVAL(p.p_vu.p_aval, "3,5,7,7009"); + p.p_type = AMF_STRING; + obj.o_num = 1; + obj.o_props = &p; +@@ -268,7 +283,7 @@ static int + SendPlayStart(RTMP *r) + { + RTMPPacket packet; +- char pbuf[512], *pend = pbuf+sizeof(pbuf); ++ char pbuf[1024], *pend = pbuf + sizeof (pbuf); + + packet.m_nChannel = 0x03; // control channel (invoke) + packet.m_headerType = 1; /* RTMP_PACKET_SIZE_MEDIUM; */ +@@ -300,7 +315,7 @@ static int + SendPlayStop(RTMP *r) + { + RTMPPacket packet; +- char pbuf[512], *pend = pbuf+sizeof(pbuf); ++ char pbuf[1024], *pend = pbuf + sizeof (pbuf); + + packet.m_nChannel = 0x03; // control channel (invoke) + packet.m_headerType = 1; /* RTMP_PACKET_SIZE_MEDIUM; */ +@@ -328,6 +343,49 @@ SendPlayStop(RTMP *r) + return RTMP_SendPacket(r, &packet, FALSE); + } + ++int ++SendCheckBWResponse(RTMP *r, int oldMethodType, int onBWDoneInit) ++{ ++ RTMPPacket packet; ++ char pbuf[256], *pend = pbuf + sizeof (pbuf); ++ char *enc; ++ ++ packet.m_nChannel = 0x03; /* control channel (invoke) */ ++ packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM; ++ packet.m_packetType = RTMP_PACKET_TYPE_INVOKE; ++ packet.m_nTimeStamp = 0; ++ packet.m_nInfoField2 = 0; ++ packet.m_hasAbsTimestamp = 0; ++ packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE; ++ ++ enc = packet.m_body; ++ if (oldMethodType) ++ { ++ enc = AMF_EncodeString(enc, pend, &av__onbwdone); ++ enc = AMF_EncodeNumber(enc, pend, 0); ++ *enc++ = AMF_NULL; ++ enc = AMF_EncodeNumber(enc, pend, 10240); ++ enc = AMF_EncodeNumber(enc, pend, 10240); ++ } ++ else ++ { ++ enc = AMF_EncodeString(enc, pend, &av_onBWDone); ++ enc = AMF_EncodeNumber(enc, pend, 0); ++ *enc++ = AMF_NULL; ++ if (!onBWDoneInit) ++ { ++ enc = AMF_EncodeNumber(enc, pend, 10240); ++ enc = AMF_EncodeNumber(enc, pend, 10240); ++ enc = AMF_EncodeNumber(enc, pend, 0); ++ enc = AMF_EncodeNumber(enc, pend, 0); ++ } ++ } ++ ++ packet.m_nBodySize = enc - packet.m_body; ++ ++ return RTMP_SendPacket(r, &packet, FALSE); ++} ++ + static void + spawn_dumper(int argc, AVal *av, char *cmd) + { +@@ -568,6 +626,7 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int + server->arglen += countAMF(&r->Link.extras, &server->argc); + } + SendConnectResult(r, txn); ++ SendCheckBWResponse(r, FALSE, TRUE); + } + else if (AVMATCH(&method, &av_createStream)) + { +@@ -582,10 +641,22 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int + AVal usherToken; + AMFProp_GetString(AMF_GetProp(&obj, NULL, 3), &usherToken); + AVreplace(&usherToken, &av_dquote, &av_escdquote); ++#ifdef WIN32 ++ AVreplace(&usherToken, &av_caret, &av_esccaret); ++ AVreplace(&usherToken, &av_pipe, &av_escpipe); ++#endif + server->arglen += 6 + usherToken.av_len; + server->argc += 2; + r->Link.usherToken = usherToken; + } ++ else if (AVMATCH(&method, &av__checkbw)) ++ { ++ SendCheckBWResponse(r, TRUE, FALSE); ++ } ++ else if (AVMATCH(&method, &av_checkBandwidth)) ++ { ++ SendCheckBWResponse(r, FALSE, FALSE); ++ } + else if (AVMATCH(&method, &av_play)) + { + char *file, *p, *q, *cmd, *ptr; +@@ -599,6 +670,17 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int + if (obj.o_num > 5) + r->Link.length = AMFProp_GetNumber(AMF_GetProp(&obj, NULL, 5)); + */ ++ double StartFlag = 0; ++ AMFObjectProperty *Start = AMF_GetProp(&obj, NULL, 4); ++ if (!(Start->p_type == AMF_INVALID)) ++ StartFlag = AMFProp_GetNumber(Start); ++ r->Link.app = AVcopy(r->Link.app); ++ if (StartFlag == -1000 || strstr(r->Link.app.av_val, "live")) ++ { ++ StartFlag = -1000; ++ server->arglen += 7; ++ server->argc += 1; ++ } + if (r->Link.tcUrl.av_len) + { + len = server->arglen + r->Link.playpath.av_len + 4 + +@@ -616,6 +698,7 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int + argv[argc].av_val = ptr + 1; + argv[argc++].av_len = 2; + argv[argc].av_val = ptr + 5; ++ r->Link.tcUrl = StripParams(&r->Link.tcUrl); + ptr += sprintf(ptr," -r \"%s\"", r->Link.tcUrl.av_val); + argv[argc++].av_len = r->Link.tcUrl.av_len; + +@@ -640,6 +723,7 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int + argv[argc].av_val = ptr + 1; + argv[argc++].av_len = 2; + argv[argc].av_val = ptr + 5; ++ r->Link.swfUrl = StripParams(&r->Link.swfUrl); + ptr += sprintf(ptr, " -W \"%s\"", r->Link.swfUrl.av_val); + argv[argc++].av_len = r->Link.swfUrl.av_len; + } +@@ -662,10 +746,17 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int + r->Link.usherToken.av_val = NULL; + r->Link.usherToken.av_len = 0; + } +- if (r->Link.extras.o_num) { +- ptr = dumpAMF(&r->Link.extras, ptr, argv, &argc); +- AMF_Reset(&r->Link.extras); +- } ++ if (StartFlag == -1000) ++ { ++ argv[argc].av_val = ptr + 1; ++ argv[argc++].av_len = 6; ++ ptr += sprintf(ptr, " --live"); ++ } ++ if (r->Link.extras.o_num) ++ { ++ ptr = dumpAMF(&r->Link.extras, ptr, argv, &argc); ++ AMF_Reset(&r->Link.extras); ++ } + argv[argc].av_val = ptr + 1; + argv[argc++].av_len = 2; + argv[argc].av_val = ptr + 5; +@@ -673,7 +764,13 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int + r->Link.playpath.av_len, r->Link.playpath.av_val); + argv[argc++].av_len = r->Link.playpath.av_len; + +- av = r->Link.playpath; ++ if (r->Link.playpath.av_len) ++ av = r->Link.playpath; ++ else ++ { ++ av.av_val = "file"; ++ av.av_len = 4; ++ } + /* strip trailing URL parameters */ + q = memchr(av.av_val, '?', av.av_len); + if (q) +@@ -725,7 +822,30 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int + argv[argc++].av_len = 2; + argv[argc].av_val = file; + argv[argc].av_len = av.av_len; +- ptr += sprintf(ptr, " -o %s", file); ++#ifdef VLC ++ char *vlc; ++ int didAlloc = FALSE; ++ ++ if (getenv("VLC")) ++ vlc = getenv("VLC"); ++ else if (getenv("ProgramFiles")) ++ { ++ vlc = malloc(512 * sizeof (char)); ++ didAlloc = TRUE; ++ char *ProgramFiles = getenv("ProgramFiles"); ++ sprintf(vlc, "%s%s", ProgramFiles, " (x86)\\VideoLAN\\VLC\\vlc.exe"); ++ if (!file_exists(vlc)) ++ sprintf(vlc, "%s%s", ProgramFiles, "\\VideoLAN\\VLC\\vlc.exe"); ++ } ++ else ++ vlc = "C:\\Program Files\\VideoLAN\\VLC\\vlc.exe"; ++ ++ ptr += sprintf(ptr, " | %s -", vlc); ++ if (didAlloc) ++ free(vlc); ++#else ++ ptr += sprintf(ptr, " -o %s", file); ++#endif + now = RTMP_GetTime(); + if (now - server->filetime < DUPTIME && AVMATCH(&argv[argc], &server->filename)) + { +@@ -739,7 +859,23 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int + server->filetime = now; + free(server->filename.av_val); + server->filename = argv[argc++]; +- spawn_dumper(argc, argv, cmd); ++#ifdef VLC ++ FILE *vlc_cmdfile = fopen("VLC.bat", "w"); ++ char *vlc_batchcmd = strreplace(cmd, 0, "%", "%%"); ++ fprintf(vlc_cmdfile, "%s\n", vlc_batchcmd); ++ fclose(vlc_cmdfile); ++ free(vlc_batchcmd); ++ spawn_dumper(argc, argv, "VLC.bat"); ++#else ++ spawn_dumper(argc, argv, cmd); ++#endif ++ ++#ifdef WIN32 ++ // Dump command to batch file ++ FILE *cmdfile = fopen("Command.bat", "a"); ++ fprintf(cmdfile, "%s\n", cmd); ++ fclose(cmdfile); ++#endif + } + + free(cmd); +@@ -1178,3 +1314,115 @@ AVreplace(AVal *src, const AVal *orig, const AVal *repl) + src->av_val = dest; + src->av_len = dptr - dest; + } ++ ++char * ++strreplace(char *srcstr, int srclen, char *orig, char *repl) ++{ ++ char *ptr = NULL, *sptr = srcstr; ++ int origlen = strlen(orig); ++ int repllen = strlen(repl); ++ if (!srclen) ++ srclen = strlen(srcstr); ++ char *srcend = srcstr + srclen; ++ int dstbuffer = srclen / origlen * repllen; ++ if (dstbuffer < srclen) ++ dstbuffer = srclen; ++ char *dststr = calloc(dstbuffer + 1, sizeof (char)); ++ char *dptr = dststr; ++ ++ if ((ptr = strstr(srcstr, orig))) ++ { ++ while (ptr < srcend && (ptr = strstr(sptr, orig))) ++ { ++ int len = ptr - sptr; ++ memcpy(dptr, sptr, len); ++ sptr += len + origlen; ++ dptr += len; ++ memcpy(dptr, repl, repllen); ++ dptr += repllen; ++ } ++ memcpy(dptr, sptr, srcend - sptr); ++ return dststr; ++ } ++ ++ memcpy(dststr, srcstr, srclen); ++ return dststr; ++} ++ ++AVal ++StripParams(AVal *src) ++{ ++ AVal str; ++ if (src->av_val) ++ { ++ str.av_val = calloc(src->av_len + 1, sizeof (char)); ++ strncpy(str.av_val, src->av_val, src->av_len); ++ str.av_len = src->av_len; ++ char *start = str.av_val; ++ char *end = start + str.av_len; ++ char *ptr = start; ++ ++ while (ptr < end) ++ { ++ if (*ptr == '?') ++ { ++ str.av_len = ptr - start; ++ break; ++ } ++ ptr++; ++ } ++ memset(start + str.av_len, 0, 1); ++ ++ char *dynamic = strstr(start, "[[DYNAMIC]]"); ++ if (dynamic) ++ { ++ dynamic -= 1; ++ memset(dynamic, 0, 1); ++ str.av_len = dynamic - start; ++ end = start + str.av_len; ++ } ++ ++ char *import = strstr(start, "[[IMPORT]]"); ++ if (import) ++ { ++ str.av_val = import + 11; ++ strcpy(start, "http://"); ++ str.av_val = strcat(start, str.av_val); ++ str.av_len = strlen(str.av_val); ++ } ++ return str; ++ } ++ str = *src; ++ return str; ++} ++ ++int ++file_exists(const char *fname) ++{ ++ FILE *file; ++ if ((file = fopen(fname, "r"))) ++ { ++ fclose(file); ++ return TRUE; ++ } ++ return FALSE; ++} ++ ++AVal ++AVcopy(AVal src) ++{ ++ AVal dst; ++ if (src.av_len) ++ { ++ dst.av_val = malloc(src.av_len + 1); ++ memcpy(dst.av_val, src.av_val, src.av_len); ++ dst.av_val[src.av_len] = '\0'; ++ dst.av_len = src.av_len; ++ } ++ else ++ { ++ dst.av_val = NULL; ++ dst.av_len = 0; ++ } ++ return dst; ++} +diff --git a/rtmpsuck.c b/rtmpsuck.c +index e886179..e80c686 100644 +--- a/rtmpsuck.c ++++ b/rtmpsuck.c +@@ -143,15 +143,18 @@ SAVC(onStatus); + SAVC(close); + static const AVal av_NetStream_Failed = AVC("NetStream.Failed"); + static const AVal av_NetStream_Play_Failed = AVC("NetStream.Play.Failed"); +-static const AVal av_NetStream_Play_StreamNotFound = +-AVC("NetStream.Play.StreamNotFound"); +-static const AVal av_NetConnection_Connect_InvalidApp = +-AVC("NetConnection.Connect.InvalidApp"); ++static const AVal av_NetStream_Play_StreamNotFound = AVC("NetStream.Play.StreamNotFound"); ++static const AVal av_NetConnection_Connect_InvalidApp = AVC("NetConnection.Connect.InvalidApp"); + static const AVal av_NetStream_Play_Start = AVC("NetStream.Play.Start"); + static const AVal av_NetStream_Play_Complete = AVC("NetStream.Play.Complete"); + static const AVal av_NetStream_Play_Stop = AVC("NetStream.Play.Stop"); ++static const AVal av_NetStream_Authenticate_UsherToken = AVC("NetStream.Authenticate.UsherToken"); + + static const char *cst[] = { "client", "server" }; ++char *dumpAMF(AMFObject *obj, char *ptr); ++char *strreplace(char *srcstr, int srclen, char *orig, char *repl); ++AVal AVcopy(AVal src); ++AVal StripParams(AVal *src); + + // Returns 0 for OK/Failed/error, 1 for 'Stop or Complete' + int +@@ -198,26 +201,28 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b + if (cobj.o_props[i].p_type == AMF_STRING) + { + pval = cobj.o_props[i].p_vu.p_aval; +- RTMP_LogPrintf("%.*s: %.*s\n", pname.av_len, pname.av_val, pval.av_len, pval.av_val); ++ RTMP_LogPrintf("%10.*s : %.*s\n", pname.av_len, pname.av_val, pval.av_len, pval.av_val); + } + if (AVMATCH(&pname, &av_app)) + { +- server->rc.Link.app = pval; ++ server->rc.Link.app = AVcopy(pval); + pval.av_val = NULL; + } + else if (AVMATCH(&pname, &av_flashVer)) + { +- server->rc.Link.flashVer = pval; ++ server->rc.Link.flashVer = AVcopy(pval); + pval.av_val = NULL; + } + else if (AVMATCH(&pname, &av_swfUrl)) + { + #ifdef CRYPTO + if (pval.av_val) +- RTMP_HashSWF(pval.av_val, &server->rc.Link.SWFSize, +- (unsigned char *)server->rc.Link.SWFHash, 30); ++ { ++ AVal swfUrl = StripParams(&pval); ++ RTMP_HashSWF(swfUrl.av_val, &server->rc.Link.SWFSize, (unsigned char *) server->rc.Link.SWFHash, 30); ++ } + #endif +- server->rc.Link.swfUrl = pval; ++ server->rc.Link.swfUrl = AVcopy(pval); + pval.av_val = NULL; + } + else if (AVMATCH(&pname, &av_tcUrl)) +@@ -225,7 +230,7 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b + char *r1 = NULL, *r2; + int len; + +- server->rc.Link.tcUrl = pval; ++ server->rc.Link.tcUrl = AVcopy(pval); + if ((pval.av_val[0] | 0x40) == 'r' && + (pval.av_val[1] | 0x40) == 't' && + (pval.av_val[2] | 0x40) == 'm' && +@@ -267,7 +272,7 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b + } + else if (AVMATCH(&pname, &av_pageUrl)) + { +- server->rc.Link.pageUrl = pval; ++ server->rc.Link.pageUrl = AVcopy(pval); + pval.av_val = NULL; + } + else if (AVMATCH(&pname, &av_audioCodecs)) +@@ -287,14 +292,21 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b + if (pval.av_val) + free(pval.av_val); + } ++ + if (obj.o_num > 3) + { +- if (AMFProp_GetBoolean(&obj.o_props[3])) +- server->rc.Link.lFlags |= RTMP_LF_AUTH; +- if (obj.o_num > 4) +- { +- AMFProp_GetString(&obj.o_props[4], &server->rc.Link.auth); +- } ++ int i = obj.o_num - 3; ++ server->rc.Link.extras.o_num = i; ++ server->rc.Link.extras.o_props = malloc(i * sizeof (AMFObjectProperty)); ++ memcpy(server->rc.Link.extras.o_props, obj.o_props + 3, i * sizeof (AMFObjectProperty)); ++ obj.o_num = 3; ++ } ++ ++ if (server->rc.Link.extras.o_num) ++ { ++ server->rc.Link.Extras.av_val = calloc(1024, sizeof (char)); ++ dumpAMF(&server->rc.Link.extras, server->rc.Link.Extras.av_val); ++ server->rc.Link.Extras.av_len = strlen(server->rc.Link.Extras.av_val); + } + + if (!RTMP_Connect(&server->rc, pack)) +@@ -303,6 +315,16 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b + return 1; + } + server->rc.m_bSendCounter = FALSE; ++ ++ if (server->rc.Link.extras.o_props) ++ { ++ AMF_Reset(&server->rc.Link.extras); ++ } ++ } ++ else if (AVMATCH(&method, &av_NetStream_Authenticate_UsherToken)) ++ { ++ AMFProp_GetString(AMF_GetProp(&obj, NULL, 3), &server->rc.Link.usherToken); ++ RTMP_LogPrintf("%10s : %.*s\n", "usherToken", server->rc.Link.usherToken.av_len, server->rc.Link.usherToken.av_val); + } + else if (AVMATCH(&method, &av_play)) + { +@@ -323,6 +345,14 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b + if (!av.av_val) + goto out; + ++ double StartFlag = 0; ++ AMFObjectProperty *Start = AMF_GetProp(&obj, NULL, 4); ++ if (!(Start->p_type == AMF_INVALID)) ++ StartFlag = AMFProp_GetNumber(Start); ++ if (StartFlag == -1000 || strstr(server->rc.Link.app.av_val, "live")) ++ StartFlag = -1000; ++ RTMP_LogPrintf("%10s : %s\n", "live", (StartFlag == -1000) ? "yes" : "no"); ++ + /* check for duplicates */ + for (fl = server->f_head; fl; fl=fl->f_next) + { +@@ -372,9 +402,51 @@ ServeInvoke(STREAMING_SERVER *server, int which, RTMPPacket *pack, const char *b + for (p=file; *p; p++) + if (*p == ':') + *p = '_'; +- RTMP_LogPrintf("Playpath: %.*s\nSaving as: %s\n", +- server->rc.Link.playpath.av_len, server->rc.Link.playpath.av_val, +- file); ++ RTMP_LogPrintf("%10s : %.*s\n%10s : %s\n", "Playpath", server->rc.Link.playpath.av_len, ++ server->rc.Link.playpath.av_val, "Saving as", file); ++ ++#ifdef WIN32 ++ // Dump command to batch file ++ char *cmd = NULL, *ptr = NULL; ++ AVal swfUrl, tcUrl; ++ ++ cmd = calloc(2048, sizeof (char)); ++ ptr = cmd; ++ tcUrl = StripParams(&server->rc.Link.tcUrl); ++ swfUrl = StripParams(&server->rc.Link.swfUrl); ++ ptr += sprintf(ptr, "rtmpdump -r \"%.*s\" -a \"%.*s\" -f \"%.*s\" -W \"%.*s\" -p \"%.*s\"", ++ tcUrl.av_len, tcUrl.av_val, ++ server->rc.Link.app.av_len, server->rc.Link.app.av_val, ++ server->rc.Link.flashVer.av_len, server->rc.Link.flashVer.av_val, ++ swfUrl.av_len, swfUrl.av_val, ++ server->rc.Link.pageUrl.av_len, server->rc.Link.pageUrl.av_val); ++ ++ if (server->rc.Link.usherToken.av_val) ++ { ++ char *usherToken = strreplace(server->rc.Link.usherToken.av_val, server->rc.Link.usherToken.av_len, "\"", "\\\""); ++ usherToken = strreplace(usherToken, 0, "^", "^^"); ++ usherToken = strreplace(usherToken, 0, "|", "^|"); ++ ptr += sprintf(ptr, " --jtv \"%s\"", usherToken); ++ free(usherToken); ++ } ++ ++ if (server->rc.Link.Extras.av_len) ++ { ++ ptr += sprintf(ptr, "%.*s", server->rc.Link.Extras.av_len, server->rc.Link.Extras.av_val); ++ } ++ ++ if (StartFlag == -1000) ++ ptr += sprintf(ptr, "%s", " --live"); ++ ptr += sprintf(ptr, " -y \"%.*s\"", server->rc.Link.playpath.av_len, server->rc.Link.playpath.av_val); ++ ptr += sprintf(ptr, " -o \"%s.flv\"\n", file); ++ ++ FILE *cmdfile = fopen("Command.bat", "a"); ++ fprintf(cmdfile, "%s", cmd); ++ fclose(cmdfile); ++ ++ free(cmd); ++#endif ++ + out = fopen(file, "wb"); + free(file); + if (!out) +@@ -1196,3 +1268,146 @@ main(int argc, char **argv) + #endif + return nStatus; + } ++ ++char * ++dumpAMF(AMFObject *obj, char *ptr) ++{ ++ int i; ++ const char opt[] = "NBSO Z"; ++ ++ for (i = 0; i < obj->o_num; i++) ++ { ++ AMFObjectProperty *p = &obj->o_props[i]; ++ if (p->p_type > 5) ++ continue; ++ ptr += sprintf(ptr, " -C "); ++ if (p->p_name.av_val) ++ *ptr++ = 'N'; ++ *ptr++ = opt[p->p_type]; ++ *ptr++ = ':'; ++ if (p->p_name.av_val) ++ ptr += sprintf(ptr, "%.*s:", p->p_name.av_len, p->p_name.av_val); ++ switch (p->p_type) ++ { ++ case AMF_BOOLEAN: ++ *ptr++ = p->p_vu.p_number != 0 ? '1' : '0'; ++ break; ++ case AMF_STRING: ++ memcpy(ptr, p->p_vu.p_aval.av_val, p->p_vu.p_aval.av_len); ++ ptr += p->p_vu.p_aval.av_len; ++ break; ++ case AMF_NUMBER: ++ ptr += sprintf(ptr, "%f", p->p_vu.p_number); ++ break; ++ case AMF_OBJECT: ++ *ptr++ = '1'; ++ ptr = dumpAMF(&p->p_vu.p_object, ptr); ++ ptr += sprintf(ptr, " -C O:0"); ++ break; ++ case AMF_NULL: ++ default: ++ break; ++ } ++ } ++ return ptr; ++} ++ ++char * ++strreplace(char *srcstr, int srclen, char *orig, char *repl) ++{ ++ char *ptr = NULL, *sptr = srcstr; ++ int origlen = strlen(orig); ++ int repllen = strlen(repl); ++ if (!srclen) ++ srclen = strlen(srcstr); ++ char *srcend = srcstr + srclen; ++ int dstbuffer = srclen / origlen * repllen; ++ if (dstbuffer < srclen) ++ dstbuffer = srclen; ++ char *dststr = calloc(dstbuffer + 1, sizeof (char)); ++ char *dptr = dststr; ++ ++ if ((ptr = strstr(srcstr, orig))) ++ { ++ while (ptr < srcend && (ptr = strstr(sptr, orig))) ++ { ++ int len = ptr - sptr; ++ memcpy(dptr, sptr, len); ++ sptr += len + origlen; ++ dptr += len; ++ memcpy(dptr, repl, repllen); ++ dptr += repllen; ++ } ++ memcpy(dptr, sptr, srcend - sptr); ++ return dststr; ++ } ++ ++ memcpy(dststr, srcstr, srclen); ++ return dststr; ++} ++ ++AVal ++StripParams(AVal *src) ++{ ++ AVal str; ++ if (src->av_val) ++ { ++ str.av_val = calloc(src->av_len + 1, sizeof (char)); ++ strncpy(str.av_val, src->av_val, src->av_len); ++ str.av_len = src->av_len; ++ char *start = str.av_val; ++ char *end = start + str.av_len; ++ char *ptr = start; ++ ++ while (ptr < end) ++ { ++ if (*ptr == '?') ++ { ++ str.av_len = ptr - start; ++ break; ++ } ++ ptr++; ++ } ++ memset(start + str.av_len, 0, 1); ++ ++ char *dynamic = strstr(start, "[[DYNAMIC]]"); ++ if (dynamic) ++ { ++ dynamic -= 1; ++ memset(dynamic, 0, 1); ++ str.av_len = dynamic - start; ++ end = start + str.av_len; ++ } ++ ++ char *import = strstr(start, "[[IMPORT]]"); ++ if (import) ++ { ++ str.av_val = import + 11; ++ strcpy(start, "http://"); ++ str.av_val = strcat(start, str.av_val); ++ str.av_len = strlen(str.av_val); ++ } ++ return str; ++ } ++ str = *src; ++ return str; ++} ++ ++AVal ++AVcopy(AVal src) ++{ ++ AVal dst; ++ if (src.av_len) ++ { ++ dst.av_val = malloc(src.av_len + 1); ++ memcpy(dst.av_val, src.av_val, src.av_len); ++ dst.av_val[src.av_len] = '\0'; ++ dst.av_len = src.av_len; ++ } ++ else ++ { ++ dst.av_val = NULL; ++ dst.av_len = 0; ++ } ++ return dst; ++} diff --git a/packages/network/avahi/init.d/53_avahi b/packages/network/avahi/init.d/53_avahi index 4f34faf3b8..ef12e72fa0 100644 --- a/packages/network/avahi/init.d/53_avahi +++ b/packages/network/avahi/init.d/53_avahi @@ -23,6 +23,9 @@ # runlevels: openelec, textmode ( + # sleep 10 sec to be ensure network is started + usleep 10000000 + progress "Starting Avahi Daemon" mkdir -p /var/run/avahi-daemon diff --git a/packages/network/connman/install b/packages/network/connman/install index 397fedb301..d8c8809a7c 100755 --- a/packages/network/connman/install +++ b/packages/network/connman/install @@ -36,7 +36,7 @@ mkdir -p $INSTALL/etc/dbus-1/system.d cp $PKG_BUILD/src/connman.conf $INSTALL/etc/dbus-1/system.d mkdir -p $INSTALL/usr/bin - cp -P $PKG_BUILD/client/cm $INSTALL/usr/bin + cp -P $PKG_BUILD/client/connmanctl $INSTALL/usr/bin mkdir -p $INSTALL/usr/lib/connman cp -P $PKG_BUILD/test/* $INSTALL/usr/lib/connman diff --git a/packages/network/connman/meta b/packages/network/connman/meta index 720b118ab1..d968dae8b8 100644 --- a/packages/network/connman/meta +++ b/packages/network/connman/meta @@ -19,14 +19,14 @@ ################################################################################ PKG_NAME="connman" -PKG_VERSION="1.6" +PKG_VERSION="1.7" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" PKG_SITE="http://www.connman.net" PKG_URL="http://www.kernel.org/pub/linux/network/connman/$PKG_NAME-$PKG_VERSION.tar.xz" -PKG_DEPENDS="glib dbus systemd iptables wpa_supplicant ntp Python pygobject dbus-python" -PKG_BUILD_DEPENDS="toolchain glib dbus systemd iptables" +PKG_DEPENDS="glib readline dbus systemd iptables wpa_supplicant ntp Python pygobject dbus-python" +PKG_BUILD_DEPENDS="toolchain glib readline dbus systemd iptables" PKG_PRIORITY="optional" PKG_SECTION="network" PKG_SHORTDESC="connman: Network manager daemon" diff --git a/packages/network/connman/patches/connman-1.6-do-not-cleanup-routes.patch b/packages/network/connman/patches/connman-1.7-do-not-cleanup-routes.patch similarity index 100% rename from packages/network/connman/patches/connman-1.6-do-not-cleanup-routes.patch rename to packages/network/connman/patches/connman-1.7-do-not-cleanup-routes.patch diff --git a/packages/network/samba/scripts/52_samba b/packages/network/samba/scripts/52_samba index 16fa8a72f6..4870ce39c8 100644 --- a/packages/network/samba/scripts/52_samba +++ b/packages/network/samba/scripts/52_samba @@ -28,7 +28,7 @@ if [ "$SAMBA_START" = "true" ]; then - # sleep 2 sec to be ensure network is started + # sleep 10 sec to be ensure network is started usleep 10000000 progress "Starting Samba server" diff --git a/packages/security/gnutls/meta b/packages/security/gnutls/meta index 0a3c45a94d..d38007c122 100644 --- a/packages/security/gnutls/meta +++ b/packages/security/gnutls/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="gnutls" -PKG_VERSION="3.0.20" +PKG_VERSION="3.0.22" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="LGPL" diff --git a/packages/security/gnutls/patches/gnutls-3.0.20-automake.patch b/packages/security/gnutls/patches/gnutls-3.0.22-automake.patch similarity index 100% rename from packages/security/gnutls/patches/gnutls-3.0.20-automake.patch rename to packages/security/gnutls/patches/gnutls-3.0.22-automake.patch diff --git a/packages/sysutils/kmod/meta b/packages/sysutils/kmod/meta index c20b643a29..7e64f66b0b 100644 --- a/packages/sysutils/kmod/meta +++ b/packages/sysutils/kmod/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="kmod" -PKG_VERSION="9" +PKG_VERSION="10" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/sysutils/systemd/meta b/packages/sysutils/systemd/meta index 9dbb17edf9..cf26819121 100644 --- a/packages/sysutils/systemd/meta +++ b/packages/sysutils/systemd/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="systemd" -PKG_VERSION="189" +PKG_VERSION="191" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/sysutils/systemd/patches/systemd-189-broken-HAVE_XZ.patch b/packages/sysutils/systemd/patches/systemd-189-broken-HAVE_XZ.patch deleted file mode 100644 index 717a2aafc6..0000000000 --- a/packages/sysutils/systemd/patches/systemd-189-broken-HAVE_XZ.patch +++ /dev/null @@ -1,33 +0,0 @@ -Without this, build fail if we --disable-xz or does not have xz installed in -system. - -Signed-off-by: Yin Kangkai ---- - src/journal/journal-verify.c | 4 ++++ - 1 files changed, 4 insertions(+), 0 deletions(-) - -diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c -index 2401293..5d134bd 100644 ---- a/src/journal/journal-verify.c -+++ b/src/journal/journal-verify.c -@@ -63,6 +63,7 @@ static int journal_file_object_verify(JournalFile *f, Object *o) { - h1 = le64toh(o->data.hash); - - if (o->object.flags & OBJECT_COMPRESSED) { -+#ifdef HAVE_XZ - void *b = NULL; - uint64_t alloc = 0, b_size; - -@@ -73,6 +74,9 @@ static int journal_file_object_verify(JournalFile *f, Object *o) { - - h2 = hash64(b, b_size); - free(b); -+#else -+ return -EPROTONOSUPPORT; -+#endif - } else - h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload)); - --- -1.7.3.4 - diff --git a/packages/sysutils/systemd/patches/systemd-189-missing_includes.patch b/packages/sysutils/systemd/patches/systemd-189-missing_includes.patch deleted file mode 100644 index 19ff579cc5..0000000000 --- a/packages/sysutils/systemd/patches/systemd-189-missing_includes.patch +++ /dev/null @@ -1,78 +0,0 @@ -From: Allin Cottrell -Date: Thu, 23 Aug 2012 23:46:38 +0000 -Subject: journald: add missing includes - ---- -diff --git a/src/journal/journald-console.c b/src/journal/journald-console.c -index 6cd2397..2596d44 100644 ---- a/src/journal/journald-console.c -+++ b/src/journal/journald-console.c -@@ -21,6 +21,7 @@ - - #include - #include -+#include - - #include "journald.h" - #include "journald-console.h" -diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf -index 2f83cbd..32474df 100644 ---- a/src/journal/journald-gperf.gperf -+++ b/src/journal/journald-gperf.gperf -@@ -1,5 +1,6 @@ - %{ - #include -+#include - #include "conf-parser.h" - #include "journald.h" - %} -diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c -index aebca5d..b259480 100644 ---- a/src/journal/journald-kmsg.c -+++ b/src/journal/journald-kmsg.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c -index 7aa99a3..4e44c3a 100644 ---- a/src/journal/journald-native.c -+++ b/src/journal/journald-native.c -@@ -20,6 +20,7 @@ - ***/ - - #include -+#include - #include - - #include "socket-util.h" -diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c -index 3e4022a..113c421 100644 ---- a/src/journal/journald-stream.c -+++ b/src/journal/journald-stream.c -@@ -21,6 +21,7 @@ - - #include - #include -+#include - #include - - #ifdef HAVE_SELINUX -diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c -index daed095..9db9198 100644 ---- a/src/journal/journald-syslog.c -+++ b/src/journal/journald-syslog.c -@@ -20,6 +20,7 @@ - ***/ - - #include -+#include - #include - - #include "socket-util.h" --- -cgit v0.9.0.2-2-gbebe diff --git a/packages/sysutils/systemd/patches/systemd-191-buildfix.patch b/packages/sysutils/systemd/patches/systemd-191-buildfix.patch new file mode 100644 index 0000000000..3034e20ca9 --- /dev/null +++ b/packages/sysutils/systemd/patches/systemd-191-buildfix.patch @@ -0,0 +1,20 @@ +From e2c8b07dcb50c2adf64cdfb22e4a496fc76576fb Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 21 Sep 2012 22:16:13 +0000 +Subject: journal: bring mmap cache prototype in sync + +--- +diff --git a/src/journal/mmap-cache.h b/src/journal/mmap-cache.h +index de34634..0c42fb8 100644 +--- a/src/journal/mmap-cache.h ++++ b/src/journal/mmap-cache.h +@@ -31,6 +31,6 @@ MMapCache* mmap_cache_new(void); + MMapCache* mmap_cache_ref(MMapCache *m); + MMapCache* mmap_cache_unref(MMapCache *m); + +-int mmap_cache_get(MMapCache *m, int fd, int prot, unsigned context, bool keep_always, uint64_t offset, uint64_t size, struct stat *st, void **ret); ++int mmap_cache_get(MMapCache *m, int fd, int prot, unsigned context, bool keep_always, uint64_t offset, size_t size, struct stat *st, void **ret); + void mmap_cache_close_fd(MMapCache *m, int fd); + void mmap_cache_close_context(MMapCache *m, unsigned context); +-- +cgit v0.9.0.2-2-gbebe diff --git a/packages/sysutils/util-linux/build b/packages/sysutils/util-linux/build index fefe3def0e..5a96a5d676 100755 --- a/packages/sysutils/util-linux/build +++ b/packages/sysutils/util-linux/build @@ -23,8 +23,6 @@ . config/options $1 cd $PKG_BUILD -#scanf_cv_type_modifier=ms \ -#gt_cv_func_gnugettext1_libintl=no \ ./configure --host=$TARGET_NAME \ --build=$HOST_NAME \ --prefix=/usr \ @@ -40,8 +38,8 @@ cd $PKG_BUILD --enable-libuuid \ --enable-libblkid \ --enable-libmount \ + --disable-deprecated-mount \ --disable-mount \ - --disable-libmount-mount \ --enable-fsck \ --disable-partx \ --enable-uuidd \ @@ -50,6 +48,7 @@ cd $PKG_BUILD --disable-unshare \ --disable-arch \ --disable-ddate \ + --disable-eject \ --disable-agetty \ --disable-cramfs \ --disable-switch-root \ @@ -57,18 +56,26 @@ cd $PKG_BUILD --disable-elvtune \ --disable-kill \ --disable-last \ + --disable-utmpdump \ --disable-line \ --disable-mesg \ --disable-raw \ --disable-rename \ --disable-reset \ - --disable-login-utils \ + --disable-vipw \ + --disable-newgrp \ + --disable-chfn-chsh \ + --enable-chsh-only-listed \ + --disable-login \ + --disable-login-chown-vcs \ + --disable-login-stat-mail \ + --disable-sulogin \ + --disable-su \ --disable-schedutils \ --disable-wall \ --disable-write \ - --enable-chsh-only-listed \ - --disable-login-chown-vcs \ - --disable-login-stat-mail \ + --disable-chkdupexe \ + --disable-socket-activation \ --disable-pg-bell \ --disable-require-password \ --disable-use-tty-group \ @@ -80,19 +87,10 @@ cd $PKG_BUILD --without-udev \ --without-ncurses \ --without-slang \ - --without-utempter + --without-utempter \ + --without-systemdsystemunitdir make $MAKEINSTALL -#make -C fsck fsck -#make -C mount swapon -#make -C misc-utils blkid -#make -C sys-utils fstrim -#make -C libuuid -#make -C libblkid - -# libuuid must be installed before libblkid!!! -# $MAKEINSTALL -C libuuid -# $MAKEINSTALL -C libblkid diff --git a/packages/sysutils/util-linux/install b/packages/sysutils/util-linux/install index 02600174f0..7167fa7607 100755 --- a/packages/sysutils/util-linux/install +++ b/packages/sysutils/util-linux/install @@ -23,20 +23,22 @@ . config/options $1 mkdir -p $INSTALL/usr/bin - cp $PKG_BUILD/misc-utils/.libs/blkid $INSTALL/usr/bin - cp $PKG_BUILD/sys-utils/fstrim $INSTALL/usr/bin - cp $PKG_BUILD/fsck/.libs/fsck $INSTALL/usr/bin + cp $PKG_BUILD/fstrim $INSTALL/usr/bin + cp $PKG_BUILD/.libs/blkid $INSTALL/usr/bin + cp $PKG_BUILD/.libs/fsck $INSTALL/usr/bin mkdir -p $INSTALL/usr/lib - cp -PR $PKG_BUILD/libblkid/src/.libs/libblkid.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/.libs/libblkid.so* $INSTALL/usr/lib rm -rf $INSTALL/usr/lib/libblkid.so*T - cp -PR $PKG_BUILD/libuuid/src/.libs/libuuid.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/.libs/libmount.so* $INSTALL/usr/lib + rm -rf $INSTALL/usr/lib/libmount.so*T + cp -PR $PKG_BUILD/.libs/libuuid.so* $INSTALL/usr/lib rm -rf $INSTALL/usr/lib/libuuid.so*T if [ "$SWAP_SUPPORT" = "yes" ]; then mkdir -p $INSTALL/usr/bin - cp $PKG_BUILD/sys-utils/.libs/swapon $INSTALL/usr/bin - ln -sf swapon $INSTALL/usr/bin/swapoff + cp $PKG_BUILD/.libs/swapon $INSTALL/usr/bin + cp $PKG_BUILD/.libs/swapoff $INSTALL/usr/bin mkdir -p $INSTALL/etc/init.d cp $PKG_DIR/scripts/32_swapfile $INSTALL/etc/init.d diff --git a/packages/sysutils/util-linux/meta b/packages/sysutils/util-linux/meta index 8975f10b40..4f22032992 100644 --- a/packages/sysutils/util-linux/meta +++ b/packages/sysutils/util-linux/meta @@ -19,11 +19,11 @@ ################################################################################ PKG_NAME="util-linux" -PKG_VERSION="2.21.2" +PKG_VERSION="2.22" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" -PKG_URL="http://www.kernel.org/pub/linux/utils/util-linux/v2.21/$PKG_NAME-$PKG_VERSION.tar.xz" +PKG_URL="http://www.kernel.org/pub/linux/utils/util-linux/v2.22/$PKG_NAME-$PKG_VERSION.tar.xz" PKG_DEPENDS="" PKG_BUILD_DEPENDS="toolchain" PKG_PRIORITY="optional" diff --git a/packages/textproc/libxml2/meta b/packages/textproc/libxml2/meta index c9de9c632c..c3b03c2400 100644 --- a/packages/textproc/libxml2/meta +++ b/packages/textproc/libxml2/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="libxml2" -PKG_VERSION="2.8.0" +PKG_VERSION="2.9.0" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="MIT" diff --git a/packages/toolchain/devel/autotools/autoconf-archive/meta b/packages/toolchain/devel/autotools/autoconf-archive/meta index 79d3e0529b..b52e73aaca 100644 --- a/packages/toolchain/devel/autotools/autoconf-archive/meta +++ b/packages/toolchain/devel/autotools/autoconf-archive/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="autoconf-archive" -PKG_VERSION="2012.04.07" +PKG_VERSION="2012.09.08" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/toolchain/devel/pkg-config/meta b/packages/toolchain/devel/pkg-config/meta index 41816d8ddd..433164a413 100644 --- a/packages/toolchain/devel/pkg-config/meta +++ b/packages/toolchain/devel/pkg-config/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="pkg-config" -PKG_VERSION="0.27" +PKG_VERSION="0.27.1" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/toolchain/lang/nasm/meta b/packages/toolchain/lang/nasm/meta index 835e360507..b87064677b 100644 --- a/packages/toolchain/lang/nasm/meta +++ b/packages/toolchain/lang/nasm/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="nasm" -PKG_VERSION="2.10.04" +PKG_VERSION="2.10.05" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/toolchain/math/mpc/meta b/packages/toolchain/math/mpc/meta index a54066f952..c7cc50d830 100644 --- a/packages/toolchain/math/mpc/meta +++ b/packages/toolchain/math/mpc/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="mpc" -PKG_VERSION="1.0" +PKG_VERSION="1.0.1" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="LGPL" diff --git a/packages/toolchain/math/mpfr/patches/mpfr-3.1.1-allpatches_20120830.patch b/packages/toolchain/math/mpfr/patches/mpfr-3.1.1-allpatches_20120830.patch new file mode 100644 index 0000000000..43dfcbfe32 --- /dev/null +++ b/packages/toolchain/math/mpfr/patches/mpfr-3.1.1-allpatches_20120830.patch @@ -0,0 +1,405 @@ +diff -Naurd mpfr-3.1.1-a/PATCHES mpfr-3.1.1-b/PATCHES +--- mpfr-3.1.1-a/PATCHES 2012-08-30 09:28:51.000000000 +0000 ++++ mpfr-3.1.1-b/PATCHES 2012-08-30 09:28:51.000000000 +0000 +@@ -0,0 +1 @@ ++get_decimal64 +diff -Naurd mpfr-3.1.1-a/VERSION mpfr-3.1.1-b/VERSION +--- mpfr-3.1.1-a/VERSION 2012-07-03 15:01:13.000000000 +0000 ++++ mpfr-3.1.1-b/VERSION 2012-08-30 09:28:51.000000000 +0000 +@@ -1 +1 @@ +-3.1.1 ++3.1.1-p1 +diff -Naurd mpfr-3.1.1-a/src/get_d64.c mpfr-3.1.1-b/src/get_d64.c +--- mpfr-3.1.1-a/src/get_d64.c 2012-07-03 15:01:18.000000000 +0000 ++++ mpfr-3.1.1-b/src/get_d64.c 2012-08-30 09:28:51.000000000 +0000 +@@ -32,6 +32,10 @@ + + #ifdef MPFR_WANT_DECIMAL_FLOATS + ++#ifndef DEC64_MAX ++# define DEC64_MAX 9.999999999999999E384dd ++#endif ++ + #ifdef DPD_FORMAT + static int T[1000] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32, +@@ -142,26 +146,14 @@ + static _Decimal64 + get_decimal64_min (int negative) + { +- union ieee_double_extract x; +- +- x.s.sig = (negative) ? 1 : 0; +- x.s.exp = 0; +- x.s.manh = 0; +- x.s.manl = 1; +- return x.d; ++ return negative ? - 1E-398dd : 1E-398dd; + } + + /* construct the decimal64 largest finite number with given sign */ + static _Decimal64 + get_decimal64_max (int negative) + { +- union ieee_double_extract x; +- +- x.s.sig = (negative) ? 1 : 0; +- x.s.exp = 1919; +- x.s.manh = 1048575; /* 2^20-1 */ +- x.s.manl = ~0; +- return x.d; ++ return negative ? - DEC64_MAX : DEC64_MAX; + } + + /* one-to-one conversion: +@@ -334,7 +326,8 @@ + /* the largest decimal64 number is just below 10^(385) < 2^1279 */ + else if (MPFR_UNLIKELY (e > 1279)) /* then src >= 2^1279 */ + { +- if (MPFR_RNDZ || (rnd_mode == MPFR_RNDU && negative != 0) ++ if (rnd_mode == MPFR_RNDZ ++ || (rnd_mode == MPFR_RNDU && negative != 0) + || (rnd_mode == MPFR_RNDD && negative == 0)) + return get_decimal64_max (negative); + else +@@ -354,6 +347,15 @@ + which corresponds to s=[0.]1000...000 and e=-397 */ + if (e < -397) + { ++ if (rnd_mode == MPFR_RNDN && e == -398) ++ { ++ /* If 0.5E-398 < |src| < 1E-398 (smallest subnormal), ++ src should round to +/- 1E-398 in MPFR_RNDN. */ ++ mpfr_get_str (s, &e, 10, 1, src, MPFR_RNDA); ++ return e == -398 && s[negative] <= '5' ? ++ get_decimal64_zero (negative) : ++ get_decimal64_min (negative); ++ } + if (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDN + || (rnd_mode == MPFR_RNDD && negative == 0) + || (rnd_mode == MPFR_RNDU && negative != 0)) +@@ -379,7 +381,8 @@ + which corresponds to s=[0.]9999...999 and e=385 */ + else if (e > 385) + { +- if (MPFR_RNDZ || (rnd_mode == MPFR_RNDU && negative != 0) ++ if (rnd_mode == MPFR_RNDZ ++ || (rnd_mode == MPFR_RNDU && negative != 0) + || (rnd_mode == MPFR_RNDD && negative == 0)) + return get_decimal64_max (negative); + else +diff -Naurd mpfr-3.1.1-a/src/mpfr.h mpfr-3.1.1-b/src/mpfr.h +--- mpfr-3.1.1-a/src/mpfr.h 2012-07-03 15:01:19.000000000 +0000 ++++ mpfr-3.1.1-b/src/mpfr.h 2012-08-30 09:28:51.000000000 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 3 + #define MPFR_VERSION_MINOR 1 + #define MPFR_VERSION_PATCHLEVEL 1 +-#define MPFR_VERSION_STRING "3.1.1" ++#define MPFR_VERSION_STRING "3.1.1-p1" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-3.1.1-a/src/version.c mpfr-3.1.1-b/src/version.c +--- mpfr-3.1.1-a/src/version.c 2012-07-03 15:01:18.000000000 +0000 ++++ mpfr-3.1.1-b/src/version.c 2012-08-30 09:28:51.000000000 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "3.1.1"; ++ return "3.1.1-p1"; + } +diff -Naurd mpfr-3.1.1-a/tests/tget_set_d64.c mpfr-3.1.1-b/tests/tget_set_d64.c +--- mpfr-3.1.1-a/tests/tget_set_d64.c 2012-07-03 15:01:24.000000000 +0000 ++++ mpfr-3.1.1-b/tests/tget_set_d64.c 2012-08-30 09:28:51.000000000 +0000 +@@ -25,6 +25,10 @@ + #include /* for exit */ + #include "mpfr-test.h" + ++#ifndef DEC64_MAX ++# define DEC64_MAX 9.999999999999999E384dd ++#endif ++ + /* #define DEBUG */ + + static void +@@ -149,6 +153,15 @@ + mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ); + mpfr_set (y, x, MPFR_RNDZ); + d = mpfr_get_decimal64 (x, MPFR_RNDU); ++ ASSERT_ALWAYS (d == DEC64_MAX); ++ mpfr_set_ui (x, 0, MPFR_RNDZ); ++ mpfr_set_decimal64 (x, d, MPFR_RNDZ); ++ ASSERT_ALWAYS (mpfr_cmp (x, y) == 0); ++ ++ mpfr_set_str (x, "-9.999999999999999E384", 10, MPFR_RNDZ); ++ mpfr_set (y, x, MPFR_RNDZ); ++ d = mpfr_get_decimal64 (x, MPFR_RNDA); ++ ASSERT_ALWAYS (d == -DEC64_MAX); + mpfr_set_ui (x, 0, MPFR_RNDZ); + mpfr_set_decimal64 (x, d, MPFR_RNDZ); + ASSERT_ALWAYS (mpfr_cmp (x, y) == 0); +@@ -225,6 +238,83 @@ + mpfr_clear (x); + } + ++static void ++check_overflow (void) ++{ ++ mpfr_t x; ++ int err = 0, neg, rnd; ++ ++ mpfr_init2 (x, 96); ++ for (neg = 0; neg < 2; neg++) ++ RND_LOOP (rnd) ++ { ++ _Decimal64 d, e; ++ mpfr_rnd_t r = (mpfr_rnd_t) rnd; ++ int sign = neg ? -1 : 1; ++ ++ e = sign * (MPFR_IS_LIKE_RNDZ (r, neg) ? 1 : 2) * DEC64_MAX; ++ /* This tests the binary exponent e > 1279 case of get_d64.c */ ++ mpfr_set_si_2exp (x, sign, 9999, MPFR_RNDN); ++ d = mpfr_get_decimal64 (x, r); ++ if (d != e) ++ { ++ printf ("Error 1 in check_overflow for %s, %s\n", ++ neg ? "negative" : "positive", ++ mpfr_print_rnd_mode (r)); ++ err = 1; ++ } ++ /* This tests the decimal exponent e > 385 case of get_d64.c */ ++ mpfr_set_si_2exp (x, sign * 31, 1274, MPFR_RNDN); ++ d = mpfr_get_decimal64 (x, r); ++ if (d != e) ++ { ++ printf ("Error 2 in check_overflow for %s, %s\n", ++ neg ? "negative" : "positive", ++ mpfr_print_rnd_mode (r)); ++ err = 1; ++ } ++ /* This tests the last else (-382 <= e <= 385) of get_d64.c */ ++ mpfr_set_decimal64 (x, e, MPFR_RNDA); ++ d = mpfr_get_decimal64 (x, r); ++ if (d != e) ++ { ++ printf ("Error 3 in check_overflow for %s, %s\n", ++ neg ? "negative" : "positive", ++ mpfr_print_rnd_mode (r)); ++ err = 1; ++ } ++ } ++ mpfr_clear (x); ++ if (err) ++ exit (1); ++} ++ ++static void ++check_tiny (void) ++{ ++ mpfr_t x; ++ _Decimal64 d; ++ ++ /* If 0.5E-398 < |x| < 1E-398 (smallest subnormal), x should round ++ to +/- 1E-398 in MPFR_RNDN. Note: the midpoint 0.5E-398 between ++ 0 and 1E-398 is not a representable binary number, so that there ++ are no tests for it. */ ++ mpfr_init2 (x, 128); ++ mpfr_set_str (x, "1E-398", 10, MPFR_RNDZ); ++ d = mpfr_get_decimal64 (x, MPFR_RNDN); ++ MPFR_ASSERTN (d == 1.0E-398dd); ++ mpfr_neg (x, x, MPFR_RNDN); ++ d = mpfr_get_decimal64 (x, MPFR_RNDN); ++ MPFR_ASSERTN (d == -1.0E-398dd); ++ mpfr_set_str (x, "0.5E-398", 10, MPFR_RNDU); ++ d = mpfr_get_decimal64 (x, MPFR_RNDN); ++ MPFR_ASSERTN (d == 1.0E-398dd); ++ mpfr_neg (x, x, MPFR_RNDN); ++ d = mpfr_get_decimal64 (x, MPFR_RNDN); ++ MPFR_ASSERTN (d == -1.0E-398dd); ++ mpfr_clear (x); ++} ++ + int + main (void) + { +@@ -241,6 +331,8 @@ + check_inf_nan (); + check_random (); + check_native (); ++ check_overflow (); ++ check_tiny (); + + tests_end_mpfr (); + return 0; +diff -Naurd mpfr-3.1.1-a/PATCHES mpfr-3.1.1-b/PATCHES +--- mpfr-3.1.1-a/PATCHES 2012-08-30 09:35:12.000000000 +0000 ++++ mpfr-3.1.1-b/PATCHES 2012-08-30 09:35:12.000000000 +0000 +@@ -0,0 +1 @@ ++strtofr-ternary-value +diff -Naurd mpfr-3.1.1-a/VERSION mpfr-3.1.1-b/VERSION +--- mpfr-3.1.1-a/VERSION 2012-08-30 09:28:51.000000000 +0000 ++++ mpfr-3.1.1-b/VERSION 2012-08-30 09:35:12.000000000 +0000 +@@ -1 +1 @@ +-3.1.1-p1 ++3.1.1-p2 +diff -Naurd mpfr-3.1.1-a/src/mpfr.h mpfr-3.1.1-b/src/mpfr.h +--- mpfr-3.1.1-a/src/mpfr.h 2012-08-30 09:28:51.000000000 +0000 ++++ mpfr-3.1.1-b/src/mpfr.h 2012-08-30 09:35:12.000000000 +0000 +@@ -27,7 +27,7 @@ + #define MPFR_VERSION_MAJOR 3 + #define MPFR_VERSION_MINOR 1 + #define MPFR_VERSION_PATCHLEVEL 1 +-#define MPFR_VERSION_STRING "3.1.1-p1" ++#define MPFR_VERSION_STRING "3.1.1-p2" + + /* Macros dealing with MPFR VERSION */ + #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c)) +diff -Naurd mpfr-3.1.1-a/src/strtofr.c mpfr-3.1.1-b/src/strtofr.c +--- mpfr-3.1.1-a/src/strtofr.c 2012-07-03 15:01:16.000000000 +0000 ++++ mpfr-3.1.1-b/src/strtofr.c 2012-08-30 09:35:12.000000000 +0000 +@@ -667,6 +667,20 @@ + /* (z, exp_z) = base^(exp_base-pstr_size) */ + z = result + 2*ysize + 1; + err = mpfr_mpn_exp (z, &exp_z, pstr->base, exp_z, ysize); ++ /* Since we want y/z rounded toward zero, we must get an upper ++ bound of z. If err >= 0, the error on z is bounded by 2^err. */ ++ if (err >= 0) ++ { ++ mp_limb_t cy; ++ unsigned long h = err / GMP_NUMB_BITS; ++ unsigned long l = err - h * GMP_NUMB_BITS; ++ ++ if (h >= ysize) /* not enough precision in z */ ++ goto next_loop; ++ cy = mpn_add_1 (z, z, ysize - h, MPFR_LIMB_ONE << l); ++ if (cy != 0) /* the code below requires z on ysize limbs */ ++ goto next_loop; ++ } + exact = exact && (err == -1); + if (err == -2) + goto underflow; /* FIXME: Sure? */ +@@ -730,6 +744,7 @@ + MPFR_RNDN, rnd, MPFR_PREC(x))) + break; + ++ next_loop: + /* update the prec for next loop */ + MPFR_ZIV_NEXT (loop, prec); + } /* loop */ +diff -Naurd mpfr-3.1.1-a/src/version.c mpfr-3.1.1-b/src/version.c +--- mpfr-3.1.1-a/src/version.c 2012-08-30 09:28:51.000000000 +0000 ++++ mpfr-3.1.1-b/src/version.c 2012-08-30 09:35:12.000000000 +0000 +@@ -25,5 +25,5 @@ + const char * + mpfr_get_version (void) + { +- return "3.1.1-p1"; ++ return "3.1.1-p2"; + } +diff -Naurd mpfr-3.1.1-a/tests/tstrtofr.c mpfr-3.1.1-b/tests/tstrtofr.c +--- mpfr-3.1.1-a/tests/tstrtofr.c 2012-07-03 15:01:24.000000000 +0000 ++++ mpfr-3.1.1-b/tests/tstrtofr.c 2012-08-30 09:35:12.000000000 +0000 +@@ -1105,6 +1105,92 @@ + mpfr_clear (y); + } + ++/* From a bug reported by Joseph S. Myers ++ https://sympa.inria.fr/sympa/arc/mpfr/2012-08/msg00005.html */ ++static void ++bug20120814 (void) ++{ ++ mpfr_exp_t emin = -30, e; ++ mpfr_t x, y; ++ int r; ++ char s[64], *p; ++ ++ mpfr_init2 (x, 2); ++ mpfr_set_ui_2exp (x, 3, emin - 2, MPFR_RNDN); ++ mpfr_get_str (s + 1, &e, 10, 19, x, MPFR_RNDD); ++ s[0] = s[1]; ++ s[1] = '.'; ++ for (p = s; *p != 0; p++) ; ++ *p = 'e'; ++ sprintf (p + 1, "%d", (int) e - 1); ++ ++ mpfr_init2 (y, 4); ++ r = mpfr_strtofr (y, s, NULL, 0, MPFR_RNDN); ++ if (r <= 0 || ! mpfr_equal_p (x, y)) ++ { ++ printf ("Error in bug20120814\n"); ++ printf ("mpfr_strtofr failed on string \"%s\"\n", s); ++ printf ("Expected inex > 0 and y = 0.1100E%d\n", (int) emin); ++ printf ("Got inex = %-6d and y = ", r); ++ mpfr_dump (y); ++ exit (1); ++ } ++ ++ mpfr_clear (x); ++ mpfr_clear (y); ++} ++ ++static void ++bug20120829 (void) ++{ ++ mpfr_t x1, x2, e; ++ int inex1, inex2, i, r; ++ char s[48] = "1e-1"; ++ ++ mpfr_init2 (e, 128); ++ mpfr_inits2 (4, x1, x2, (mpfr_ptr) 0); ++ ++ inex1 = mpfr_set_si (e, -1, MPFR_RNDN); ++ MPFR_ASSERTN (inex1 == 0); ++ ++ for (i = 1; i <= sizeof(s) - 5; i++) ++ { ++ s[3+i] = '0'; ++ s[4+i] = 0; ++ inex1 = mpfr_mul_ui (e, e, 10, MPFR_RNDN); ++ MPFR_ASSERTN (inex1 == 0); ++ RND_LOOP(r) ++ { ++ mpfr_rnd_t rnd = (mpfr_rnd_t) r; ++ ++ inex1 = mpfr_exp10 (x1, e, rnd); ++ inex1 = SIGN (inex1); ++ inex2 = mpfr_strtofr (x2, s, NULL, 0, rnd); ++ inex2 = SIGN (inex2); ++ /* On 32-bit machines, for i = 7, r8389, r8391 and r8394 do: ++ strtofr.c:...: MPFR assertion failed: cy == 0 ++ r8396 is OK. ++ On 64-bit machines, for i = 15, ++ r8389 does: strtofr.c:678: MPFR assertion failed: err < (64 - 0) ++ r8391 does: strtofr.c:680: MPFR assertion failed: h < ysize ++ r8394 and r8396 are OK. ++ */ ++ if (! mpfr_equal_p (x1, x2) || inex1 != inex2) ++ { ++ printf ("Error in bug20120829 for i = %d, rnd = %s\n", ++ i, mpfr_print_rnd_mode (rnd)); ++ printf ("Expected inex = %d, x = ", inex1); ++ mpfr_dump (x1); ++ printf ("Got inex = %d, x = ", inex2); ++ mpfr_dump (x2); ++ exit (1); ++ } ++ } ++ } ++ ++ mpfr_clears (e, x1, x2, (mpfr_ptr) 0); ++} ++ + int + main (int argc, char *argv[]) + { +@@ -1117,6 +1203,8 @@ + check_retval (); + bug20081028 (); + test20100310 (); ++ bug20120814 (); ++ bug20120829 (); + + tests_end_mpfr (); + return 0; diff --git a/packages/tools/bcm2835-bootloader/meta b/packages/tools/bcm2835-bootloader/meta index 26fb98d3b7..3812d54d5f 100644 --- a/packages/tools/bcm2835-bootloader/meta +++ b/packages/tools/bcm2835-bootloader/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="bcm2835-bootloader" -PKG_VERSION="f20e9d7" +PKG_VERSION="2997db1" PKG_REV="1" PKG_ARCH="arm" PKG_LICENSE="nonfree" diff --git a/packages/web/curl/build b/packages/web/curl/build index fb02e7adf9..dd561619bc 100755 --- a/packages/web/curl/build +++ b/packages/web/curl/build @@ -23,7 +23,7 @@ . config/options $1 # link against librt because of undefined reference to 'clock_gettime' - LDFLAGS="$LDFLAGS -lrt -lrtmp" + LDFLAGS="$LDFLAGS -lrt -lm -lrtmp" cd $PKG_BUILD ac_cv_lib_rtmp_RTMP_Init=yes \ @@ -69,12 +69,12 @@ ac_cv_header_librtmp_rtmp_h=yes \ --without-krb4 \ --without-spnego \ --without-gssapi \ - --with-ssl \ --with-zlib \ --without-egd-socket \ --enable-thread \ --with-random=/dev/urandom \ - --without-gnutls \ + --with-gnutls="$SYSROOT_PREFIX/usr" \ + --without-ssl \ --without-polarssl \ --without-nss \ --with-ca-bundle="$SSL_CERTIFICATES/cacert.pem" \ diff --git a/packages/web/curl/meta b/packages/web/curl/meta index c3a2a7aa03..4a9197162d 100644 --- a/packages/web/curl/meta +++ b/packages/web/curl/meta @@ -25,8 +25,8 @@ PKG_ARCH="any" PKG_LICENSE="MIT" PKG_SITE="http://curl.haxx.se" PKG_URL="http://curl.haxx.se/download/$PKG_NAME-$PKG_VERSION.tar.bz2" -PKG_DEPENDS="zlib openssl rtmpdump" -PKG_BUILD_DEPENDS="toolchain zlib openssl rtmpdump" +PKG_DEPENDS="zlib gnutls rtmpdump" +PKG_BUILD_DEPENDS="toolchain zlib gnutls rtmpdump" PKG_PRIORITY="optional" PKG_SECTION="web" PKG_SHORTDESC="curl: Client and library for (HTTP, HTTPS, FTP, ...) transfers" diff --git a/packages/web/curl/patches/curl-7.27.0-04_workaround_as_needed_bug.patch b/packages/web/curl/patches/curl-7.27.0-04_workaround_as_needed_bug.patch new file mode 100644 index 0000000000..46a397668f --- /dev/null +++ b/packages/web/curl/patches/curl-7.27.0-04_workaround_as_needed_bug.patch @@ -0,0 +1,38 @@ +Description: Work around libtool --as-needed reordering bug +Origin: vendor +Bug-Debian: http://bugs.debian.org/347650 +Forwarded: not-needed +Author: Alessandro Ghedini +Reviewed-by: Alessandro Ghedini +Last-Update: 2013-03-22 + +--- a/ltmain.sh ++++ b/ltmain.sh +@@ -5800,6 +5800,11 @@ + arg=$func_stripname_result + ;; + ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ deplibs="$deplibs $arg" ++ continue ++ ;; ++ + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result +@@ -6163,6 +6168,15 @@ + lib= + found=no + case $deplib in ++ -Wl,--as-needed|-Wl,--no-as-needed) ++ if test "$linkmode,$pass" = "prog,link"; then ++ compile_deplibs="$deplib $compile_deplibs" ++ finalize_deplibs="$deplib $finalize_deplibs" ++ else ++ deplibs="$deplib $deplibs" ++ fi ++ continue ++ ;; + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test "$linkmode,$pass" = "prog,link"; then diff --git a/packages/web/curl/patches/curl-7.27.0-gtls-fix-build-failure-by-including-nettle-specific.patch b/packages/web/curl/patches/curl-7.27.0-gtls-fix-build-failure-by-including-nettle-specific.patch new file mode 100644 index 0000000000..b0a81657fd --- /dev/null +++ b/packages/web/curl/patches/curl-7.27.0-gtls-fix-build-failure-by-including-nettle-specific.patch @@ -0,0 +1,30 @@ +From 986c7949c0638bebb99bd08d63216433254c2185 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 6 Aug 2012 15:04:25 +0200 +Subject: [PATCH] gtls: fix build failure by including nettle-specific headers + +Bug: http://curl.haxx.se/bug/view.cgi?id=3554668 +Reported by: Anthony G. Basile +--- + lib/gtls.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/lib/gtls.c b/lib/gtls.c +index d981ef1..c750a6f 100644 +--- a/lib/gtls.c ++++ b/lib/gtls.c +@@ -34,7 +34,10 @@ + + #include + #include +-#ifndef USE_GNUTLS_NETTLE ++#ifdef USE_GNUTLS_NETTLE ++#include ++#include ++#else + #include + #endif + +-- +1.7.10.4 + diff --git a/packages/web/curl/patches/curl-7.27.0-metalink-change-code-order-to-build-with-gnutls-nettle.patch b/packages/web/curl/patches/curl-7.27.0-metalink-change-code-order-to-build-with-gnutls-nettle.patch new file mode 100644 index 0000000000..7cbd98b1a7 --- /dev/null +++ b/packages/web/curl/patches/curl-7.27.0-metalink-change-code-order-to-build-with-gnutls-nettle.patch @@ -0,0 +1,148 @@ +From 9f304291bd72aae66944cd7523707e1b88c6ad7b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 6 Aug 2012 19:20:35 +0200 +Subject: [PATCH] metalink: change code order to build with gnutls-nettle + +Bug: http://curl.haxx.se/bug/view.cgi?id=3554668 +Reported by: Anthony G. Basile +--- + src/tool_metalink.c | 116 +++++++++++++++++++++++++-------------------------- + 1 file changed, 58 insertions(+), 58 deletions(-) + +diff --git a/src/tool_metalink.c b/src/tool_metalink.c +index 5491815..3a24a15 100644 +--- a/src/tool_metalink.c ++++ b/src/tool_metalink.c +@@ -82,64 +82,6 @@ + return PARAM_NO_MEM; \ + } WHILE_FALSE + +-const digest_params MD5_DIGEST_PARAMS[] = { +- { +- (Curl_digest_init_func) MD5_Init, +- (Curl_digest_update_func) MD5_Update, +- (Curl_digest_final_func) MD5_Final, +- sizeof(MD5_CTX), +- 16 +- } +-}; +- +-const digest_params SHA1_DIGEST_PARAMS[] = { +- { +- (Curl_digest_init_func) SHA1_Init, +- (Curl_digest_update_func) SHA1_Update, +- (Curl_digest_final_func) SHA1_Final, +- sizeof(SHA_CTX), +- 20 +- } +-}; +- +-const digest_params SHA256_DIGEST_PARAMS[] = { +- { +- (Curl_digest_init_func) SHA256_Init, +- (Curl_digest_update_func) SHA256_Update, +- (Curl_digest_final_func) SHA256_Final, +- sizeof(SHA256_CTX), +- 32 +- } +-}; +- +-static const metalink_digest_def SHA256_DIGEST_DEF[] = { +- {"sha-256", SHA256_DIGEST_PARAMS} +-}; +- +-static const metalink_digest_def SHA1_DIGEST_DEF[] = { +- {"sha-1", SHA1_DIGEST_PARAMS} +-}; +- +-static const metalink_digest_def MD5_DIGEST_DEF[] = { +- {"md5", MD5_DIGEST_PARAMS} +-}; +- +-/* +- * The alias of supported hash functions in the order by preference +- * (basically stronger hash comes first). We included "sha-256" and +- * "sha256". The former is the name defined in the IANA registry named +- * "Hash Function Textual Names". The latter is widely (and +- * historically) used in Metalink version 3. +- */ +-static const metalink_digest_alias digest_aliases[] = { +- {"sha-256", SHA256_DIGEST_DEF}, +- {"sha256", SHA256_DIGEST_DEF}, +- {"sha-1", SHA1_DIGEST_DEF}, +- {"sha1", SHA1_DIGEST_DEF}, +- {"md5", MD5_DIGEST_DEF}, +- {NULL, NULL} +-}; +- + #ifdef USE_GNUTLS_NETTLE + + static void MD5_Init(MD5_CTX *ctx) +@@ -251,6 +193,64 @@ static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx) + + #endif /* CRYPTO LIBS */ + ++const digest_params MD5_DIGEST_PARAMS[] = { ++ { ++ (Curl_digest_init_func) MD5_Init, ++ (Curl_digest_update_func) MD5_Update, ++ (Curl_digest_final_func) MD5_Final, ++ sizeof(MD5_CTX), ++ 16 ++ } ++}; ++ ++const digest_params SHA1_DIGEST_PARAMS[] = { ++ { ++ (Curl_digest_init_func) SHA1_Init, ++ (Curl_digest_update_func) SHA1_Update, ++ (Curl_digest_final_func) SHA1_Final, ++ sizeof(SHA_CTX), ++ 20 ++ } ++}; ++ ++const digest_params SHA256_DIGEST_PARAMS[] = { ++ { ++ (Curl_digest_init_func) SHA256_Init, ++ (Curl_digest_update_func) SHA256_Update, ++ (Curl_digest_final_func) SHA256_Final, ++ sizeof(SHA256_CTX), ++ 32 ++ } ++}; ++ ++static const metalink_digest_def SHA256_DIGEST_DEF[] = { ++ {"sha-256", SHA256_DIGEST_PARAMS} ++}; ++ ++static const metalink_digest_def SHA1_DIGEST_DEF[] = { ++ {"sha-1", SHA1_DIGEST_PARAMS} ++}; ++ ++static const metalink_digest_def MD5_DIGEST_DEF[] = { ++ {"md5", MD5_DIGEST_PARAMS} ++}; ++ ++/* ++ * The alias of supported hash functions in the order by preference ++ * (basically stronger hash comes first). We included "sha-256" and ++ * "sha256". The former is the name defined in the IANA registry named ++ * "Hash Function Textual Names". The latter is widely (and ++ * historically) used in Metalink version 3. ++ */ ++static const metalink_digest_alias digest_aliases[] = { ++ {"sha-256", SHA256_DIGEST_DEF}, ++ {"sha256", SHA256_DIGEST_DEF}, ++ {"sha-1", SHA1_DIGEST_DEF}, ++ {"sha1", SHA1_DIGEST_DEF}, ++ {"md5", MD5_DIGEST_DEF}, ++ {NULL, NULL} ++}; ++ + digest_context *Curl_digest_init(const digest_params *dparams) + { + digest_context *ctxt; +-- +1.7.10.4 + diff --git a/packages/x11/driver/xf86-video-intel/meta b/packages/x11/driver/xf86-video-intel/meta index 13b8aa9603..9db5c797ff 100644 --- a/packages/x11/driver/xf86-video-intel/meta +++ b/packages/x11/driver/xf86-video-intel/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xf86-video-intel" -PKG_VERSION="2.20.6" +PKG_VERSION="2.20.8" PKG_REV="1" PKG_ARCH="i386 x86_64" PKG_LICENSE="OSS" diff --git a/packages/x11/xserver/xorg-server/build b/packages/x11/xserver/xorg-server/build index 3065a91938..152c9da6d6 100755 --- a/packages/x11/xserver/xorg-server/build +++ b/packages/x11/xserver/xorg-server/build @@ -121,7 +121,7 @@ cd $PKG_BUILD --with-int10=x86emu \ --disable-ipv6 \ --with-gnu-ld \ - --with-sha1=libcrypto \ + --with-sha1=libgcrypt \ --with-os-vendor="OpenELEC.tv" \ --with-module-dir=$XORG_PATH_MODULES \ --with-xkb-path=$XORG_PATH_XKB \ diff --git a/packages/x11/xserver/xorg-server/meta b/packages/x11/xserver/xorg-server/meta index da38761fad..d29efb713e 100644 --- a/packages/x11/xserver/xorg-server/meta +++ b/packages/x11/xserver/xorg-server/meta @@ -25,8 +25,8 @@ PKG_ARCH="any" PKG_LICENSE="OSS" PKG_SITE="http://www.X.org" PKG_URL="http://xorg.freedesktop.org/archive/individual/xserver/$PKG_NAME-$PKG_VERSION.tar.bz2" -PKG_DEPENDS="libpciaccess libX11 libXfont libdrm openssl freetype pixman systemd" -PKG_BUILD_DEPENDS="toolchain util-macros font-util fontsproto randrproto recordproto renderproto dri2proto fixesproto damageproto scrnsaverproto videoproto inputproto xf86dgaproto xf86vidmodeproto xf86driproto xf86miscproto glproto libpciaccess libX11 libXfont libxkbfile libdrm openssl freetype pixman fontsproto systemd" +PKG_DEPENDS="libpciaccess libX11 libXfont libdrm libgcrypt freetype pixman systemd" +PKG_BUILD_DEPENDS="toolchain util-macros font-util fontsproto randrproto recordproto renderproto dri2proto fixesproto damageproto scrnsaverproto videoproto inputproto xf86dgaproto xf86vidmodeproto xf86driproto xf86miscproto glproto libpciaccess libX11 libXfont libxkbfile libdrm libgcrypt freetype pixman fontsproto systemd" PKG_PRIORITY="optional" PKG_SECTION="x11/xserver" PKG_SHORTDESC="xorg-server: The Xorg X server" diff --git a/projects/RPi/linux/linux.arm.conf b/projects/RPi/linux/linux.arm.conf index 6a6c803c57..34a8803248 100644 --- a/projects/RPi/linux/linux.arm.conf +++ b/projects/RPi/linux/linux.arm.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 3.2.28 Kernel Configuration +# Linux/arm 3.2.29 Kernel Configuration # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -1293,13 +1293,10 @@ CONFIG_VIDEO_PVRUSB2_DVB=y # CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set # CONFIG_VIDEO_HDPVR is not set CONFIG_VIDEO_EM28XX=m -CONFIG_VIDEO_EM28XX_ALSA=m CONFIG_VIDEO_EM28XX_DVB=m CONFIG_VIDEO_EM28XX_RC=y -# CONFIG_VIDEO_TLG2300 is not set # CONFIG_VIDEO_CX231XX is not set CONFIG_VIDEO_TM6000=m -CONFIG_VIDEO_TM6000_ALSA=m CONFIG_VIDEO_TM6000_DVB=m # CONFIG_VIDEO_USBVISION is not set # CONFIG_USB_ET61X251 is not set @@ -1523,38 +1520,7 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y # CONFIG_LOGO is not set -CONFIG_SOUND=y -# CONFIG_SOUND_OSS_CORE is not set -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -CONFIG_SND_HWDEP=m -CONFIG_SND_RAWMIDI=m -# CONFIG_SND_SEQUENCER is not set -# CONFIG_SND_MIXER_OSS is not set -# CONFIG_SND_PCM_OSS is not set -CONFIG_SND_HRTIMER=y -# CONFIG_SND_DYNAMIC_MINORS is not set -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_VERBOSE_PROCFS is not set -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set -# CONFIG_SND_RAWMIDI_SEQ is not set -# CONFIG_SND_OPL3_LIB_SEQ is not set -# CONFIG_SND_OPL4_LIB_SEQ is not set -# CONFIG_SND_SBAWE_SEQ is not set -# CONFIG_SND_EMU10K1_SEQ is not set -# CONFIG_SND_DRIVERS is not set -CONFIG_SND_ARM=y -# CONFIG_SND_ARMAACI is not set -CONFIG_SND_BCM2835=y -CONFIG_SND_USB=y -CONFIG_SND_USB_AUDIO=m -# CONFIG_SND_USB_UA101 is not set -# CONFIG_SND_USB_CAIAQ is not set -# CONFIG_SND_USB_6FIRE is not set -# CONFIG_SND_SOC is not set -# CONFIG_SOUND_PRIME is not set +# CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y CONFIG_HIDRAW=y @@ -1576,7 +1542,6 @@ CONFIG_HID_AUREAL=y CONFIG_HID_BELKIN=y CONFIG_HID_CHERRY=y CONFIG_HID_CHICONY=y -# CONFIG_HID_PRODIKEYS is not set CONFIG_HID_CYPRESS=y # CONFIG_HID_DRAGONRISE is not set # CONFIG_HID_EMS_FF is not set @@ -1864,7 +1829,6 @@ CONFIG_R8712U=m # CONFIG_RTS5139 is not set # CONFIG_TRANZPORT is not set # CONFIG_POHMELFS is not set -# CONFIG_LINE6_USB is not set # CONFIG_USB_SERIAL_QUATECH2 is not set # CONFIG_USB_SERIAL_QUATECH_USB2 is not set CONFIG_VT6656=m @@ -1886,7 +1850,6 @@ CONFIG_ZCACHE=y # CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set CONFIG_STAGING_MEDIA=y CONFIG_DVB_AS102=m -# CONFIG_EASYCAP is not set CONFIG_LIRC_STAGING=y CONFIG_LIRC_IGORPLUGUSB=y # CONFIG_LIRC_IMON is not set diff --git a/projects/RPi/options b/projects/RPi/options index 5af716703b..77c2726c34 100755 --- a/projects/RPi/options +++ b/projects/RPi/options @@ -139,7 +139,7 @@ XBMC_VIS_GOOM="no" # build and install ALSA Audio support (yes / no) - ALSA_SUPPORT="yes" + ALSA_SUPPORT="no" # build and install PulseAudio support (yes / no) PULSEAUDIO_SUPPORT="no" diff --git a/projects/RPi/xbmc/advancedsettings.xml b/projects/RPi/xbmc/advancedsettings.xml index 1e1412aa4e..abc74fa1ab 100644 --- a/projects/RPi/xbmc/advancedsettings.xml +++ b/projects/RPi/xbmc/advancedsettings.xml @@ -12,12 +12,6 @@ 2 true - - 3 - 0 - off - - 5282880