In the firmware of most xDSL modems is a large program file called a hardware driver BLOB (Binary Large OBject). Many hundreds of kilobytes in size, it contains the digital signal processing software. This software manages the xDSL hardware: the modem transceiver, comprising the analog frontend and the line driver.
The Huawei hardware driver blob is a proprietary piece of Broadcom software. There is no publicly available source code. The Broadcom BCM6368 microprocessor in the Huawei has two cores. And the blob is loaded by the control (Linux) core into the shared address space of the second core of the BCM6368. The second core then executes that code, to control the DSL line driver. And some form of inter-process messaging takes place between the two cores.
We can swap out that hardware blob for another blob version. We have already extracted a newer blob version from the Netgear DGND3700, a device running on the same 6368 platform as the Huawei. 
That newer driver blob can be downloaded to the Huawei by one of at least four methods: ftp, tftp, http, or the telnet upload trick.
The simplest of those four methods is tftp, the (trivial) file transfer protocol. By default tftpd, the tftp daemon (i.e. the server) uses no authentication.
In debian and ubuntu there are several flavours of tftpd, the simplest being tftp-hpa.  It is an extension of the openBSD tftpd. A one-liner installs and configures it:
$ sudo apt-get install tftpd-hpa
From ps we can see (at least on this box) that files hosted by tftpd are stored under /srv/tftp:
$ ps auxw | grep [t]ftpd root 19331 0.0 0.0 14844 324 ? Ss 16:29 0:00 /usr/sbin/in.tftpd --listen --user tftp --address 0.0.0.0:69 --secure /srv/tftp
And that is where we will place our new driver blob, ready to upload to the HG612:
$ ls -l /srv/tftp/ total 828 -rw-r--r-- 1 root root 846560 Nov 11 17:29 adsl_phy.A2pv6C035m.bin
Now we log into the Huawei from the PC:
$ telnet 192.168.1.2 Welcome Visiting Huawei Home Gateway Copyright by Huawei Technologies Co., Ltd. Login:admin Password:admin ATP>sh BusyBox v1.9.1 (2010-10-15 17:59:06 CST) built-in shell (ash) Enter 'help' for a list of built-in commands.
The contents of read-only /etc are copied into /tmp
# cp -ar /etc /tmp
The original xDSL driver is renamed to preserve it from over-writing during our tests:
# cd /tmp/etc/adsl # mv adsl_phy.bin adsl_phy.A2pv6C030b.bin
Now we retrieve the newer xDSL driver blob from the tftpd server on the PC:
# tftp -g -r adsl_phy.A2pv6C035m.bin 192.168.1.3 # (adjust for your PC's IP address)
We now have two driver blobs in /tmp/etc/adsl, one old, one new:
# ls -l /tmp/etc/adsl/ -rw-rw-r-- 1 0 0 813980 adsl_phy.A2pv6C030b.bin -rw-r--r-- 1 0 0 846560 adsl_phy.A2pv6C035m.bin
We create a symlink to the newer blob, ready for its loading:
# ln -sfn adsl_phy.A2pv6C035m.bin adsl_phy.bin
Now the /tmp mountpoint is mounted over the top of the (read-only) /etc mountpoint:
# mount -o bind /tmp/etc /etc
Here we see that original hardware driver is still running (A2pv6C030b.d22g):
# xdslcmd --version xdslcmd version 1.0 DSL PHY: AnnexA version - A2pv6C030b.d22g ******* Pass ********* #
And here is the current performance of that original driver on this 1000 metre ADSL2+ line:
# xdslcmd info --state xdslcmd: ADSL driver and PHY status Status: Showtime Retrain Reason: 8000 Max: Upstream rate = 1184 Kbps, Downstream rate = 19488 Kbps Path: 0, Upstream rate = 1020 Kbps, Downstream rate = 17659 Kbps #
Now the xdsl driver is stopped and re-started, causing the (symlinked) new blob (A2pv6C035m) to be loaded and executed by the second core:
# xdslcmd stop # xdslcmd start --up xdslCtl_GetVersion success
We can confirm that the new driver blob has been loaded:
# xdslcmd --version xdslcmd version 1.0 DSL PHY: AnnexA version - A2pv6C035m.d22g ******* Pass ********* #
And… drum roll………..
# xdslcmd info --state xdslcmd: ADSL driver and PHY status Status: Showtime Retrain Reason: 8000 Max: Upstream rate = 1248 Kbps, Downstream rate = 19540 Kbps Path: 0, Upstream rate = 1020 Kbps, Downstream rate = 17585 Kbps #
The new blob has essentially the same performance as the old one!
But maybe if we down-tweak the target SNR margin (TSNRM) it might hold on at a higher sync rate than the older blob:
Benchmarking first that newer blob with a lower TSNRM:
# xdslcmd start --snr 25 # xdslcmd info --state xdslcmd: ADSL driver and PHY status Status: Showtime Retrain Reason: 8000 Max: Upstream rate = 1244 Kbps, Downstream rate = 22308 Kbps Path: 0, Upstream rate = 1020 Kbps, Downstream rate = 20474 Kbps #
Now if we swap back to the old driver blob (A2pv6C030b) we can compare that driver to see how it also performs at 25% of the target SNRM (6.0dB):
# ln -sfn /etc/adsl/adsl_phy.A2pv6C030b.bin adsl_phy.bin # xdslcmd stop # xdslcmd start --up --snr 25 xdslCtl_GetVersion success # xdslcmd --version xdslcmd version 1.0 DSL PHY: AnnexA version - A2pv6C030b.d22g ******* Pass ********* #
And for the performance comparison, we find:
# xdslcmd info --state xdslcmd: ADSL driver and PHY status Status: Showtime Retrain Reason: 8000 Max: Upstream rate = 1184 Kbps, Downstream rate = 22296 Kbps Path: 0, Upstream rate = 1020 Kbps, Downstream rate = 20502 Kbps #
EDIT: after running a few more tests, the new driver does appear to have almost identical performance to the original driver!
However, nothing should be read into these tests since they are anything but scientific. Ideally Dynamic Line Management at the DSLAM would be disabled, and line noise and attenuation would be closely controlled under laboratory conditions.
The blob-swapping measures documented above are, fortunately, transient. When the router is rebooted, everything goes back to its original state.
If, however, it was decided to permanently swap-out the driver blob for a different one, that would involve re-making a squashfs root file system, and re-building the entire firmware complete with the kernel image, before flashing in the whole she-bang.
All the tools to perform that permanent change, including a script for automation, are found here