This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 2.x development tree".
The branch, next has been updated via 06f451c0beaba72872fa7ab81a043eb92a3f63ee (commit) via 15b470a79da5c3fa119920e051386421a3fa317f (commit) via fe53fa8dac070d884e05aa423ec5c854a8997fbd (commit) via 80159102fcddef6db3c778ebf1f080ebde5504c6 (commit) via a1f369eb1ee97edad4b81518649fd8672763e252 (commit) via 02dba6c6cb654567639764332f8b0a24474badb3 (commit) via 5ab875af711f98f02cead4688a4f76958d9ff894 (commit) via 98a5192ef2f3cde9b9c6867f69f3a400f3c62ec5 (commit) via fe0c6a624e2265c22d70f64124c0751e2d7fa755 (commit) via 35086a2db41f8c5a44f69392c4d87880c391176e (commit) via c0bf6eadf05d7f91cf52271a9b6b39a0bbca5871 (commit) via fb90bce89b8523882c779395f59245290c43c592 (commit) via 08e5991c3628df34566cc939bd07061418d5376f (commit) via f0dd06542596fa14cb0ef3bbaeb3ae16ee78c325 (commit) via 8e23b35195bd004c64bb83b45d4358488a2dc67e (commit) via 97c73abc88358e084af84500ad1cbff649d4f2a0 (commit) via 2bb836df110ec8c7e30fc93ca638f445dd586fd2 (commit) via 864a8efff39035ac7ab7c667b0d5821285c7db43 (commit) via c3408c01a14491e7e6eb4937863afe18d208ec05 (commit) via ba2a22487ae87281a33805827ec174d87b04c3fe (commit) via 82bcc200c778abc6c6b9bc7716c33d4a58e8ffa6 (commit) via 33e2ee618b3abcd0f71c102702197188f5334e65 (commit) via 3bb9a745b549da26be3607724212da3e202763a1 (commit) via 95ef7be8dfd4c18ffa419bac6eeb3b0e4ea414e1 (commit) via 9692499b2a87f1bdcebd8e1fd8e4f40084c898ba (commit) via 7db3e17a4aa5cd7e8b1b9e1e9e53495aafa169ca (commit) via 214cc7b19528774eebc43e82d9c94c5e4592bc39 (commit) via d840d02aee26d2f71b9d411b1960eb5b2423b19a (commit) via a91fd50d80dffb610cc2a6d5d31a9ee1b6a0d37d (commit) via facf38edd1be5eac58db1e9b5e174e4f6bc095a7 (commit) via 132557976f619a6c9b361442d5c4993eee588cc2 (commit) via 218d2d75f5b47bcfe92b98fb888edb690aa9eeae (commit) via 764bedefb3d8d7085a0c623290541a5b62e1ec13 (commit) via 95f4218ed73fdeeff182bea847be32b5b85808ac (commit) via 5946f1f9d0cc021b6db9f5127cdc46d7123cbdf1 (commit) via 91e56a59a4adc968b3fed8a95a9a3f569230f145 (commit) via 4d7f5ead1657438247e1f0ce378e259cc04aef48 (commit) via 7fae88972f04acde0f011ebc1dbfbed35e522536 (commit) via 66c684fa60c4ad2a6333d4bb41196c636c4748de (commit) via 0d87efae29c14dedbd1e7623ba7b9e968bec040b (commit) via 8cc7ba902092e8b49da402afa09fcaa3990387fd (commit) via 7168162ef13be445996ff2f65d12e5643ef0f2b2 (commit) via b097fdd66fa7e1c2252171016bfbcfa40bb2f140 (commit) via 75f3abe29d048b3e4096c28ef1ce32121fe69795 (commit) via 81f315bff2e161073c12733a01a635b22e97f89f (commit) via 7d8965e2cb0b3ca2868f01f814cf0018dc721f15 (commit) via 22e166064029944a4da45667f4c3ae86cf4a50bc (commit) via d77dfa7342c593dd4913dc3cec3219cc39032eca (commit) via 6cda03e8316751061b64ba9f1c39f72a13e78818 (commit) via 15094e71e68dd3f96d61bf62aa9c0f7d170bf787 (commit) via 56e211f66eda13d263a9aa4e2aa81c2cfd1bb50f (commit) via 9894fb91f18a11fc7ef6c7032cff7dc897189a92 (commit) via ff3bae7b8974808300078a7be3b46852860e4d9b (commit) via bbf2fe890270c79b494a6ccb9e5a22012585b5ba (commit) via b70a4d5267bf2d0da19315c4c176031fd265bae2 (commit) via 2b94001c485851543eaf6c718422a1cbf805ca11 (commit) via 9982e01913d0c098a2a184b84a8f4f8137166ecf (commit) via bbdd37b1d57992649cfc1edac2f761ae2c520afb (commit) via 4d84d320a84591976f92a4ae343b8ffee26de6c7 (commit) via e71475c13afeef652ae94a545978e354e21eb03e (commit) via 32787fb0dff053a4a31f9785ddb3f40e1d6a6063 (commit) via 0c5dcca2eeb2aea50fd52ce411c4255c4cc2b942 (commit) via 7370484e87052bfc6f9e146d925adab203f1cea0 (commit) via d5ea5e366c52830d4e54b89309340674fc518af2 (commit) via a61bfd61b292b28660539c8214a1edcf90d22db3 (commit) via 07562a76208386065c56386b3a77f44137d16c2f (commit) via 5ae99dd2d1ed307959f25143e6c343a53e4df373 (commit) via 7ce49ff07440e404959149820e507f79d7c839da (commit) via c6ede545fdfbc12c10a3a66a3ea76a45e2d39ef4 (commit) via a1f23a84c7c5b60bf87b30a19451214e59793b9a (commit) via 9ac9fc3d802db666b94cc85175bef2cfbd335ed5 (commit) via 57865e53f70b234f2b1f1be07ed8ca8ef091664b (commit) via e0eeb8a6176ab672b9dd3b3ce93f689e9a2881c3 (commit) via 2407ace4946f1c0af6c43e6139337b76bfabaa7f (commit) via bd34e32e4b2ce637845cb7e7e8a2c8ede1dffe83 (commit) via 1fbd7376b71e7a9affcb41ea7948af66df6ac94f (commit) via 6047b2c178020dc98fb84aa520aea23f9f957bd3 (commit) via e8cee92b70064358871ce28c1c8d84cc1a297d0c (commit) via 2beef649d438da5bda0a2df81e4601de54668487 (commit) via 58dca4e50ba32dcad9551300691c12c55e740344 (commit) from 14a08a8d15989ace2aa259ddcbc42e4d8a1c890e (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 06f451c0beaba72872fa7ab81a043eb92a3f63ee Merge: 15b470a 8015910 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Jan 28 23:10:47 2015 +0100
Merge remote-tracking branch 'glotzi/monit' into next
commit 15b470a79da5c3fa119920e051386421a3fa317f Merge: fe53fa8 02dba6c Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Jan 28 22:51:17 2015 +0100
Merge remote-tracking branch 'ummeegge/nmap' into next
commit fe53fa8dac070d884e05aa423ec5c854a8997fbd Merge: 14a08a8 5ab875a Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Jan 28 22:49:36 2015 +0100
Merge remote-tracking branch 'ummeegge/lynis' into next
Conflicts: make.sh
commit 80159102fcddef6db3c778ebf1f080ebde5504c6 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Tue Jan 27 14:11:28 2015 +0100
monit addon: upgrade to 5.11
commit a1f369eb1ee97edad4b81518649fd8672763e252 Merge: f0dd065 14a08a8 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Tue Jan 27 13:33:01 2015 +0100
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into monit
commit 02dba6c6cb654567639764332f8b0a24474badb3 Author: Erik Kapfer erik.kapfer@ipfire.org Date: Tue Jan 13 12:05:46 2015 +0100
Nmap: Update to version 6.47 .
Fix #10716
commit 5ab875af711f98f02cead4688a4f76958d9ff894 Author: Erik Kapfer erik.kapfer@ipfire.org Date: Tue Jan 13 11:09:05 2015 +0100
lynis: Update to version 1.6.4.
Fix #10715
commit 98a5192ef2f3cde9b9c6867f69f3a400f3c62ec5 Author: Erik Kapfer erik.kapfer@ipfire.org Date: Mon Jan 12 12:17:43 2015 +0100
openssl: Disable SSLv2 and SSLv3.
Fixes #10712.
commit f0dd06542596fa14cb0ef3bbaeb3ae16ee78c325 Merge: d5ea5e3 5e7c872 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Tue Jan 6 15:51:29 2015 +0100
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into monit
Conflicts: config/etc/logrotate.conf
commit d5ea5e366c52830d4e54b89309340674fc518af2 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Sat Oct 25 20:20:05 2014 +0200
Revert "monit addon: Upgrade to 5.9"
This reverts commit a61bfd61b292b28660539c8214a1edcf90d22db3.
commit a61bfd61b292b28660539c8214a1edcf90d22db3 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Thu Oct 23 18:56:58 2014 +0200
monit addon: Upgrade to 5.9
commit 07562a76208386065c56386b3a77f44137d16c2f Merge: 5ae99dd ad92967 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Wed Oct 22 20:51:32 2014 +0200
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into monit
commit 5ae99dd2d1ed307959f25143e6c343a53e4df373 Merge: 7ce49ff 6c4319a Author: Dirk Wagner dirk.wagner@ipfire.org Date: Wed Oct 15 22:38:13 2014 +0200
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into monit
commit 7ce49ff07440e404959149820e507f79d7c839da Author: Dirk Wagner dirk.wagner@ipfire.org Date: Wed Jul 23 21:49:52 2014 +0200
monit addon: fixed monitrc permissions.
commit c6ede545fdfbc12c10a3a66a3ea76a45e2d39ef4 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Wed Jul 23 20:55:26 2014 +0200
monit addon: fixed init.d links.
commit a1f23a84c7c5b60bf87b30a19451214e59793b9a Merge: 9ac9fc3 65418d1 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Wed Jul 23 11:07:58 2014 +0200
Merge branch 'asterisk-update' into monit
Conflicts: config/etc/logrotate.conf config/rootfiles/packages/asterisk
commit 9ac9fc3d802db666b94cc85175bef2cfbd335ed5 Merge: 57865e5 9d9c825 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Wed Jul 23 10:37:02 2014 +0200
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into monit
Conflicts: config/rootfiles/packages/asterisk
commit 57865e53f70b234f2b1f1be07ed8ca8ef091664b Author: Dirk Wagner dirk.wagner@ipfire.org Date: Wed Jul 23 10:30:14 2014 +0200
monit addon: fixed start script links.
commit e0eeb8a6176ab672b9dd3b3ce93f689e9a2881c3 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Sun Jun 15 22:00:58 2014 +0200
monit addon: update to 5.8.1
commit 2407ace4946f1c0af6c43e6139337b76bfabaa7f Merge: bd34e32 0ee45bc Author: Dirk Wagner dirk.wagner@ipfire.org Date: Sat Jun 14 09:41:59 2014 +0200
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into monit
commit bd34e32e4b2ce637845cb7e7e8a2c8ede1dffe83 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Wed Jun 11 10:54:28 2014 +0200
monit addon: fixed path in init script
commit 1fbd7376b71e7a9affcb41ea7948af66df6ac94f Merge: 6047b2c e3b5a05 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Sat May 17 18:43:00 2014 +0200
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into monit
commit 6047b2c178020dc98fb84aa520aea23f9f957bd3 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Sat May 17 18:42:21 2014 +0200
monit addon: Fixed initscript stuff
commit e8cee92b70064358871ce28c1c8d84cc1a297d0c Merge: 2beef64 28b8e0e Author: Dirk Wagner dirk.wagner@ipfire.org Date: Fri May 9 13:48:03 2014 +0200
Merge branch 'asterisk-update' into monit
commit 2beef649d438da5bda0a2df81e4601de54668487 Merge: 58dca4e 03d0b8c Author: Dirk Wagner dirk.wagner@ipfire.org Date: Fri May 9 09:00:20 2014 +0200
Merge branch 'next' of ssh://git.ipfire.org/pub/git/ipfire-2.x into monit
commit 58dca4e50ba32dcad9551300691c12c55e740344 Author: Dirk Wagner dirk.wagner@ipfire.org Date: Fri May 9 08:59:17 2014 +0200
monit addon: First version.
-----------------------------------------------------------------------
Summary of changes: config/backup/includes/monit | 2 + config/hostapd/hostapd.conf | 2 +- .../kernel/kernel.config.armv5tel-ipfire-kirkwood | 10 +- config/kernel/kernel.config.armv5tel-ipfire-multi | 12 +- config/kernel/kernel.config.armv5tel-ipfire-rpi | 2 +- config/monit/monitrc | 252 + config/rootfiles/common/armv5tel/initscripts | 1 + config/rootfiles/common/armv5tel/u-boot | 16 +- config/rootfiles/common/crda | 14 +- config/rootfiles/common/dvb-firmwares | 5 +- config/rootfiles/common/i586/initscripts | 1 + config/rootfiles/common/kbd | 3 + config/rootfiles/common/linux-firmware | 180 +- config/rootfiles/common/ntp | 264 +- config/rootfiles/common/stage2 | 1 + .../77 => core/86}/filelists/armv5tel/u-boot | 0 .../{oldcore/84 => core/86}/filelists/bash | 0 .../{oldcore/70 => core/86}/filelists/crda | 0 config/rootfiles/core/86/filelists/files | 3 + .../rootfiles/{oldcore/77 => core/86}/filelists/iw | 0 .../{oldcore/66 => core/86}/filelists/kbd | 0 config/rootfiles/core/86/filelists/ntp | 287 + .../{oldcore/81 => core/86}/filelists/openssl | 0 .../82 => core/86}/filelists/openssl-compat | 0 .../rootfiles/core/86/filelists/updated-firmwares | 202 + .../70 => core/86}/filelists/wireless-regdb | 0 .../80 => core/86}/filelists/wpa_supplicant | 0 config/rootfiles/core/86/update.sh | 17 +- config/rootfiles/packages/lynis | 142 +- config/rootfiles/packages/monit | 8 + config/rootfiles/packages/nmap | 179 +- config/u-boot/boot.scr | Bin 419 -> 0 bytes config/u-boot/boot.script | 7 - config/u-boot/convert_bootscript | 1 - config/u-boot/uEnv.txt | 4 + html/cgi-bin/wlanap.cgi | 4 +- lfs/{fetchmail => backports} | 76 +- lfs/crda | 13 +- lfs/dvb-firmwares | 8 +- lfs/flash-images | 17 +- lfs/hostapd | 8 +- lfs/initscripts | 0 lfs/iw | 4 +- lfs/kbd | 12 +- lfs/linux | 20 +- lfs/linux-firmware | 7 +- lfs/lynis | 10 +- lfs/{bacula => monit} | 31 +- lfs/nmap | 8 +- lfs/ntp | 4 +- lfs/openssl | 6 +- lfs/openssl-compat | 4 +- lfs/squid-accounting | 2 +- lfs/u-boot | 20 +- lfs/wireless-regdb | 4 +- lfs/wpa_supplicant | 6 +- make.sh | 6 + src/initscripts/init.d/console | 2 +- src/initscripts/init.d/{pound => monit} | 16 +- src/installer/dracut-module/run-installer.sh | 2 +- src/installer/main.c | 76 +- src/installer/po/ar.po | 197 +- src/installer/po/ca.po | 197 +- src/installer/po/cs_CZ.po | 197 +- src/installer/po/da.po | 219 +- src/installer/po/de.po | 206 +- src/installer/po/el_GR.po | 197 +- src/installer/po/es.po | 197 +- src/installer/po/fa.po | 221 +- src/installer/po/fr.po | 197 +- src/installer/po/hr.po | 329 + src/installer/po/hu.po | 197 +- src/installer/po/id.po | 197 +- src/installer/po/it.po | 299 +- src/installer/po/ja.po | 197 +- src/installer/po/{id.po => ja_JP.po} | 203 +- src/installer/po/km_KH.po | 197 +- src/installer/po/nl.po | 197 +- src/installer/po/pl.po | 281 +- src/installer/po/pt_BR.po | 205 +- src/installer/po/pt_PT.po | 197 +- src/installer/po/ro_RO.po | 197 +- src/installer/po/ru.po | 197 +- src/installer/po/{ca.po => rw.po} | 201 +- src/installer/po/sk.po | 197 +- src/installer/po/sq.po | 197 +- src/installer/po/{ru.po => sr.po} | 203 +- src/installer/po/sv.po | 197 +- src/installer/po/th.po | 197 +- src/installer/po/tk.po | 197 +- src/installer/po/tr.po | 295 +- src/installer/po/uk.po | 197 +- src/installer/po/uz@Latn.po | 197 +- src/installer/po/vi.po | 197 +- src/installer/po/zh.po | 197 +- .../backports-3.18.1-1-add_usbnet_modules.patch | 29383 +++++++++++++++++++ src/patches/backports-3.18.1-1-grsecurity.patch | 3806 +++ src/patches/backports-3.18.1-1-ipfire-build.patch | 34 + ...h => backports-3.18.1-1_add_libertas_uap.patch} | 109 +- src/patches/crda-3.13-crypto_use_optional.patch | 22 + ...linux-3.14.25-rt5592_no_special_txop_init.patch | 13 + .../linux-3.14.25_rt2x00_fix_bss_bcn_num.patch | 12 + ...-509d96d4f1f602d62d36db660973249e16f9d088.patch | 10002 +++++++ .../sunxi/002-uboot-jwrdegoede-psci-support.patch | 1495 + ...fix-gmac-not-working-reliable-on-bananapi.patch | 20 + src/scripts/update-bootloader | 142 + src/setup/po/da.po | 6 +- src/setup/po/de.po | 6 +- src/setup/po/fa.po | 139 +- src/setup/po/fr.po | 39 +- src/setup/po/{da.po => hr.po} | 263 +- src/setup/po/it.po | 264 +- src/setup/po/{th.po => ja_JP.po} | 8 +- src/setup/po/pl.po | 264 +- src/setup/po/ru.po | 79 +- src/setup/po/{nl.po => rw.po} | 8 +- src/setup/po/{uk.po => sr.po} | 8 +- src/setup/po/tr.po | 263 +- src/squid-accounting/acct-lib.pl | 1 + src/squid-accounting/acct.pl | 4 +- 120 files changed, 52572 insertions(+), 2992 deletions(-) create mode 100644 config/backup/includes/monit create mode 100644 config/monit/monitrc mode change 100644 => 100755 config/rootfiles/common/armv5tel/initscripts mode change 100644 => 100755 config/rootfiles/common/i586/initscripts copy config/rootfiles/{oldcore/77 => core/86}/filelists/armv5tel/u-boot (100%) copy config/rootfiles/{oldcore/84 => core/86}/filelists/bash (100%) copy config/rootfiles/{oldcore/70 => core/86}/filelists/crda (100%) copy config/rootfiles/{oldcore/77 => core/86}/filelists/iw (100%) copy config/rootfiles/{oldcore/66 => core/86}/filelists/kbd (100%) create mode 100644 config/rootfiles/core/86/filelists/ntp copy config/rootfiles/{oldcore/81 => core/86}/filelists/openssl (100%) copy config/rootfiles/{oldcore/82 => core/86}/filelists/openssl-compat (100%) create mode 100644 config/rootfiles/core/86/filelists/updated-firmwares copy config/rootfiles/{oldcore/70 => core/86}/filelists/wireless-regdb (100%) copy config/rootfiles/{oldcore/80 => core/86}/filelists/wpa_supplicant (100%) create mode 100644 config/rootfiles/packages/monit delete mode 100755 config/u-boot/boot.scr delete mode 100755 config/u-boot/boot.script delete mode 100755 config/u-boot/convert_bootscript create mode 100755 config/u-boot/uEnv.txt copy lfs/{fetchmail => backports} (50%) mode change 100644 => 100755 lfs/initscripts copy lfs/{bacula => monit} (81%) copy src/initscripts/init.d/{pound => monit} (58%) create mode 100644 src/installer/po/hr.po copy src/installer/po/{id.po => ja_JP.po} (55%) copy src/installer/po/{ca.po => rw.po} (57%) copy src/installer/po/{ru.po => sr.po} (56%) create mode 100644 src/patches/backports-3.18.1-1-add_usbnet_modules.patch create mode 100644 src/patches/backports-3.18.1-1-grsecurity.patch create mode 100644 src/patches/backports-3.18.1-1-ipfire-build.patch copy src/patches/{linux-3.10.39-add_libertas_uap.patch => backports-3.18.1-1_add_libertas_uap.patch} (97%) create mode 100644 src/patches/crda-3.13-crypto_use_optional.patch create mode 100644 src/patches/linux-3.14.25-rt5592_no_special_txop_init.patch create mode 100644 src/patches/linux-3.14.25_rt2x00_fix_bss_bcn_num.patch create mode 100644 src/patches/u-boot/sunxi/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch create mode 100644 src/patches/u-boot/sunxi/002-uboot-jwrdegoede-psci-support.patch create mode 100644 src/patches/u-boot/sunxi/003-uboot-fix-gmac-not-working-reliable-on-bananapi.patch create mode 100644 src/scripts/update-bootloader copy src/setup/po/{da.po => hr.po} (61%) copy src/setup/po/{th.po => ja_JP.po} (98%) copy src/setup/po/{nl.po => rw.po} (98%) copy src/setup/po/{uk.po => sr.po} (98%)
Difference in files: diff --git a/config/backup/includes/monit b/config/backup/includes/monit new file mode 100644 index 0000000..c25b941 --- /dev/null +++ b/config/backup/includes/monit @@ -0,0 +1,2 @@ +/etc/monitrc +/etc/monit.d diff --git a/config/hostapd/hostapd.conf b/config/hostapd/hostapd.conf index e1f493f..33fd304 100644 --- a/config/hostapd/hostapd.conf +++ b/config/hostapd/hostapd.conf @@ -3,7 +3,7 @@ driver=nl80211 # interface=blue0 hw_mode=g -channel=05 +channel=6 logger_syslog=-1 logger_syslog_level=3 logger_stdout=-1 diff --git a/config/kernel/kernel.config.armv5tel-ipfire-kirkwood b/config/kernel/kernel.config.armv5tel-ipfire-kirkwood index 13fac5e..fbfc05c 100644 --- a/config/kernel/kernel.config.armv5tel-ipfire-kirkwood +++ b/config/kernel/kernel.config.armv5tel-ipfire-kirkwood @@ -3079,7 +3079,7 @@ CONFIG_REGULATOR_LP8755=m # CONFIG_REGULATOR_TPS62360 is not set # CONFIG_REGULATOR_TPS65023 is not set # CONFIG_REGULATOR_TPS6507X is not set -CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT=m
# # Multimedia core support @@ -3090,9 +3090,9 @@ CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y # CONFIG_MEDIA_RADIO_SUPPORT is not set CONFIG_MEDIA_RC_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y -CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_DEV=m CONFIG_VIDEO_V4L2_SUBDEV_API=y -CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L2=m # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set CONFIG_VIDEO_TUNER=m @@ -3106,7 +3106,7 @@ CONFIG_VIDEOBUF2_CORE=m CONFIG_VIDEOBUF2_MEMOPS=m CONFIG_VIDEOBUF2_DMA_CONTIG=m CONFIG_VIDEOBUF2_VMALLOC=m -CONFIG_DVB_CORE=y +CONFIG_DVB_CORE=m CONFIG_DVB_NET=y CONFIG_TTPCI_EEPROM=m CONFIG_DVB_MAX_ADAPTERS=8 @@ -3115,7 +3115,7 @@ CONFIG_DVB_DYNAMIC_MINORS=y # # Media drivers # -CONFIG_RC_CORE=y +CONFIG_RC_CORE=m CONFIG_RC_MAP=m CONFIG_RC_DECODERS=y CONFIG_LIRC=m diff --git a/config/kernel/kernel.config.armv5tel-ipfire-multi b/config/kernel/kernel.config.armv5tel-ipfire-multi index a1c49d4..8249d2c 100644 --- a/config/kernel/kernel.config.armv5tel-ipfire-multi +++ b/config/kernel/kernel.config.armv5tel-ipfire-multi @@ -3330,7 +3330,7 @@ CONFIG_REGULATOR_TI_ABB=y # CONFIG_REGULATOR_TPS6507X is not set CONFIG_REGULATOR_TWL4030=y CONFIG_REGULATOR_VEXPRESS=m -CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT=m
# # Multimedia core support @@ -3341,9 +3341,9 @@ CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y # CONFIG_MEDIA_RADIO_SUPPORT is not set CONFIG_MEDIA_RC_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y -CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_DEV=m CONFIG_VIDEO_V4L2_SUBDEV_API=y -CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L2=m # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set CONFIG_VIDEO_TUNER=m @@ -3357,7 +3357,7 @@ CONFIG_VIDEOBUF2_CORE=m CONFIG_VIDEOBUF2_MEMOPS=m CONFIG_VIDEOBUF2_DMA_CONTIG=m CONFIG_VIDEOBUF2_VMALLOC=m -CONFIG_DVB_CORE=y +CONFIG_DVB_CORE=m CONFIG_DVB_NET=y CONFIG_TTPCI_EEPROM=m CONFIG_DVB_MAX_ADAPTERS=8 @@ -3366,7 +3366,7 @@ CONFIG_DVB_DYNAMIC_MINORS=y # # Media drivers # -CONFIG_RC_CORE=y +CONFIG_RC_CORE=m CONFIG_RC_MAP=m CONFIG_RC_DECODERS=y CONFIG_LIRC=m @@ -3606,8 +3606,6 @@ CONFIG_VIDEO_OMAP2_VOUT_VRFB=y CONFIG_VIDEO_OMAP2_VOUT=y CONFIG_VIDEO_TIMBERDALE=m CONFIG_SOC_CAMERA=m -CONFIG_SOC_CAMERA_SCALE_CROP=m -CONFIG_SOC_CAMERA_PLATFORM=m CONFIG_VIDEO_MX3=m CONFIG_VIDEO_RCAR_VIN=m # CONFIG_VIDEO_SH_MOBILE_CSI2 is not set diff --git a/config/kernel/kernel.config.armv5tel-ipfire-rpi b/config/kernel/kernel.config.armv5tel-ipfire-rpi index cfc9dc1..b02167d 100644 --- a/config/kernel/kernel.config.armv5tel-ipfire-rpi +++ b/config/kernel/kernel.config.armv5tel-ipfire-rpi @@ -1453,7 +1453,7 @@ CONFIG_USB_KAWETH=m CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m -CONFIG_USB_USBNET=y +CONFIG_USB_USBNET=m CONFIG_USB_NET_AX8817X=m CONFIG_USB_NET_AX88179_178A=m CONFIG_USB_NET_CDCETHER=m diff --git a/config/monit/monitrc b/config/monit/monitrc new file mode 100644 index 0000000..9fee14a --- /dev/null +++ b/config/monit/monitrc @@ -0,0 +1,252 @@ +############################################################################### +## Monit control file +############################################################################### +## +## Comments begin with a '#' and extend through the end of the line. Keywords +## are case insensitive. All path's MUST BE FULLY QUALIFIED, starting with '/'. +## +## Below you will find examples of some frequently used statements. For +## information about the control file and a complete list of statements and +## options, please have a look in the Monit manual. +## +## +############################################################################### +## Global section +############################################################################### +## +## Start Monit in the background (run as a daemon): +# +set daemon 60 # check services at 1-minute intervals +# with start delay 240 # optional: delay the first check by 4-minutes (by +# # default Monit check immediately after Monit start) +# +# +## Set syslog logging with the 'daemon' facility. If the FACILITY option is +## omitted, Monit will use 'user' facility by default. If you want to log to +## a standalone log file instead, specify the full path to the log file +# +set logfile syslog facility log_daemon +# +# +## Set the location of the Monit lock file which stores the process id of the +## running Monit instance. By default this file is stored in $HOME/.monit.pid +# +set pidfile /var/run/monit.pid +# +## Set the location of the Monit id file which stores the unique id for the +## Monit instance. The id is generated and stored on first Monit start. By +## default the file is placed in $HOME/.monit.id. +# +set idfile /var/lib/monit/id +# +## Set the location of the Monit state file which saves monitoring states +## on each cycle. By default the file is placed in $HOME/.monit.state. If +## the state file is stored on a persistent filesystem, Monit will recover +## the monitoring state across reboots. If it is on temporary filesystem, the +## state will be lost on reboot which may be convenient in some situations. +# +set statefile /var/lib/monit/state +# +## Set the list of mail servers for alert delivery. Multiple servers may be +## specified using a comma separator. If the first mail server fails, Monit +# will use the second mail server in the list and so on. By default Monit uses +# port 25 - it is possible to override this with the PORT option. +# +# set mailserver mail.bar.baz, # primary mailserver +# backup.bar.baz port 10025, # backup mailserver on port 10025 +# localhost # fallback relay +# +# +## By default Monit will drop alert events if no mail servers are available. +## If you want to keep the alerts for later delivery retry, you can use the +## EVENTQUEUE statement. The base directory where undelivered alerts will be +## stored is specified by the BASEDIR option. You can limit the queue size +## by using the SLOTS option (if omitted, the queue is limited by space +## available in the back end filesystem). +# +set eventqueue + basedir /var/lib/monit # set the base directory where events will be stored + slots 100 # optionally limit the queue size +# +# +## Send status and events to M/Monit (for more informations about M/Monit +## see http://mmonit.com/). By default Monit registers credentials with +## M/Monit so M/Monit can smoothly communicate back to Monit and you don't +## have to register Monit credentials manually in M/Monit. It is possible to +## disable credential registration using the commented out option below. +## Though, if safety is a concern we recommend instead using https when +## communicating with M/Monit and send credentials encrypted. +# +# set mmonit http://monit:monit@192.168.1.10:8080/collector +# # and register without credentials # Don't register credentials +# +# +## Monit by default uses the following format for alerts if the the mail-format +## statement is missing:: +## --8<-- +## set mail-format { +## from: monit@$HOST +## subject: monit alert -- $EVENT $SERVICE +## message: $EVENT Service $SERVICE +## Date: $DATE +## Action: $ACTION +## Host: $HOST +## Description: $DESCRIPTION +## +## Your faithful employee, +## Monit +## } +## --8<-- +## +## You can override this message format or parts of it, such as subject +## or sender using the MAIL-FORMAT statement. Macros such as $DATE, etc. +## are expanded at runtime. For example, to override the sender, use: +# +# set mail-format { from: monit@foo.bar }a +# +# +## You can set alert recipients whom will receive alerts if/when a +## service defined in this file has errors. Alerts may be restricted on +## events by using a filter as in the second example below. +# +# set alert sysadm@foo.bar # receive all alerts +## Do not alert when Monit start, stop or perform a user initiated action. +## This filter is recommended to avoid getting alerts for trivial cases +# set alert your-name@your.domain not on { instance, action } +# +# +## Monit has an embedded web server which can be used to view status of +## services monitored and manage services from a web interface. See the +## Monit Wiki if you want to enable SSL for the web server. +# +set httpd port 2812 and + use address localhost # only accept connection from localhost + allow localhost # allow localhost to connect to the server and +# allow admin:monit # require user 'admin' with password 'monit' +# allow @monit # allow users of group 'monit' to connect (rw) +# allow @users readonly # allow users of group 'users' to connect readonly + +############################################################################### +## Services +############################################################################### +## +## Check general system resources such as load average, cpu and memory +## usage. Each test specifies a resource, conditions and the action to be +## performed should a test fail. +# +# check system myhost.mydomain.tld +# if loadavg (1min) > 4 then alert +# if loadavg (5min) > 2 then alert +# if memory usage > 75% then alert +# if swap usage > 25% then alert +# if cpu usage (user) > 70% then alert +# if cpu usage (system) > 30% then alert +# if cpu usage (wait) > 20% then alert +# +# +## Check if a file exists, checksum, permissions, uid and gid. In addition +## to alert recipients in the global section, customized alert can be sent to +## additional recipients by specifying a local alert handler. The service may +## be grouped using the GROUP option. More than one group can be specified by +## repeating the 'group name' statement. +# +# check file apache_bin with path /usr/local/apache/bin/httpd +# if failed checksum and +# expect the sum 8f7f419955cefa0b33a2ba316cba3659 then unmonitor +# if failed permission 755 then unmonitor +# if failed uid root then unmonitor +# if failed gid root then unmonitor +# alert security@foo.bar on { +# checksum, permission, uid, gid, unmonitor +# } with the mail-format { subject: Alarm! } +# group server +# +# +## Check that a process is running, in this case Apache, and that it respond +## to HTTP and HTTPS requests. Check its resource usage such as cpu and memory, +## and number of children. If the process is not running, Monit will restart +## it by default. In case the service is restarted very often and the +## problem remains, it is possible to disable monitoring using the TIMEOUT +## statement. This service depends on another service (apache_bin) which +## is defined above. +# +# check process apache with pidfile /usr/local/apache/logs/httpd.pid +# start program = "/etc/init.d/httpd start" with timeout 60 seconds +# stop program = "/etc/init.d/httpd stop" +# if cpu > 60% for 2 cycles then alert +# if cpu > 80% for 5 cycles then restart +# if totalmem > 200.0 MB for 5 cycles then restart +# if children > 250 then restart +# if loadavg(5min) greater than 10 for 8 cycles then stop +# if failed host www.tildeslash.com port 80 protocol http +# and request "/somefile.html" +# then restart +# if failed port 443 type tcpssl protocol http +# with timeout 15 seconds +# then restart +# if 3 restarts within 5 cycles then timeout +# depends on apache_bin +# group server +# +# +## Check filesystem permissions, uid, gid, space and inode usage. Other services, +## such as databases, may depend on this resource and an automatically graceful +## stop may be cascaded to them before the filesystem will become full and data +## lost. +# +# check filesystem datafs with path /dev/sdb1 +# start program = "/bin/mount /data" +# stop program = "/bin/umount /data" +# if failed permission 660 then unmonitor +# if failed uid root then unmonitor +# if failed gid disk then unmonitor +# if space usage > 80% for 5 times within 15 cycles then alert +# if space usage > 99% then stop +# if inode usage > 30000 then alert +# if inode usage > 99% then stop +# group server +# +# +## Check a file's timestamp. In this example, we test if a file is older +## than 15 minutes and assume something is wrong if its not updated. Also, +## if the file size exceed a given limit, execute a script +# +# check file database with path /data/mydatabase.db +# if failed permission 700 then alert +# if failed uid data then alert +# if failed gid data then alert +# if timestamp > 15 minutes then alert +# if size > 100 MB then exec "/my/cleanup/script" as uid dba and gid dba +# +# +## Check directory permission, uid and gid. An event is triggered if the +## directory does not belong to the user with uid 0 and gid 0. In addition, +## the permissions have to match the octal description of 755 (see chmod(1)). +# +# check directory bin with path /bin +# if failed permission 755 then unmonitor +# if failed uid 0 then unmonitor +# if failed gid 0 then unmonitor +# +# +## Check a remote host availability by issuing a ping test and check the +## content of a response from a web server. Up to three pings are sent and +## connection to a port and an application level network check is performed. +# +# check host myserver with address 192.168.1.1 +# if failed icmp type echo count 3 with timeout 3 seconds then alert +# if failed port 3306 protocol mysql with timeout 15 seconds then alert +# if failed port 80 protocol http +# and request /monit/ with content = "Monit [0-9.]+ Download" +# then alert +# +# +############################################################################### +## Includes +############################################################################### +## +## It is possible to include additional configuration parts from other files or +## directories. +# +include /etc/monit.d/* +# diff --git a/config/rootfiles/common/armv5tel/initscripts b/config/rootfiles/common/armv5tel/initscripts old mode 100644 new mode 100755 index 9804415..e529e66 --- a/config/rootfiles/common/armv5tel/initscripts +++ b/config/rootfiles/common/armv5tel/initscripts @@ -52,6 +52,7 @@ etc/rc.d/init.d/mISDN #etc/rc.d/init.d/mldonkey etc/rc.d/init.d/modules #etc/rc.d/init.d/motion +#etc/rc.d/init.d/monit etc/rc.d/init.d/mountfs etc/rc.d/init.d/mountkernfs etc/rc.d/init.d/mounttmpfs diff --git a/config/rootfiles/common/armv5tel/u-boot b/config/rootfiles/common/armv5tel/u-boot index b139d7e..a31e3cf 100644 --- a/config/rootfiles/common/armv5tel/u-boot +++ b/config/rootfiles/common/armv5tel/u-boot @@ -1,16 +1,16 @@ #boot/MLO -boot/boot.scr -boot/boot.script -boot/convert_bootscript #boot/u-boot.img +boot/uEnv.txt usr/bin/mkimage #usr/share/u-boot +#usr/share/u-boot/banana_pi +usr/share/u-boot/banana_pi/u-boot-sunxi-with-spl.bin #usr/share/u-boot/pandaboard -#usr/share/u-boot/pandaboard/MLO -#usr/share/u-boot/pandaboard/u-boot.img +usr/share/u-boot/pandaboard/MLO +usr/share/u-boot/pandaboard/u-boot.img #usr/share/u-boot/wandboard_dl -#usr/share/u-boot/wandboard_dl/u-boot.imx +usr/share/u-boot/wandboard_dl/u-boot.imx #usr/share/u-boot/wandboard_quad -#usr/share/u-boot/wandboard_quad/u-boot.imx +usr/share/u-boot/wandboard_quad/u-boot.imx #usr/share/u-boot/wandboard_solo -#usr/share/u-boot/wandboard_solo/u-boot.imx +usr/share/u-boot/wandboard_solo/u-boot.imx diff --git a/config/rootfiles/common/crda b/config/rootfiles/common/crda index 23c2ad0..74f0850 100644 --- a/config/rootfiles/common/crda +++ b/config/rootfiles/common/crda @@ -1,12 +1,14 @@ lib/udev/rules.d/85-regulatory.rules #root/.python-eggs -#root/.python-eggs/M2Crypto-0.21.1-py2.7-linux-MACHINE.egg-tmp -#root/.python-eggs/M2Crypto-0.21.1-py2.7-linux-MACHINE.egg-tmp/M2Crypto -#root/.python-eggs/M2Crypto-0.21.1-py2.7-linux-MACHINE.egg-tmp/M2Crypto/__m2crypto.so -#root/.python-eggs/M2Crypto-0.21.1-py2.7-linux-i686.egg-tmp -#root/.python-eggs/M2Crypto-0.21.1-py2.7-linux-i686.egg-tmp/M2Crypto -#root/.python-eggs/M2Crypto-0.21.1-py2.7-linux-i686.egg-tmp/M2Crypto/__m2crypto.so +#root/.python-eggs/M2Crypto-0.21.1-py2.7-linux-i586.egg-tmp +#root/.python-eggs/M2Crypto-0.21.1-py2.7-linux-i586.egg-tmp/M2Crypto +#root/.python-eggs/M2Crypto-0.21.1-py2.7-linux-i586.egg-tmp/M2Crypto/__m2crypto.so sbin/crda sbin/regdbdump +#usr/include/reglib +#usr/include/reglib/nl80211.h +#usr/include/reglib/regdb.h +#usr/include/reglib/reglib.h +usr/lib/libreg.so #usr/share/man/man8/crda.8.gz #usr/share/man/man8/regdbdump.8.gz diff --git a/config/rootfiles/common/dvb-firmwares b/config/rootfiles/common/dvb-firmwares index 53dec97..e9ec940 100644 --- a/config/rootfiles/common/dvb-firmwares +++ b/config/rootfiles/common/dvb-firmwares @@ -1,4 +1,7 @@ lib/firmware/dvb-fe-bcm3510-01.fw +lib/firmware/dvb-fe-drxj-mc-1.0.8.fw +lib/firmware/dvb-fe-drxj-mc-vsb-1.0.8.fw +lib/firmware/dvb-fe-drxj-mc-vsb-qam-1.0.8.fw lib/firmware/dvb-fe-or51132-qam.fw lib/firmware/dvb-fe-or51132-vsb.fw lib/firmware/dvb-fe-or51211.fw @@ -21,4 +24,4 @@ lib/firmware/dvb-usb-vp702x-01.fw lib/firmware/dvb-usb-vp7045-01.fw lib/firmware/dvb-usb-wt220u-01.fw lib/firmware/dvb-usb-wt220u-02.fw -lib/firmware/v4l-cx23885-enc.fw +lib/firmware/v4l-cx23885-enc-broken.fw diff --git a/config/rootfiles/common/i586/initscripts b/config/rootfiles/common/i586/initscripts old mode 100644 new mode 100755 index d0bc8c5..58b67c8 --- a/config/rootfiles/common/i586/initscripts +++ b/config/rootfiles/common/i586/initscripts @@ -53,6 +53,7 @@ etc/rc.d/init.d/mISDN #etc/rc.d/init.d/miniupnpd #etc/rc.d/init.d/mldonkey etc/rc.d/init.d/modules +#etc/rc.d/init.d/monit #etc/rc.d/init.d/motion etc/rc.d/init.d/mountfs etc/rc.d/init.d/mountkernfs diff --git a/config/rootfiles/common/kbd b/config/rootfiles/common/kbd index 7b6ccc3..5f694ff 100644 --- a/config/rootfiles/common/kbd +++ b/config/rootfiles/common/kbd @@ -137,6 +137,7 @@ lib/kbd/consolefonts/iso07u-16.psfu.gz #lib/kbd/consolefonts/lat0-12.psfu.gz #lib/kbd/consolefonts/lat0-14.psfu.gz lib/kbd/consolefonts/lat0-16.psfu.gz +lib/kbd/consolefonts/lat0-sun16.psfu.gz #lib/kbd/consolefonts/lat1-08.psfu.gz #lib/kbd/consolefonts/lat1-10.psfu.gz #lib/kbd/consolefonts/lat1-12.psfu.gz @@ -147,6 +148,7 @@ lib/kbd/consolefonts/lat1-16.psfu.gz #lib/kbd/consolefonts/lat2-12.psfu.gz #lib/kbd/consolefonts/lat2-14.psfu.gz lib/kbd/consolefonts/lat2-16.psfu.gz +lib/kbd/consolefonts/lat2-sun16.psfu.gz #lib/kbd/consolefonts/lat2a-16.psfu.gz #lib/kbd/consolefonts/lat4-08.psfu.gz #lib/kbd/consolefonts/lat4-10.psfu.gz @@ -188,6 +190,7 @@ lib/kbd/consolefonts/lat5-16.psfu.gz #lib/kbd/consolefonts/lat9w-12.psfu.gz #lib/kbd/consolefonts/lat9w-14.psfu.gz #lib/kbd/consolefonts/lat9w-16.psfu.gz +lib/kbd/consolefonts/latarcyrheb-sun16.psfu.gz #lib/kbd/consolefonts/partialfonts #lib/kbd/consolefonts/partialfonts/8859-1.a0-ff.08.gz #lib/kbd/consolefonts/partialfonts/8859-1.a0-ff.14.gz diff --git a/config/rootfiles/common/linux-firmware b/config/rootfiles/common/linux-firmware index d828b8d..a883999 100644 --- a/config/rootfiles/common/linux-firmware +++ b/config/rootfiles/common/linux-firmware @@ -2,6 +2,8 @@ lib/firmware/3com/3C359.bin lib/firmware/3com/typhoon.bin lib/firmware/GPL-3 +lib/firmware/LICENCE.Abilis +lib/firmware/LICENCE.IntcSST2 lib/firmware/LICENCE.Marvell lib/firmware/LICENCE.OLPC lib/firmware/LICENCE.agere @@ -11,23 +13,30 @@ lib/firmware/LICENCE.ca0132 lib/firmware/LICENCE.chelsio_firmware lib/firmware/LICENCE.cw1200 lib/firmware/LICENCE.ene_firmware +lib/firmware/LICENCE.fw_sst_0f28 lib/firmware/LICENCE.go7007 lib/firmware/LICENCE.i2400m lib/firmware/LICENCE.ibt_firmware +lib/firmware/LICENCE.it913x lib/firmware/LICENCE.iwlwifi_firmware lib/firmware/LICENCE.mwl8335 lib/firmware/LICENCE.myri10ge_firmware lib/firmware/LICENCE.phanfw +lib/firmware/LICENCE.qat_dh895xcc_firmware lib/firmware/LICENCE.qla2xxx +lib/firmware/LICENCE.r8a779x_usb3 lib/firmware/LICENCE.ralink-firmware.txt lib/firmware/LICENCE.ralink_a_mediatek_company_firmware lib/firmware/LICENCE.rtlwifi_firmware.txt +lib/firmware/LICENCE.siano lib/firmware/LICENCE.tda7706-firmware.txt lib/firmware/LICENCE.ti-connectivity lib/firmware/LICENCE.ueagle-atm4-firmware lib/firmware/LICENCE.via_vt6656 lib/firmware/LICENCE.wl1251 +lib/firmware/LICENCE.xc4000 lib/firmware/LICENCE.xc5000 +lib/firmware/LICENCE.xc5000c lib/firmware/LICENSE.amd-ucode lib/firmware/LICENSE.dib0700 lib/firmware/LICENSE.radeon @@ -58,6 +67,8 @@ lib/firmware/amd-ucode/microcode_amd.bin lib/firmware/amd-ucode/microcode_amd.bin.asc lib/firmware/amd-ucode/microcode_amd_fam15h.bin lib/firmware/amd-ucode/microcode_amd_fam15h.bin.asc +lib/firmware/amd-ucode/microcode_amd_fam16h.bin +lib/firmware/amd-ucode/microcode_amd_fam16h.bin.asc #lib/firmware/ar3k #lib/firmware/ar3k/1020200 lib/firmware/ar3k/1020200/PS_ASIC.pst @@ -100,6 +111,8 @@ lib/firmware/ar7010_1_1.fw lib/firmware/ar9170-1.fw lib/firmware/ar9170-2.fw lib/firmware/ar9271.fw +lib/firmware/as102_data1_st.hex +lib/firmware/as102_data2_st.hex lib/firmware/ath3k-1.fw #lib/firmware/ath6k #lib/firmware/ath6k/AR6002 @@ -191,9 +204,11 @@ lib/firmware/bnx2x/bnx2x-e1-6.2.9.0.fw lib/firmware/bnx2x/bnx2x-e1-7.0.20.0.fw lib/firmware/bnx2x/bnx2x-e1-7.0.23.0.fw lib/firmware/bnx2x/bnx2x-e1-7.0.29.0.fw +lib/firmware/bnx2x/bnx2x-e1-7.10.51.0.fw lib/firmware/bnx2x/bnx2x-e1-7.2.16.0.fw lib/firmware/bnx2x/bnx2x-e1-7.2.51.0.fw lib/firmware/bnx2x/bnx2x-e1-7.8.17.0.fw +lib/firmware/bnx2x/bnx2x-e1-7.8.19.0.fw lib/firmware/bnx2x/bnx2x-e1-7.8.2.0.fw lib/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw lib/firmware/bnx2x/bnx2x-e1h-6.2.5.0.fw @@ -201,9 +216,11 @@ lib/firmware/bnx2x/bnx2x-e1h-6.2.9.0.fw lib/firmware/bnx2x/bnx2x-e1h-7.0.20.0.fw lib/firmware/bnx2x/bnx2x-e1h-7.0.23.0.fw lib/firmware/bnx2x/bnx2x-e1h-7.0.29.0.fw +lib/firmware/bnx2x/bnx2x-e1h-7.10.51.0.fw lib/firmware/bnx2x/bnx2x-e1h-7.2.16.0.fw lib/firmware/bnx2x/bnx2x-e1h-7.2.51.0.fw lib/firmware/bnx2x/bnx2x-e1h-7.8.17.0.fw +lib/firmware/bnx2x/bnx2x-e1h-7.8.19.0.fw lib/firmware/bnx2x/bnx2x-e1h-7.8.2.0.fw lib/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw lib/firmware/bnx2x/bnx2x-e2-6.2.5.0.fw @@ -211,14 +228,18 @@ lib/firmware/bnx2x/bnx2x-e2-6.2.9.0.fw lib/firmware/bnx2x/bnx2x-e2-7.0.20.0.fw lib/firmware/bnx2x/bnx2x-e2-7.0.23.0.fw lib/firmware/bnx2x/bnx2x-e2-7.0.29.0.fw +lib/firmware/bnx2x/bnx2x-e2-7.10.51.0.fw lib/firmware/bnx2x/bnx2x-e2-7.2.16.0.fw lib/firmware/bnx2x/bnx2x-e2-7.2.51.0.fw lib/firmware/bnx2x/bnx2x-e2-7.8.17.0.fw +lib/firmware/bnx2x/bnx2x-e2-7.8.19.0.fw lib/firmware/bnx2x/bnx2x-e2-7.8.2.0.fw #lib/firmware/brcm lib/firmware/brcm/bcm4329-fullmac-4.bin lib/firmware/brcm/bcm43xx-0.fw lib/firmware/brcm/bcm43xx_hdr-0.fw +lib/firmware/brcm/brcmfmac43143-sdio.bin +lib/firmware/brcm/brcmfmac43143.bin lib/firmware/brcm/brcmfmac43236b.bin lib/firmware/brcm/brcmfmac43241b0-sdio.bin lib/firmware/brcm/brcmfmac43241b4-sdio.bin @@ -226,6 +247,8 @@ lib/firmware/brcm/brcmfmac4329-sdio.bin lib/firmware/brcm/brcmfmac4330-sdio.bin lib/firmware/brcm/brcmfmac4334-sdio.bin lib/firmware/brcm/brcmfmac4335-sdio.bin +lib/firmware/brcm/brcmfmac43362-sdio.bin +lib/firmware/brcm/brcmfmac4354-sdio.bin lib/firmware/carl9170-1.fw #lib/firmware/carl9170fw #lib/firmware/carl9170fw/CMakeLists.txt @@ -391,6 +414,8 @@ lib/firmware/cis/src/PE520.cis lib/firmware/cis/src/RS-COM-2P.cis lib/firmware/cis/src/tamarack.cis lib/firmware/cis/tamarack.cis +lib/firmware/cmmb_vega_12mhz.inp +lib/firmware/cmmb_venice_12mhz.inp #lib/firmware/configure #lib/firmware/cpia2 lib/firmware/cpia2/stv0672_vp4.bin @@ -412,9 +437,9 @@ lib/firmware/cxgb3/t3fw-7.10.0.bin lib/firmware/cxgb3/t3fw-7.12.0.bin lib/firmware/cxgb3/t3fw-7.4.0.bin #lib/firmware/cxgb4 -lib/firmware/cxgb4/t4fw-1.9.23.0.bin +lib/firmware/cxgb4/t4fw-1.12.25.0.bin lib/firmware/cxgb4/t4fw.bin -lib/firmware/cxgb4/t5fw-1.9.23.0.bin +lib/firmware/cxgb4/t5fw-1.12.25.0.bin lib/firmware/cxgb4/t5fw.bin #lib/firmware/dabusb lib/firmware/dabusb/bitstream.bin @@ -424,9 +449,15 @@ lib/firmware/dabusb/firmware.fw #lib/firmware/dsp56k/bootstrap.asm lib/firmware/dsp56k/bootstrap.bin #lib/firmware/dsp56k/concat-bootstrap.pl +lib/firmware/dvb-fe-xc4000-1.4.1.fw lib/firmware/dvb-fe-xc5000-1.6.114.fw +lib/firmware/dvb-fe-xc5000c-4.1.30.7.fw lib/firmware/dvb-usb-dib0700-1.20.fw +lib/firmware/dvb-usb-it9135-01.fw +lib/firmware/dvb-usb-it9135-02.fw lib/firmware/dvb-usb-terratec-h5-drxk.fw +lib/firmware/dvb_nova_12mhz.inp +lib/firmware/dvb_nova_12mhz_b0.inp #lib/firmware/e100 lib/firmware/e100/d101m_ucode.bin lib/firmware/e100/d101s_ucode.bin @@ -472,9 +503,17 @@ lib/firmware/i2400m-fw-usb-1.4.sbcf lib/firmware/i2400m-fw-usb-1.5.sbcf lib/firmware/i6050-fw-usb-1.5.sbcf #lib/firmware/intel +lib/firmware/intel/IntcSST2.bin +lib/firmware/intel/fw_sst_0f28.bin +lib/firmware/intel/fw_sst_0f28.bin-48kHz_i2s_master +lib/firmware/intel/ibt-hw-37.7.10-fw-1.0.1.2d.d.bseq lib/firmware/intel/ibt-hw-37.7.10-fw-1.0.2.3.d.bseq +lib/firmware/intel/ibt-hw-37.7.10-fw-1.80.1.2d.d.bseq lib/firmware/intel/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq lib/firmware/intel/ibt-hw-37.7.bseq +lib/firmware/intel/ibt-hw-37.8.10-fw-1.10.2.27.d.bseq +lib/firmware/intel/ibt-hw-37.8.10-fw-1.10.3.11.e.bseq +lib/firmware/intel/ibt-hw-37.8.bseq lib/firmware/intelliport2.bin #lib/firmware/isci #lib/firmware/isci/Makefile @@ -483,6 +522,9 @@ lib/firmware/isci/README #lib/firmware/isci/create_fw.h lib/firmware/isci/isci_firmware.bin #lib/firmware/isci/probe_roms.h +lib/firmware/isdbt_nova_12mhz.inp +lib/firmware/isdbt_nova_12mhz_b0.inp +lib/firmware/isdbt_rio.inp lib/firmware/iwlwifi-100-5.ucode lib/firmware/iwlwifi-1000-3.ucode lib/firmware/iwlwifi-1000-5.ucode @@ -490,7 +532,10 @@ lib/firmware/iwlwifi-105-6.ucode lib/firmware/iwlwifi-135-6.ucode lib/firmware/iwlwifi-2000-6.ucode lib/firmware/iwlwifi-2030-6.ucode +lib/firmware/iwlwifi-3160-10.ucode lib/firmware/iwlwifi-3160-7.ucode +lib/firmware/iwlwifi-3160-8.ucode +lib/firmware/iwlwifi-3160-9.ucode lib/firmware/iwlwifi-3945-2.ucode lib/firmware/iwlwifi-4965-2.ucode lib/firmware/iwlwifi-5000-1.ucode @@ -504,7 +549,14 @@ lib/firmware/iwlwifi-6000g2b-5.ucode lib/firmware/iwlwifi-6000g2b-6.ucode lib/firmware/iwlwifi-6050-4.ucode lib/firmware/iwlwifi-6050-5.ucode +lib/firmware/iwlwifi-7260-10.ucode lib/firmware/iwlwifi-7260-7.ucode +lib/firmware/iwlwifi-7260-8.ucode +lib/firmware/iwlwifi-7260-9.ucode +lib/firmware/iwlwifi-7265-10.ucode +lib/firmware/iwlwifi-7265-8.ucode +lib/firmware/iwlwifi-7265-9.ucode +lib/firmware/iwlwifi-7265D-10.ucode #lib/firmware/kaweth lib/firmware/kaweth/new_code.bin lib/firmware/kaweth/new_code_fix.bin @@ -595,15 +647,20 @@ lib/firmware/mwl8k/fmimage_8687.fw lib/firmware/mwl8k/fmimage_8764_ap-1.fw lib/firmware/mwl8k/helper_8366.fw lib/firmware/mwl8k/helper_8687.fw +lib/firmware/myri10ge_eth_big_z8e.dat lib/firmware/myri10ge_eth_z8e.dat +lib/firmware/myri10ge_ethp_big_z8e.dat lib/firmware/myri10ge_ethp_z8e.dat +lib/firmware/myri10ge_rss_eth_big_z8e.dat lib/firmware/myri10ge_rss_eth_z8e.dat +lib/firmware/myri10ge_rss_ethp_big_z8e.dat lib/firmware/myri10ge_rss_ethp_z8e.dat #lib/firmware/myricom lib/firmware/myricom/lanai.bin #lib/firmware/ositech lib/firmware/ositech/Xilinx7OD.bin lib/firmware/phanfw.bin +lib/firmware/qat_895xcc.bin lib/firmware/ql2100_fw.bin lib/firmware/ql2200_fw.bin lib/firmware/ql2300_fw.bin @@ -618,6 +675,7 @@ lib/firmware/qlogic/isp1000.bin lib/firmware/qlogic/sd7220.fw #lib/firmware/r128 lib/firmware/r128/r128_cce.bin +lib/firmware/r8a779x_usb3_v1.dlmem #lib/firmware/radeon lib/firmware/radeon/ARUBA_me.bin lib/firmware/radeon/ARUBA_pfp.bin @@ -628,6 +686,7 @@ lib/firmware/radeon/BARTS_pfp.bin lib/firmware/radeon/BARTS_smc.bin lib/firmware/radeon/BONAIRE_ce.bin lib/firmware/radeon/BONAIRE_mc.bin +lib/firmware/radeon/BONAIRE_mc2.bin lib/firmware/radeon/BONAIRE_me.bin lib/firmware/radeon/BONAIRE_mec.bin lib/firmware/radeon/BONAIRE_pfp.bin @@ -635,6 +694,7 @@ lib/firmware/radeon/BONAIRE_rlc.bin lib/firmware/radeon/BONAIRE_sdma.bin lib/firmware/radeon/BONAIRE_smc.bin lib/firmware/radeon/BONAIRE_uvd.bin +lib/firmware/radeon/BONAIRE_vce.bin lib/firmware/radeon/BTC_rlc.bin lib/firmware/radeon/CAICOS_mc.bin lib/firmware/radeon/CAICOS_me.bin @@ -656,10 +716,20 @@ lib/firmware/radeon/CYPRESS_smc.bin lib/firmware/radeon/CYPRESS_uvd.bin lib/firmware/radeon/HAINAN_ce.bin lib/firmware/radeon/HAINAN_mc.bin +lib/firmware/radeon/HAINAN_mc2.bin lib/firmware/radeon/HAINAN_me.bin lib/firmware/radeon/HAINAN_pfp.bin lib/firmware/radeon/HAINAN_rlc.bin lib/firmware/radeon/HAINAN_smc.bin +lib/firmware/radeon/HAWAII_ce.bin +lib/firmware/radeon/HAWAII_mc.bin +lib/firmware/radeon/HAWAII_mc2.bin +lib/firmware/radeon/HAWAII_me.bin +lib/firmware/radeon/HAWAII_mec.bin +lib/firmware/radeon/HAWAII_pfp.bin +lib/firmware/radeon/HAWAII_rlc.bin +lib/firmware/radeon/HAWAII_sdma.bin +lib/firmware/radeon/HAWAII_smc.bin lib/firmware/radeon/JUNIPER_me.bin lib/firmware/radeon/JUNIPER_pfp.bin lib/firmware/radeon/JUNIPER_rlc.bin @@ -676,8 +746,15 @@ lib/firmware/radeon/KAVERI_mec.bin lib/firmware/radeon/KAVERI_pfp.bin lib/firmware/radeon/KAVERI_rlc.bin lib/firmware/radeon/KAVERI_sdma.bin +lib/firmware/radeon/MULLINS_ce.bin +lib/firmware/radeon/MULLINS_me.bin +lib/firmware/radeon/MULLINS_mec.bin +lib/firmware/radeon/MULLINS_pfp.bin +lib/firmware/radeon/MULLINS_rlc.bin +lib/firmware/radeon/MULLINS_sdma.bin lib/firmware/radeon/OLAND_ce.bin lib/firmware/radeon/OLAND_mc.bin +lib/firmware/radeon/OLAND_mc2.bin lib/firmware/radeon/OLAND_me.bin lib/firmware/radeon/OLAND_pfp.bin lib/firmware/radeon/OLAND_rlc.bin @@ -686,6 +763,7 @@ lib/firmware/radeon/PALM_me.bin lib/firmware/radeon/PALM_pfp.bin lib/firmware/radeon/PITCAIRN_ce.bin lib/firmware/radeon/PITCAIRN_mc.bin +lib/firmware/radeon/PITCAIRN_mc2.bin lib/firmware/radeon/PITCAIRN_me.bin lib/firmware/radeon/PITCAIRN_pfp.bin lib/firmware/radeon/PITCAIRN_rlc.bin @@ -698,6 +776,7 @@ lib/firmware/radeon/R520_cp.bin lib/firmware/radeon/R600_me.bin lib/firmware/radeon/R600_pfp.bin lib/firmware/radeon/R600_rlc.bin +lib/firmware/radeon/R600_uvd.bin lib/firmware/radeon/R700_rlc.bin lib/firmware/radeon/REDWOOD_me.bin lib/firmware/radeon/REDWOOD_pfp.bin @@ -707,6 +786,7 @@ lib/firmware/radeon/RS600_cp.bin lib/firmware/radeon/RS690_cp.bin lib/firmware/radeon/RS780_me.bin lib/firmware/radeon/RS780_pfp.bin +lib/firmware/radeon/RS780_uvd.bin lib/firmware/radeon/RV610_me.bin lib/firmware/radeon/RV610_pfp.bin lib/firmware/radeon/RV620_me.bin @@ -728,6 +808,7 @@ lib/firmware/radeon/RV740_smc.bin lib/firmware/radeon/RV770_me.bin lib/firmware/radeon/RV770_pfp.bin lib/firmware/radeon/RV770_smc.bin +lib/firmware/radeon/RV770_uvd.bin lib/firmware/radeon/SUMO2_me.bin lib/firmware/radeon/SUMO2_pfp.bin lib/firmware/radeon/SUMO_me.bin @@ -736,6 +817,7 @@ lib/firmware/radeon/SUMO_rlc.bin lib/firmware/radeon/SUMO_uvd.bin lib/firmware/radeon/TAHITI_ce.bin lib/firmware/radeon/TAHITI_mc.bin +lib/firmware/radeon/TAHITI_mc2.bin lib/firmware/radeon/TAHITI_me.bin lib/firmware/radeon/TAHITI_pfp.bin lib/firmware/radeon/TAHITI_rlc.bin @@ -747,11 +829,78 @@ lib/firmware/radeon/TURKS_pfp.bin lib/firmware/radeon/TURKS_smc.bin lib/firmware/radeon/VERDE_ce.bin lib/firmware/radeon/VERDE_mc.bin +lib/firmware/radeon/VERDE_mc2.bin lib/firmware/radeon/VERDE_me.bin lib/firmware/radeon/VERDE_pfp.bin lib/firmware/radeon/VERDE_rlc.bin lib/firmware/radeon/VERDE_smc.bin +lib/firmware/radeon/bonaire_ce.bin +lib/firmware/radeon/bonaire_mc.bin +lib/firmware/radeon/bonaire_me.bin +lib/firmware/radeon/bonaire_mec.bin +lib/firmware/radeon/bonaire_pfp.bin +lib/firmware/radeon/bonaire_rlc.bin +lib/firmware/radeon/bonaire_sdma.bin +lib/firmware/radeon/bonaire_smc.bin +lib/firmware/radeon/hainan_ce.bin +lib/firmware/radeon/hainan_mc.bin +lib/firmware/radeon/hainan_me.bin +lib/firmware/radeon/hainan_pfp.bin +lib/firmware/radeon/hainan_rlc.bin +lib/firmware/radeon/hainan_smc.bin +lib/firmware/radeon/hawaii_ce.bin +lib/firmware/radeon/hawaii_mc.bin +lib/firmware/radeon/hawaii_me.bin +lib/firmware/radeon/hawaii_mec.bin +lib/firmware/radeon/hawaii_pfp.bin +lib/firmware/radeon/hawaii_rlc.bin +lib/firmware/radeon/hawaii_sdma.bin +lib/firmware/radeon/hawaii_smc.bin +lib/firmware/radeon/kabini_ce.bin +lib/firmware/radeon/kabini_me.bin +lib/firmware/radeon/kabini_mec.bin +lib/firmware/radeon/kabini_pfp.bin +lib/firmware/radeon/kabini_rlc.bin +lib/firmware/radeon/kabini_sdma.bin +lib/firmware/radeon/kaveri_ce.bin +lib/firmware/radeon/kaveri_me.bin +lib/firmware/radeon/kaveri_mec.bin +lib/firmware/radeon/kaveri_mec2.bin +lib/firmware/radeon/kaveri_pfp.bin +lib/firmware/radeon/kaveri_rlc.bin +lib/firmware/radeon/kaveri_sdma.bin +lib/firmware/radeon/mullins_ce.bin +lib/firmware/radeon/mullins_me.bin +lib/firmware/radeon/mullins_mec.bin +lib/firmware/radeon/mullins_pfp.bin +lib/firmware/radeon/mullins_rlc.bin +lib/firmware/radeon/mullins_sdma.bin +lib/firmware/radeon/oland_ce.bin +lib/firmware/radeon/oland_mc.bin +lib/firmware/radeon/oland_me.bin +lib/firmware/radeon/oland_pfp.bin +lib/firmware/radeon/oland_rlc.bin +lib/firmware/radeon/oland_smc.bin +lib/firmware/radeon/pitcairn_ce.bin +lib/firmware/radeon/pitcairn_mc.bin +lib/firmware/radeon/pitcairn_me.bin +lib/firmware/radeon/pitcairn_pfp.bin +lib/firmware/radeon/pitcairn_rlc.bin +lib/firmware/radeon/pitcairn_smc.bin +lib/firmware/radeon/tahiti_ce.bin +lib/firmware/radeon/tahiti_mc.bin +lib/firmware/radeon/tahiti_me.bin +lib/firmware/radeon/tahiti_pfp.bin +lib/firmware/radeon/tahiti_rlc.bin +lib/firmware/radeon/tahiti_smc.bin +lib/firmware/radeon/verde_ce.bin +lib/firmware/radeon/verde_mc.bin +lib/firmware/radeon/verde_me.bin +lib/firmware/radeon/verde_pfp.bin +lib/firmware/radeon/verde_rlc.bin +lib/firmware/radeon/verde_smc.bin lib/firmware/rp2.fw +lib/firmware/rsi_91x.fw lib/firmware/rt2561.bin lib/firmware/rt2561s.bin lib/firmware/rt2661.bin @@ -766,6 +915,8 @@ lib/firmware/rt73.bin lib/firmware/rtl_nic/rtl8105e-1.fw lib/firmware/rtl_nic/rtl8106e-1.fw lib/firmware/rtl_nic/rtl8106e-2.fw +lib/firmware/rtl_nic/rtl8107e-1.fw +lib/firmware/rtl_nic/rtl8107e-2.fw lib/firmware/rtl_nic/rtl8168d-1.fw lib/firmware/rtl_nic/rtl8168d-2.fw lib/firmware/rtl_nic/rtl8168e-1.fw @@ -776,6 +927,8 @@ lib/firmware/rtl_nic/rtl8168f-2.fw lib/firmware/rtl_nic/rtl8168g-1.fw lib/firmware/rtl_nic/rtl8168g-2.fw lib/firmware/rtl_nic/rtl8168g-3.fw +lib/firmware/rtl_nic/rtl8168h-1.fw +lib/firmware/rtl_nic/rtl8168h-2.fw lib/firmware/rtl_nic/rtl8402-1.fw lib/firmware/rtl_nic/rtl8411-1.fw lib/firmware/rtl_nic/rtl8411-2.fw @@ -790,15 +943,24 @@ lib/firmware/rtlwifi/rtl8192cufw_A.bin lib/firmware/rtlwifi/rtl8192cufw_B.bin lib/firmware/rtlwifi/rtl8192cufw_TMSC.bin lib/firmware/rtlwifi/rtl8192defw.bin +lib/firmware/rtlwifi/rtl8192eefw.bin lib/firmware/rtlwifi/rtl8192sefw.bin lib/firmware/rtlwifi/rtl8712u.bin +lib/firmware/rtlwifi/rtl8723aufw_A.bin +lib/firmware/rtlwifi/rtl8723aufw_B.bin +lib/firmware/rtlwifi/rtl8723aufw_B_NoBT.bin +lib/firmware/rtlwifi/rtl8723befw.bin lib/firmware/rtlwifi/rtl8723fw.bin lib/firmware/rtlwifi/rtl8723fw_B.bin +lib/firmware/rtlwifi/rtl8821aefw.bin +lib/firmware/rtlwifi/rtl8821aefw_wowlan.bin lib/firmware/s2250.fw lib/firmware/s2250_loader.fw -lib/firmware/s5p-mfc -lib/firmware/s5p-mfc/s5p-mfc-v6.fw -lib/firmware/s5p-mfc/s5p-mfc.fw +lib/firmware/s5p-mfc-v6-v2.fw +lib/firmware/s5p-mfc-v6.fw +lib/firmware/s5p-mfc-v7.fw +lib/firmware/s5p-mfc-v8.fw +lib/firmware/s5p-mfc.fw #lib/firmware/sb16 lib/firmware/sb16/alaw_main.csp lib/firmware/sb16/ima_adpcm_capture.csp @@ -812,11 +974,17 @@ lib/firmware/slicoss/gbrcvucode.sys lib/firmware/slicoss/oasisdbgdownload.sys lib/firmware/slicoss/oasisdownload.sys lib/firmware/slicoss/oasisrcvucode.sys +lib/firmware/sms1xxx-hcw-55xxx-dvbt-02.fw +lib/firmware/sms1xxx-hcw-55xxx-isdbt-02.fw +lib/firmware/sms1xxx-nova-a-dvbt-01.fw +lib/firmware/sms1xxx-nova-b-dvbt-01.fw +lib/firmware/sms1xxx-stellar-dvbt-01.fw #lib/firmware/sun lib/firmware/sun/cassini.bin #lib/firmware/sxg lib/firmware/sxg/saharadbgdownloadB.sys lib/firmware/sxg/saharadownloadB.sys +lib/firmware/tdmb_nova_12mhz.inp #lib/firmware/tehuti lib/firmware/tehuti/bdx.bin #lib/firmware/ti-connectivity @@ -850,6 +1018,8 @@ lib/firmware/ti-connectivity/wl128x-nvs.bin lib/firmware/ti-connectivity/wl12xx-nvs.bin lib/firmware/ti-connectivity/wl18xx-conf.bin lib/firmware/ti-connectivity/wl18xx-fw-2.bin +lib/firmware/ti-connectivity/wl18xx-fw-3.bin +lib/firmware/ti-connectivity/wl18xx-fw-4.bin lib/firmware/ti-connectivity/wl18xx-fw.bin lib/firmware/ti_3410.fw lib/firmware/ti_5052.fw diff --git a/config/rootfiles/common/ntp b/config/rootfiles/common/ntp index 883d4ff..aacdb25 100644 --- a/config/rootfiles/common/ntp +++ b/config/rootfiles/common/ntp @@ -3,6 +3,7 @@ etc/ntp.conf etc/rc.d/rc0.d/K46ntpd etc/rc.d/rc3.d/S26ntpd etc/rc.d/rc6.d/K46ntpd +usr/bin/calc_tickadj usr/bin/ntp-keygen usr/bin/ntp-wait usr/bin/ntpd @@ -13,12 +14,273 @@ usr/bin/ntptime usr/bin/ntptrace usr/bin/sntp usr/bin/tickadj +#usr/include/event2 +#usr/share/doc/ntp4 +#usr/share/doc/ntp4/html +#usr/share/doc/ntp4/html/access.html +#usr/share/doc/ntp4/html/accopt.html +#usr/share/doc/ntp4/html/assoc.html +#usr/share/doc/ntp4/html/audio.html +#usr/share/doc/ntp4/html/authentic.html +#usr/share/doc/ntp4/html/authopt.html +#usr/share/doc/ntp4/html/autokey.html +#usr/share/doc/ntp4/html/bugs.html +#usr/share/doc/ntp4/html/build.html +#usr/share/doc/ntp4/html/clock.html +#usr/share/doc/ntp4/html/clockopt.html +#usr/share/doc/ntp4/html/cluster.html +#usr/share/doc/ntp4/html/comdex.html +#usr/share/doc/ntp4/html/config.html +#usr/share/doc/ntp4/html/confopt.html +#usr/share/doc/ntp4/html/copyright.html +#usr/share/doc/ntp4/html/debug.html +#usr/share/doc/ntp4/html/decode.html +#usr/share/doc/ntp4/html/discipline.html +#usr/share/doc/ntp4/html/discover.html +#usr/share/doc/ntp4/html/drivers +#usr/share/doc/ntp4/html/drivers/driver1.html +#usr/share/doc/ntp4/html/drivers/driver10.html +#usr/share/doc/ntp4/html/drivers/driver11.html +#usr/share/doc/ntp4/html/drivers/driver12.html +#usr/share/doc/ntp4/html/drivers/driver16.html +#usr/share/doc/ntp4/html/drivers/driver18.html +#usr/share/doc/ntp4/html/drivers/driver19.html +#usr/share/doc/ntp4/html/drivers/driver20.html +#usr/share/doc/ntp4/html/drivers/driver22.html +#usr/share/doc/ntp4/html/drivers/driver26.html +#usr/share/doc/ntp4/html/drivers/driver27.html +#usr/share/doc/ntp4/html/drivers/driver28.html +#usr/share/doc/ntp4/html/drivers/driver29.html +#usr/share/doc/ntp4/html/drivers/driver3.html +#usr/share/doc/ntp4/html/drivers/driver30.html +#usr/share/doc/ntp4/html/drivers/driver31.html +#usr/share/doc/ntp4/html/drivers/driver32.html +#usr/share/doc/ntp4/html/drivers/driver33.html +#usr/share/doc/ntp4/html/drivers/driver34.html +#usr/share/doc/ntp4/html/drivers/driver35.html +#usr/share/doc/ntp4/html/drivers/driver36.html +#usr/share/doc/ntp4/html/drivers/driver37.html +#usr/share/doc/ntp4/html/drivers/driver38.html +#usr/share/doc/ntp4/html/drivers/driver39.html +#usr/share/doc/ntp4/html/drivers/driver4.html +#usr/share/doc/ntp4/html/drivers/driver40.html +#usr/share/doc/ntp4/html/drivers/driver42.html +#usr/share/doc/ntp4/html/drivers/driver43.html +#usr/share/doc/ntp4/html/drivers/driver44.html +#usr/share/doc/ntp4/html/drivers/driver45.html +#usr/share/doc/ntp4/html/drivers/driver46.html +#usr/share/doc/ntp4/html/drivers/driver5.html +#usr/share/doc/ntp4/html/drivers/driver6.html +#usr/share/doc/ntp4/html/drivers/driver7.html +#usr/share/doc/ntp4/html/drivers/driver8.html +#usr/share/doc/ntp4/html/drivers/driver9.html +#usr/share/doc/ntp4/html/drivers/icons +#usr/share/doc/ntp4/html/drivers/icons/home.gif +#usr/share/doc/ntp4/html/drivers/icons/mail2.gif +#usr/share/doc/ntp4/html/drivers/mx4200data.html +#usr/share/doc/ntp4/html/drivers/oncore-shmem.html +#usr/share/doc/ntp4/html/drivers/scripts +#usr/share/doc/ntp4/html/drivers/scripts/footer.txt +#usr/share/doc/ntp4/html/drivers/scripts/style.css +#usr/share/doc/ntp4/html/drivers/tf582_4.html +#usr/share/doc/ntp4/html/extern.html +#usr/share/doc/ntp4/html/filter.html +#usr/share/doc/ntp4/html/hints +#usr/share/doc/ntp4/html/hints.html +#usr/share/doc/ntp4/html/hints/a-ux +#usr/share/doc/ntp4/html/hints/aix +#usr/share/doc/ntp4/html/hints/bsdi +#usr/share/doc/ntp4/html/hints/changes +#usr/share/doc/ntp4/html/hints/decosf1 +#usr/share/doc/ntp4/html/hints/decosf2 +#usr/share/doc/ntp4/html/hints/freebsd +#usr/share/doc/ntp4/html/hints/hpux +#usr/share/doc/ntp4/html/hints/linux +#usr/share/doc/ntp4/html/hints/mpeix +#usr/share/doc/ntp4/html/hints/notes-xntp-v3 +#usr/share/doc/ntp4/html/hints/parse +#usr/share/doc/ntp4/html/hints/refclocks +#usr/share/doc/ntp4/html/hints/rs6000 +#usr/share/doc/ntp4/html/hints/sco.html +#usr/share/doc/ntp4/html/hints/sgi +#usr/share/doc/ntp4/html/hints/solaris-dosynctodr.html +#usr/share/doc/ntp4/html/hints/solaris.html +#usr/share/doc/ntp4/html/hints/solaris.xtra.4023118 +#usr/share/doc/ntp4/html/hints/solaris.xtra.4095849 +#usr/share/doc/ntp4/html/hints/solaris.xtra.S99ntpd +#usr/share/doc/ntp4/html/hints/solaris.xtra.patchfreq +#usr/share/doc/ntp4/html/hints/sun4 +#usr/share/doc/ntp4/html/hints/svr4-dell +#usr/share/doc/ntp4/html/hints/svr4_package +#usr/share/doc/ntp4/html/hints/todo +#usr/share/doc/ntp4/html/hints/vxworks.html +#usr/share/doc/ntp4/html/hints/winnt.html +#usr/share/doc/ntp4/html/history.html +#usr/share/doc/ntp4/html/howto.html +#usr/share/doc/ntp4/html/huffpuff.html +#usr/share/doc/ntp4/html/icons +#usr/share/doc/ntp4/html/icons/home.gif +#usr/share/doc/ntp4/html/icons/mail2.gif +#usr/share/doc/ntp4/html/icons/sitemap.png +#usr/share/doc/ntp4/html/index.html +#usr/share/doc/ntp4/html/kern.html +#usr/share/doc/ntp4/html/kernpps.html +#usr/share/doc/ntp4/html/keygen.html +#usr/share/doc/ntp4/html/leap.html +#usr/share/doc/ntp4/html/miscopt.html +#usr/share/doc/ntp4/html/monopt.html +#usr/share/doc/ntp4/html/msyslog.html +#usr/share/doc/ntp4/html/ntp-wait.html +#usr/share/doc/ntp4/html/ntp_conf.html +#usr/share/doc/ntp4/html/ntpd.html +#usr/share/doc/ntp4/html/ntpdate.html +#usr/share/doc/ntp4/html/ntpdc.html +#usr/share/doc/ntp4/html/ntpdsim.html +#usr/share/doc/ntp4/html/ntpdsim_new.html +#usr/share/doc/ntp4/html/ntpq.html +#usr/share/doc/ntp4/html/ntptime.html +#usr/share/doc/ntp4/html/ntptrace.html +#usr/share/doc/ntp4/html/orphan.html +#usr/share/doc/ntp4/html/parsedata.html +#usr/share/doc/ntp4/html/parsenew.html +#usr/share/doc/ntp4/html/pic +#usr/share/doc/ntp4/html/pic/9400n.jpg +#usr/share/doc/ntp4/html/pic/alice11.gif +#usr/share/doc/ntp4/html/pic/alice13.gif +#usr/share/doc/ntp4/html/pic/alice15.gif +#usr/share/doc/ntp4/html/pic/alice23.gif +#usr/share/doc/ntp4/html/pic/alice31.gif +#usr/share/doc/ntp4/html/pic/alice32.gif +#usr/share/doc/ntp4/html/pic/alice35.gif +#usr/share/doc/ntp4/html/pic/alice38.gif +#usr/share/doc/ntp4/html/pic/alice44.gif +#usr/share/doc/ntp4/html/pic/alice47.gif +#usr/share/doc/ntp4/html/pic/alice51.gif +#usr/share/doc/ntp4/html/pic/alice61.gif +#usr/share/doc/ntp4/html/pic/barnstable.gif +#usr/share/doc/ntp4/html/pic/beaver.gif +#usr/share/doc/ntp4/html/pic/boom3.gif +#usr/share/doc/ntp4/html/pic/boom3a.gif +#usr/share/doc/ntp4/html/pic/boom4.gif +#usr/share/doc/ntp4/html/pic/broad.gif +#usr/share/doc/ntp4/html/pic/bustardfly.gif +#usr/share/doc/ntp4/html/pic/c51.jpg +#usr/share/doc/ntp4/html/pic/description.jpg +#usr/share/doc/ntp4/html/pic/discipline.gif +#usr/share/doc/ntp4/html/pic/dogsnake.gif +#usr/share/doc/ntp4/html/pic/driver29.gif +#usr/share/doc/ntp4/html/pic/driver43_1.gif +#usr/share/doc/ntp4/html/pic/driver43_2.jpg +#usr/share/doc/ntp4/html/pic/fg6021.gif +#usr/share/doc/ntp4/html/pic/fg6039.jpg +#usr/share/doc/ntp4/html/pic/fig_3_1.gif +#usr/share/doc/ntp4/html/pic/flatheads.gif +#usr/share/doc/ntp4/html/pic/flt1.gif +#usr/share/doc/ntp4/html/pic/flt2.gif +#usr/share/doc/ntp4/html/pic/flt3.gif +#usr/share/doc/ntp4/html/pic/flt4.gif +#usr/share/doc/ntp4/html/pic/flt5.gif +#usr/share/doc/ntp4/html/pic/flt6.gif +#usr/share/doc/ntp4/html/pic/flt7.gif +#usr/share/doc/ntp4/html/pic/flt8.gif +#usr/share/doc/ntp4/html/pic/flt9.gif +#usr/share/doc/ntp4/html/pic/freq1211.gif +#usr/share/doc/ntp4/html/pic/gadget.jpg +#usr/share/doc/ntp4/html/pic/gps167.jpg +#usr/share/doc/ntp4/html/pic/group.gif +#usr/share/doc/ntp4/html/pic/hornraba.gif +#usr/share/doc/ntp4/html/pic/igclock.gif +#usr/share/doc/ntp4/html/pic/neoclock4x.gif +#usr/share/doc/ntp4/html/pic/offset1211.gif +#usr/share/doc/ntp4/html/pic/oncore_evalbig.gif +#usr/share/doc/ntp4/html/pic/oncore_remoteant.jpg +#usr/share/doc/ntp4/html/pic/oncore_utplusbig.gif +#usr/share/doc/ntp4/html/pic/oz2.gif +#usr/share/doc/ntp4/html/pic/panda.gif +#usr/share/doc/ntp4/html/pic/pd_om006.gif +#usr/share/doc/ntp4/html/pic/pd_om011.gif +#usr/share/doc/ntp4/html/pic/peer.gif +#usr/share/doc/ntp4/html/pic/pogo.gif +#usr/share/doc/ntp4/html/pic/pogo1a.gif +#usr/share/doc/ntp4/html/pic/pogo3a.gif +#usr/share/doc/ntp4/html/pic/pogo4.gif +#usr/share/doc/ntp4/html/pic/pogo5.gif +#usr/share/doc/ntp4/html/pic/pogo6.gif +#usr/share/doc/ntp4/html/pic/pogo7.gif +#usr/share/doc/ntp4/html/pic/pogo8.gif +#usr/share/doc/ntp4/html/pic/pzf509.jpg +#usr/share/doc/ntp4/html/pic/pzf511.jpg +#usr/share/doc/ntp4/html/pic/rabbit.gif +#usr/share/doc/ntp4/html/pic/radio2.jpg +#usr/share/doc/ntp4/html/pic/sheepb.jpg +#usr/share/doc/ntp4/html/pic/stack1a.jpg +#usr/share/doc/ntp4/html/pic/stats.gif +#usr/share/doc/ntp4/html/pic/sx5.gif +#usr/share/doc/ntp4/html/pic/thunderbolt.jpg +#usr/share/doc/ntp4/html/pic/time1.gif +#usr/share/doc/ntp4/html/pic/tonea.gif +#usr/share/doc/ntp4/html/pic/tribeb.gif +#usr/share/doc/ntp4/html/pic/wingdorothy.gif +#usr/share/doc/ntp4/html/poll.html +#usr/share/doc/ntp4/html/pps.html +#usr/share/doc/ntp4/html/prefer.html +#usr/share/doc/ntp4/html/quick.html +#usr/share/doc/ntp4/html/rate.html +#usr/share/doc/ntp4/html/rdebug.html +#usr/share/doc/ntp4/html/refclock.html +#usr/share/doc/ntp4/html/release.html +#usr/share/doc/ntp4/html/scripts +#usr/share/doc/ntp4/html/scripts/accopt.txt +#usr/share/doc/ntp4/html/scripts/audio.txt +#usr/share/doc/ntp4/html/scripts/authopt.txt +#usr/share/doc/ntp4/html/scripts/clockopt.txt +#usr/share/doc/ntp4/html/scripts/command.txt +#usr/share/doc/ntp4/html/scripts/config.txt +#usr/share/doc/ntp4/html/scripts/confopt.txt +#usr/share/doc/ntp4/html/scripts/external.txt +#usr/share/doc/ntp4/html/scripts/footer.txt +#usr/share/doc/ntp4/html/scripts/hand.txt +#usr/share/doc/ntp4/html/scripts/install.txt +#usr/share/doc/ntp4/html/scripts/manual.txt +#usr/share/doc/ntp4/html/scripts/misc.txt +#usr/share/doc/ntp4/html/scripts/miscopt.txt +#usr/share/doc/ntp4/html/scripts/monopt.txt +#usr/share/doc/ntp4/html/scripts/refclock.txt +#usr/share/doc/ntp4/html/scripts/special.txt +#usr/share/doc/ntp4/html/scripts/style.css +#usr/share/doc/ntp4/html/select.html +#usr/share/doc/ntp4/html/sitemap.html +#usr/share/doc/ntp4/html/sntp.html +#usr/share/doc/ntp4/html/stats.html +#usr/share/doc/ntp4/html/tickadj.html +#usr/share/doc/ntp4/html/warp.html +#usr/share/doc/ntp4/html/xleave.html +#usr/share/doc/ntp4/ntp-keygen.html +#usr/share/doc/ntp4/ntp-wait.html +#usr/share/doc/ntp4/ntp.conf.html +#usr/share/doc/ntp4/ntp.keys.html +#usr/share/doc/ntp4/ntpd.html +#usr/share/doc/ntp4/ntpdc.html +#usr/share/doc/ntp4/ntpq.html +#usr/share/doc/ntp4/ntpsnmpd.html +#usr/share/doc/ntp4/ntpsweep.html +#usr/share/doc/ntp4/ntptrace.html +#usr/share/doc/sntp +#usr/share/doc/sntp/sntp.html +#usr/share/man/man1/calc_tickadj.1 #usr/share/man/man1/ntp-keygen.1 +#usr/share/man/man1/ntp-wait.1 #usr/share/man/man1/ntpd.1 #usr/share/man/man1/ntpdc.1 #usr/share/man/man1/ntpq.1 -#usr/share/man/man1/ntpsnmpd.1 +#usr/share/man/man1/ntptrace.1 #usr/share/man/man1/sntp.1 +#usr/share/man/man5/ntp.conf.5 +#usr/share/man/man5/ntp.keys.5 +#usr/share/ntp +#usr/share/ntp/lib +#usr/share/ntp/lib/NTP +#usr/share/ntp/lib/NTP/Util.pm var/ipfire/time/counter.conf var/ipfire/time/enable var/ipfire/time/settime.conf diff --git a/config/rootfiles/common/stage2 b/config/rootfiles/common/stage2 index eb97040..9a4d8ed 100644 --- a/config/rootfiles/common/stage2 +++ b/config/rootfiles/common/stage2 @@ -95,6 +95,7 @@ usr/local/bin/settime usr/local/bin/timecheck usr/local/bin/timezone-transition #usr/local/bin/uname +usr/local/bin/update-bootloader usr/local/bin/update-lang-cache #usr/local/include #usr/local/lib diff --git a/config/rootfiles/core/86/filelists/armv5tel/u-boot b/config/rootfiles/core/86/filelists/armv5tel/u-boot new file mode 120000 index 0000000..3df31a8 --- /dev/null +++ b/config/rootfiles/core/86/filelists/armv5tel/u-boot @@ -0,0 +1 @@ +../../../../common/armv5tel/u-boot \ No newline at end of file diff --git a/config/rootfiles/core/86/filelists/bash b/config/rootfiles/core/86/filelists/bash new file mode 120000 index 0000000..de970cb --- /dev/null +++ b/config/rootfiles/core/86/filelists/bash @@ -0,0 +1 @@ +../../../common/bash \ No newline at end of file diff --git a/config/rootfiles/core/86/filelists/crda b/config/rootfiles/core/86/filelists/crda new file mode 120000 index 0000000..d68c46e --- /dev/null +++ b/config/rootfiles/core/86/filelists/crda @@ -0,0 +1 @@ +../../../common/crda \ No newline at end of file diff --git a/config/rootfiles/core/86/filelists/files b/config/rootfiles/core/86/filelists/files index cfcb0cc..dcdb65c 100644 --- a/config/rootfiles/core/86/filelists/files +++ b/config/rootfiles/core/86/filelists/files @@ -1,5 +1,8 @@ etc/system-release etc/issue +opt/pakfire/etc/pakfire.conf +usr/lib/firewall/rules.pl +usr/local/bin/update-bootloader var/ipfire/header.pl var/ipfire/langs var/ipfire/lang.pl diff --git a/config/rootfiles/core/86/filelists/iw b/config/rootfiles/core/86/filelists/iw new file mode 120000 index 0000000..7c58a20 --- /dev/null +++ b/config/rootfiles/core/86/filelists/iw @@ -0,0 +1 @@ +../../../common/iw \ No newline at end of file diff --git a/config/rootfiles/core/86/filelists/kbd b/config/rootfiles/core/86/filelists/kbd new file mode 120000 index 0000000..9b85839 --- /dev/null +++ b/config/rootfiles/core/86/filelists/kbd @@ -0,0 +1 @@ +../../../common/kbd \ No newline at end of file diff --git a/config/rootfiles/core/86/filelists/ntp b/config/rootfiles/core/86/filelists/ntp new file mode 100644 index 0000000..aacdb25 --- /dev/null +++ b/config/rootfiles/core/86/filelists/ntp @@ -0,0 +1,287 @@ +etc/ntp +etc/ntp.conf +etc/rc.d/rc0.d/K46ntpd +etc/rc.d/rc3.d/S26ntpd +etc/rc.d/rc6.d/K46ntpd +usr/bin/calc_tickadj +usr/bin/ntp-keygen +usr/bin/ntp-wait +usr/bin/ntpd +usr/bin/ntpdate +usr/bin/ntpdc +usr/bin/ntpq +usr/bin/ntptime +usr/bin/ntptrace +usr/bin/sntp +usr/bin/tickadj +#usr/include/event2 +#usr/share/doc/ntp4 +#usr/share/doc/ntp4/html +#usr/share/doc/ntp4/html/access.html +#usr/share/doc/ntp4/html/accopt.html +#usr/share/doc/ntp4/html/assoc.html +#usr/share/doc/ntp4/html/audio.html +#usr/share/doc/ntp4/html/authentic.html +#usr/share/doc/ntp4/html/authopt.html +#usr/share/doc/ntp4/html/autokey.html +#usr/share/doc/ntp4/html/bugs.html +#usr/share/doc/ntp4/html/build.html +#usr/share/doc/ntp4/html/clock.html +#usr/share/doc/ntp4/html/clockopt.html +#usr/share/doc/ntp4/html/cluster.html +#usr/share/doc/ntp4/html/comdex.html +#usr/share/doc/ntp4/html/config.html +#usr/share/doc/ntp4/html/confopt.html +#usr/share/doc/ntp4/html/copyright.html +#usr/share/doc/ntp4/html/debug.html +#usr/share/doc/ntp4/html/decode.html +#usr/share/doc/ntp4/html/discipline.html +#usr/share/doc/ntp4/html/discover.html +#usr/share/doc/ntp4/html/drivers +#usr/share/doc/ntp4/html/drivers/driver1.html +#usr/share/doc/ntp4/html/drivers/driver10.html +#usr/share/doc/ntp4/html/drivers/driver11.html +#usr/share/doc/ntp4/html/drivers/driver12.html +#usr/share/doc/ntp4/html/drivers/driver16.html +#usr/share/doc/ntp4/html/drivers/driver18.html +#usr/share/doc/ntp4/html/drivers/driver19.html +#usr/share/doc/ntp4/html/drivers/driver20.html +#usr/share/doc/ntp4/html/drivers/driver22.html +#usr/share/doc/ntp4/html/drivers/driver26.html +#usr/share/doc/ntp4/html/drivers/driver27.html +#usr/share/doc/ntp4/html/drivers/driver28.html +#usr/share/doc/ntp4/html/drivers/driver29.html +#usr/share/doc/ntp4/html/drivers/driver3.html +#usr/share/doc/ntp4/html/drivers/driver30.html +#usr/share/doc/ntp4/html/drivers/driver31.html +#usr/share/doc/ntp4/html/drivers/driver32.html +#usr/share/doc/ntp4/html/drivers/driver33.html +#usr/share/doc/ntp4/html/drivers/driver34.html +#usr/share/doc/ntp4/html/drivers/driver35.html +#usr/share/doc/ntp4/html/drivers/driver36.html +#usr/share/doc/ntp4/html/drivers/driver37.html +#usr/share/doc/ntp4/html/drivers/driver38.html +#usr/share/doc/ntp4/html/drivers/driver39.html +#usr/share/doc/ntp4/html/drivers/driver4.html +#usr/share/doc/ntp4/html/drivers/driver40.html +#usr/share/doc/ntp4/html/drivers/driver42.html +#usr/share/doc/ntp4/html/drivers/driver43.html +#usr/share/doc/ntp4/html/drivers/driver44.html +#usr/share/doc/ntp4/html/drivers/driver45.html +#usr/share/doc/ntp4/html/drivers/driver46.html +#usr/share/doc/ntp4/html/drivers/driver5.html +#usr/share/doc/ntp4/html/drivers/driver6.html +#usr/share/doc/ntp4/html/drivers/driver7.html +#usr/share/doc/ntp4/html/drivers/driver8.html +#usr/share/doc/ntp4/html/drivers/driver9.html +#usr/share/doc/ntp4/html/drivers/icons +#usr/share/doc/ntp4/html/drivers/icons/home.gif +#usr/share/doc/ntp4/html/drivers/icons/mail2.gif +#usr/share/doc/ntp4/html/drivers/mx4200data.html +#usr/share/doc/ntp4/html/drivers/oncore-shmem.html +#usr/share/doc/ntp4/html/drivers/scripts +#usr/share/doc/ntp4/html/drivers/scripts/footer.txt +#usr/share/doc/ntp4/html/drivers/scripts/style.css +#usr/share/doc/ntp4/html/drivers/tf582_4.html +#usr/share/doc/ntp4/html/extern.html +#usr/share/doc/ntp4/html/filter.html +#usr/share/doc/ntp4/html/hints +#usr/share/doc/ntp4/html/hints.html +#usr/share/doc/ntp4/html/hints/a-ux +#usr/share/doc/ntp4/html/hints/aix +#usr/share/doc/ntp4/html/hints/bsdi +#usr/share/doc/ntp4/html/hints/changes +#usr/share/doc/ntp4/html/hints/decosf1 +#usr/share/doc/ntp4/html/hints/decosf2 +#usr/share/doc/ntp4/html/hints/freebsd +#usr/share/doc/ntp4/html/hints/hpux +#usr/share/doc/ntp4/html/hints/linux +#usr/share/doc/ntp4/html/hints/mpeix +#usr/share/doc/ntp4/html/hints/notes-xntp-v3 +#usr/share/doc/ntp4/html/hints/parse +#usr/share/doc/ntp4/html/hints/refclocks +#usr/share/doc/ntp4/html/hints/rs6000 +#usr/share/doc/ntp4/html/hints/sco.html +#usr/share/doc/ntp4/html/hints/sgi +#usr/share/doc/ntp4/html/hints/solaris-dosynctodr.html +#usr/share/doc/ntp4/html/hints/solaris.html +#usr/share/doc/ntp4/html/hints/solaris.xtra.4023118 +#usr/share/doc/ntp4/html/hints/solaris.xtra.4095849 +#usr/share/doc/ntp4/html/hints/solaris.xtra.S99ntpd +#usr/share/doc/ntp4/html/hints/solaris.xtra.patchfreq +#usr/share/doc/ntp4/html/hints/sun4 +#usr/share/doc/ntp4/html/hints/svr4-dell +#usr/share/doc/ntp4/html/hints/svr4_package +#usr/share/doc/ntp4/html/hints/todo +#usr/share/doc/ntp4/html/hints/vxworks.html +#usr/share/doc/ntp4/html/hints/winnt.html +#usr/share/doc/ntp4/html/history.html +#usr/share/doc/ntp4/html/howto.html +#usr/share/doc/ntp4/html/huffpuff.html +#usr/share/doc/ntp4/html/icons +#usr/share/doc/ntp4/html/icons/home.gif +#usr/share/doc/ntp4/html/icons/mail2.gif +#usr/share/doc/ntp4/html/icons/sitemap.png +#usr/share/doc/ntp4/html/index.html +#usr/share/doc/ntp4/html/kern.html +#usr/share/doc/ntp4/html/kernpps.html +#usr/share/doc/ntp4/html/keygen.html +#usr/share/doc/ntp4/html/leap.html +#usr/share/doc/ntp4/html/miscopt.html +#usr/share/doc/ntp4/html/monopt.html +#usr/share/doc/ntp4/html/msyslog.html +#usr/share/doc/ntp4/html/ntp-wait.html +#usr/share/doc/ntp4/html/ntp_conf.html +#usr/share/doc/ntp4/html/ntpd.html +#usr/share/doc/ntp4/html/ntpdate.html +#usr/share/doc/ntp4/html/ntpdc.html +#usr/share/doc/ntp4/html/ntpdsim.html +#usr/share/doc/ntp4/html/ntpdsim_new.html +#usr/share/doc/ntp4/html/ntpq.html +#usr/share/doc/ntp4/html/ntptime.html +#usr/share/doc/ntp4/html/ntptrace.html +#usr/share/doc/ntp4/html/orphan.html +#usr/share/doc/ntp4/html/parsedata.html +#usr/share/doc/ntp4/html/parsenew.html +#usr/share/doc/ntp4/html/pic +#usr/share/doc/ntp4/html/pic/9400n.jpg +#usr/share/doc/ntp4/html/pic/alice11.gif +#usr/share/doc/ntp4/html/pic/alice13.gif +#usr/share/doc/ntp4/html/pic/alice15.gif +#usr/share/doc/ntp4/html/pic/alice23.gif +#usr/share/doc/ntp4/html/pic/alice31.gif +#usr/share/doc/ntp4/html/pic/alice32.gif +#usr/share/doc/ntp4/html/pic/alice35.gif +#usr/share/doc/ntp4/html/pic/alice38.gif +#usr/share/doc/ntp4/html/pic/alice44.gif +#usr/share/doc/ntp4/html/pic/alice47.gif +#usr/share/doc/ntp4/html/pic/alice51.gif +#usr/share/doc/ntp4/html/pic/alice61.gif +#usr/share/doc/ntp4/html/pic/barnstable.gif +#usr/share/doc/ntp4/html/pic/beaver.gif +#usr/share/doc/ntp4/html/pic/boom3.gif +#usr/share/doc/ntp4/html/pic/boom3a.gif +#usr/share/doc/ntp4/html/pic/boom4.gif +#usr/share/doc/ntp4/html/pic/broad.gif +#usr/share/doc/ntp4/html/pic/bustardfly.gif +#usr/share/doc/ntp4/html/pic/c51.jpg +#usr/share/doc/ntp4/html/pic/description.jpg +#usr/share/doc/ntp4/html/pic/discipline.gif +#usr/share/doc/ntp4/html/pic/dogsnake.gif +#usr/share/doc/ntp4/html/pic/driver29.gif +#usr/share/doc/ntp4/html/pic/driver43_1.gif +#usr/share/doc/ntp4/html/pic/driver43_2.jpg +#usr/share/doc/ntp4/html/pic/fg6021.gif +#usr/share/doc/ntp4/html/pic/fg6039.jpg +#usr/share/doc/ntp4/html/pic/fig_3_1.gif +#usr/share/doc/ntp4/html/pic/flatheads.gif +#usr/share/doc/ntp4/html/pic/flt1.gif +#usr/share/doc/ntp4/html/pic/flt2.gif +#usr/share/doc/ntp4/html/pic/flt3.gif +#usr/share/doc/ntp4/html/pic/flt4.gif +#usr/share/doc/ntp4/html/pic/flt5.gif +#usr/share/doc/ntp4/html/pic/flt6.gif +#usr/share/doc/ntp4/html/pic/flt7.gif +#usr/share/doc/ntp4/html/pic/flt8.gif +#usr/share/doc/ntp4/html/pic/flt9.gif +#usr/share/doc/ntp4/html/pic/freq1211.gif +#usr/share/doc/ntp4/html/pic/gadget.jpg +#usr/share/doc/ntp4/html/pic/gps167.jpg +#usr/share/doc/ntp4/html/pic/group.gif +#usr/share/doc/ntp4/html/pic/hornraba.gif +#usr/share/doc/ntp4/html/pic/igclock.gif +#usr/share/doc/ntp4/html/pic/neoclock4x.gif +#usr/share/doc/ntp4/html/pic/offset1211.gif +#usr/share/doc/ntp4/html/pic/oncore_evalbig.gif +#usr/share/doc/ntp4/html/pic/oncore_remoteant.jpg +#usr/share/doc/ntp4/html/pic/oncore_utplusbig.gif +#usr/share/doc/ntp4/html/pic/oz2.gif +#usr/share/doc/ntp4/html/pic/panda.gif +#usr/share/doc/ntp4/html/pic/pd_om006.gif +#usr/share/doc/ntp4/html/pic/pd_om011.gif +#usr/share/doc/ntp4/html/pic/peer.gif +#usr/share/doc/ntp4/html/pic/pogo.gif +#usr/share/doc/ntp4/html/pic/pogo1a.gif +#usr/share/doc/ntp4/html/pic/pogo3a.gif +#usr/share/doc/ntp4/html/pic/pogo4.gif +#usr/share/doc/ntp4/html/pic/pogo5.gif +#usr/share/doc/ntp4/html/pic/pogo6.gif +#usr/share/doc/ntp4/html/pic/pogo7.gif +#usr/share/doc/ntp4/html/pic/pogo8.gif +#usr/share/doc/ntp4/html/pic/pzf509.jpg +#usr/share/doc/ntp4/html/pic/pzf511.jpg +#usr/share/doc/ntp4/html/pic/rabbit.gif +#usr/share/doc/ntp4/html/pic/radio2.jpg +#usr/share/doc/ntp4/html/pic/sheepb.jpg +#usr/share/doc/ntp4/html/pic/stack1a.jpg +#usr/share/doc/ntp4/html/pic/stats.gif +#usr/share/doc/ntp4/html/pic/sx5.gif +#usr/share/doc/ntp4/html/pic/thunderbolt.jpg +#usr/share/doc/ntp4/html/pic/time1.gif +#usr/share/doc/ntp4/html/pic/tonea.gif +#usr/share/doc/ntp4/html/pic/tribeb.gif +#usr/share/doc/ntp4/html/pic/wingdorothy.gif +#usr/share/doc/ntp4/html/poll.html +#usr/share/doc/ntp4/html/pps.html +#usr/share/doc/ntp4/html/prefer.html +#usr/share/doc/ntp4/html/quick.html +#usr/share/doc/ntp4/html/rate.html +#usr/share/doc/ntp4/html/rdebug.html +#usr/share/doc/ntp4/html/refclock.html +#usr/share/doc/ntp4/html/release.html +#usr/share/doc/ntp4/html/scripts +#usr/share/doc/ntp4/html/scripts/accopt.txt +#usr/share/doc/ntp4/html/scripts/audio.txt +#usr/share/doc/ntp4/html/scripts/authopt.txt +#usr/share/doc/ntp4/html/scripts/clockopt.txt +#usr/share/doc/ntp4/html/scripts/command.txt +#usr/share/doc/ntp4/html/scripts/config.txt +#usr/share/doc/ntp4/html/scripts/confopt.txt +#usr/share/doc/ntp4/html/scripts/external.txt +#usr/share/doc/ntp4/html/scripts/footer.txt +#usr/share/doc/ntp4/html/scripts/hand.txt +#usr/share/doc/ntp4/html/scripts/install.txt +#usr/share/doc/ntp4/html/scripts/manual.txt +#usr/share/doc/ntp4/html/scripts/misc.txt +#usr/share/doc/ntp4/html/scripts/miscopt.txt +#usr/share/doc/ntp4/html/scripts/monopt.txt +#usr/share/doc/ntp4/html/scripts/refclock.txt +#usr/share/doc/ntp4/html/scripts/special.txt +#usr/share/doc/ntp4/html/scripts/style.css +#usr/share/doc/ntp4/html/select.html +#usr/share/doc/ntp4/html/sitemap.html +#usr/share/doc/ntp4/html/sntp.html +#usr/share/doc/ntp4/html/stats.html +#usr/share/doc/ntp4/html/tickadj.html +#usr/share/doc/ntp4/html/warp.html +#usr/share/doc/ntp4/html/xleave.html +#usr/share/doc/ntp4/ntp-keygen.html +#usr/share/doc/ntp4/ntp-wait.html +#usr/share/doc/ntp4/ntp.conf.html +#usr/share/doc/ntp4/ntp.keys.html +#usr/share/doc/ntp4/ntpd.html +#usr/share/doc/ntp4/ntpdc.html +#usr/share/doc/ntp4/ntpq.html +#usr/share/doc/ntp4/ntpsnmpd.html +#usr/share/doc/ntp4/ntpsweep.html +#usr/share/doc/ntp4/ntptrace.html +#usr/share/doc/sntp +#usr/share/doc/sntp/sntp.html +#usr/share/man/man1/calc_tickadj.1 +#usr/share/man/man1/ntp-keygen.1 +#usr/share/man/man1/ntp-wait.1 +#usr/share/man/man1/ntpd.1 +#usr/share/man/man1/ntpdc.1 +#usr/share/man/man1/ntpq.1 +#usr/share/man/man1/ntptrace.1 +#usr/share/man/man1/sntp.1 +#usr/share/man/man5/ntp.conf.5 +#usr/share/man/man5/ntp.keys.5 +#usr/share/ntp +#usr/share/ntp/lib +#usr/share/ntp/lib/NTP +#usr/share/ntp/lib/NTP/Util.pm +var/ipfire/time/counter.conf +var/ipfire/time/enable +var/ipfire/time/settime.conf +var/ipfire/time/settings diff --git a/config/rootfiles/core/86/filelists/openssl b/config/rootfiles/core/86/filelists/openssl new file mode 120000 index 0000000..e011a92 --- /dev/null +++ b/config/rootfiles/core/86/filelists/openssl @@ -0,0 +1 @@ +../../../common/openssl \ No newline at end of file diff --git a/config/rootfiles/core/86/filelists/openssl-compat b/config/rootfiles/core/86/filelists/openssl-compat new file mode 120000 index 0000000..c9fa421 --- /dev/null +++ b/config/rootfiles/core/86/filelists/openssl-compat @@ -0,0 +1 @@ +../../../common/openssl-compat \ No newline at end of file diff --git a/config/rootfiles/core/86/filelists/updated-firmwares b/config/rootfiles/core/86/filelists/updated-firmwares new file mode 100644 index 0000000..6a7a43c --- /dev/null +++ b/config/rootfiles/core/86/filelists/updated-firmwares @@ -0,0 +1,202 @@ +lib/firmware/amd-ucode/microcode_amd_fam15h.bin +lib/firmware/amd-ucode/microcode_amd_fam15h.bin.asc +lib/firmware/amd-ucode/microcode_amd_fam16h.bin +lib/firmware/amd-ucode/microcode_amd_fam16h.bin.asc +lib/firmware/as102_data1_st.hex +lib/firmware/as102_data2_st.hex +lib/firmware/bnx2x/bnx2x-e1-7.10.51.0.fw +lib/firmware/bnx2x/bnx2x-e1-7.8.19.0.fw +lib/firmware/bnx2x/bnx2x-e1h-7.10.51.0.fw +lib/firmware/bnx2x/bnx2x-e1h-7.8.19.0.fw +lib/firmware/bnx2x/bnx2x-e2-7.10.51.0.fw +lib/firmware/bnx2x/bnx2x-e2-7.8.19.0.fw +lib/firmware/brcm/brcmfmac43143.bin +lib/firmware/brcm/brcmfmac43143-sdio.bin +lib/firmware/brcm/brcmfmac43362-sdio.bin +lib/firmware/brcm/brcmfmac4354-sdio.bin +lib/firmware/cmmb_vega_12mhz.inp +lib/firmware/cmmb_venice_12mhz.inp +lib/firmware/cxgb4/t4fw-1.12.25.0.bin +lib/firmware/cxgb4/t4fw.bin +lib/firmware/cxgb4/t5fw-1.12.25.0.bin +lib/firmware/cxgb4/t5fw.bin +lib/firmware/dvb-fe-drxj-mc-1.0.8.fw +lib/firmware/dvb-fe-drxj-mc-vsb-1.0.8.fw +lib/firmware/dvb-fe-drxj-mc-vsb-qam-1.0.8.fw +lib/firmware/dvb-fe-xc4000-1.4.1.fw +lib/firmware/dvb-fe-xc5000c-4.1.30.7.fw +lib/firmware/dvb_nova_12mhz_b0.inp +lib/firmware/dvb_nova_12mhz.inp +lib/firmware/dvb-usb-it9135-01.fw +lib/firmware/dvb-usb-it9135-02.fw +lib/firmware/emi62/bitstream.fw +lib/firmware/intel/fw_sst_0f28.bin +lib/firmware/intel/fw_sst_0f28.bin-48kHz_i2s_master +lib/firmware/intel/ibt-hw-37.7.10-fw-1.0.1.2d.d.bseq +lib/firmware/intel/ibt-hw-37.7.10-fw-1.0.2.3.d.bseq +lib/firmware/intel/ibt-hw-37.7.10-fw-1.80.1.2d.d.bseq +lib/firmware/intel/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq +lib/firmware/intel/ibt-hw-37.8.10-fw-1.10.2.27.d.bseq +lib/firmware/intel/ibt-hw-37.8.10-fw-1.10.3.11.e.bseq +lib/firmware/intel/ibt-hw-37.8.bseq +lib/firmware/intel/IntcSST2.bin +lib/firmware/isdbt_nova_12mhz_b0.inp +lib/firmware/isdbt_nova_12mhz.inp +lib/firmware/isdbt_rio.inp +lib/firmware/iwlwifi-3160-10.ucode +lib/firmware/iwlwifi-3160-8.ucode +lib/firmware/iwlwifi-3160-9.ucode +lib/firmware/iwlwifi-7260-10.ucode +lib/firmware/iwlwifi-7260-8.ucode +lib/firmware/iwlwifi-7260-9.ucode +lib/firmware/iwlwifi-7265-10.ucode +lib/firmware/iwlwifi-7265-8.ucode +lib/firmware/iwlwifi-7265-9.ucode +lib/firmware/iwlwifi-7265D-10.ucode +lib/firmware/LICENCE.Abilis +lib/firmware/LICENCE.chelsio_firmware +lib/firmware/LICENCE.fw_sst_0f28 +lib/firmware/LICENCE.ibt_firmware +lib/firmware/LICENCE.IntcSST2 +lib/firmware/LICENCE.it913x +lib/firmware/LICENCE.iwlwifi_firmware +lib/firmware/LICENCE.qat_dh895xcc_firmware +lib/firmware/LICENCE.r8a779x_usb3 +lib/firmware/LICENCE.siano +lib/firmware/LICENCE.xc4000 +lib/firmware/LICENCE.xc5000c +lib/firmware/LICENSE.amd-ucode +lib/firmware/LICENSE.radeon +lib/firmware/myri10ge_eth_big_z8e.dat +lib/firmware/myri10ge_ethp_big_z8e.dat +lib/firmware/myri10ge_ethp_z8e.dat +lib/firmware/myri10ge_eth_z8e.dat +lib/firmware/myri10ge_rss_eth_big_z8e.dat +lib/firmware/myri10ge_rss_ethp_big_z8e.dat +lib/firmware/myri10ge_rss_ethp_z8e.dat +lib/firmware/myri10ge_rss_eth_z8e.dat +lib/firmware/qat_895xcc.bin +lib/firmware/ql2400_fw.bin +lib/firmware/ql2500_fw.bin +lib/firmware/r8a779x_usb3_v1.dlmem +lib/firmware/radeon/bonaire_ce.bin +lib/firmware/radeon/BONAIRE_mc2.bin +lib/firmware/radeon/bonaire_mc.bin +lib/firmware/radeon/bonaire_me.bin +lib/firmware/radeon/bonaire_mec.bin +lib/firmware/radeon/bonaire_pfp.bin +lib/firmware/radeon/bonaire_rlc.bin +lib/firmware/radeon/bonaire_sdma.bin +lib/firmware/radeon/bonaire_smc.bin +lib/firmware/radeon/BONAIRE_vce.bin +lib/firmware/radeon/hainan_ce.bin +lib/firmware/radeon/HAINAN_mc2.bin +lib/firmware/radeon/hainan_mc.bin +lib/firmware/radeon/hainan_me.bin +lib/firmware/radeon/hainan_pfp.bin +lib/firmware/radeon/hainan_rlc.bin +lib/firmware/radeon/hainan_smc.bin +lib/firmware/radeon/hawaii_ce.bin +lib/firmware/radeon/HAWAII_ce.bin +lib/firmware/radeon/HAWAII_mc2.bin +lib/firmware/radeon/hawaii_mc.bin +lib/firmware/radeon/HAWAII_mc.bin +lib/firmware/radeon/hawaii_me.bin +lib/firmware/radeon/HAWAII_me.bin +lib/firmware/radeon/hawaii_mec.bin +lib/firmware/radeon/HAWAII_mec.bin +lib/firmware/radeon/hawaii_pfp.bin +lib/firmware/radeon/HAWAII_pfp.bin +lib/firmware/radeon/hawaii_rlc.bin +lib/firmware/radeon/HAWAII_rlc.bin +lib/firmware/radeon/hawaii_sdma.bin +lib/firmware/radeon/HAWAII_sdma.bin +lib/firmware/radeon/hawaii_smc.bin +lib/firmware/radeon/HAWAII_smc.bin +lib/firmware/radeon/kabini_ce.bin +lib/firmware/radeon/kabini_me.bin +lib/firmware/radeon/kabini_mec.bin +lib/firmware/radeon/kabini_pfp.bin +lib/firmware/radeon/kabini_rlc.bin +lib/firmware/radeon/kabini_sdma.bin +lib/firmware/radeon/kaveri_ce.bin +lib/firmware/radeon/kaveri_me.bin +lib/firmware/radeon/kaveri_mec2.bin +lib/firmware/radeon/kaveri_mec.bin +lib/firmware/radeon/kaveri_pfp.bin +lib/firmware/radeon/kaveri_rlc.bin +lib/firmware/radeon/kaveri_sdma.bin +lib/firmware/radeon/mullins_ce.bin +lib/firmware/radeon/MULLINS_ce.bin +lib/firmware/radeon/mullins_me.bin +lib/firmware/radeon/MULLINS_me.bin +lib/firmware/radeon/mullins_mec.bin +lib/firmware/radeon/MULLINS_mec.bin +lib/firmware/radeon/mullins_pfp.bin +lib/firmware/radeon/MULLINS_pfp.bin +lib/firmware/radeon/mullins_rlc.bin +lib/firmware/radeon/MULLINS_rlc.bin +lib/firmware/radeon/mullins_sdma.bin +lib/firmware/radeon/MULLINS_sdma.bin +lib/firmware/radeon/oland_ce.bin +lib/firmware/radeon/OLAND_mc2.bin +lib/firmware/radeon/oland_mc.bin +lib/firmware/radeon/oland_me.bin +lib/firmware/radeon/oland_pfp.bin +lib/firmware/radeon/oland_rlc.bin +lib/firmware/radeon/oland_smc.bin +lib/firmware/radeon/pitcairn_ce.bin +lib/firmware/radeon/PITCAIRN_mc2.bin +lib/firmware/radeon/pitcairn_mc.bin +lib/firmware/radeon/pitcairn_me.bin +lib/firmware/radeon/pitcairn_pfp.bin +lib/firmware/radeon/pitcairn_rlc.bin +lib/firmware/radeon/pitcairn_smc.bin +lib/firmware/radeon/R600_uvd.bin +lib/firmware/radeon/RS780_uvd.bin +lib/firmware/radeon/RV770_uvd.bin +lib/firmware/radeon/tahiti_ce.bin +lib/firmware/radeon/TAHITI_mc2.bin +lib/firmware/radeon/tahiti_mc.bin +lib/firmware/radeon/tahiti_me.bin +lib/firmware/radeon/tahiti_pfp.bin +lib/firmware/radeon/tahiti_rlc.bin +lib/firmware/radeon/tahiti_smc.bin +lib/firmware/radeon/verde_ce.bin +lib/firmware/radeon/VERDE_mc2.bin +lib/firmware/radeon/verde_mc.bin +lib/firmware/radeon/verde_me.bin +lib/firmware/radeon/verde_pfp.bin +lib/firmware/radeon/verde_rlc.bin +lib/firmware/radeon/verde_smc.bin +lib/firmware/README +lib/firmware/rsi_91x.fw +lib/firmware/rtl_nic/rtl8107e-1.fw +lib/firmware/rtl_nic/rtl8107e-2.fw +lib/firmware/rtl_nic/rtl8168h-1.fw +lib/firmware/rtl_nic/rtl8168h-2.fw +lib/firmware/rtlwifi/rtl8192cfw.bin +lib/firmware/rtlwifi/rtl8192cfwU_B.bin +lib/firmware/rtlwifi/rtl8192defw.bin +lib/firmware/rtlwifi/rtl8192eefw.bin +lib/firmware/rtlwifi/rtl8723aufw_A.bin +lib/firmware/rtlwifi/rtl8723aufw_B.bin +lib/firmware/rtlwifi/rtl8723aufw_B_NoBT.bin +lib/firmware/rtlwifi/rtl8723befw.bin +lib/firmware/rtlwifi/rtl8821aefw.bin +lib/firmware/rtlwifi/rtl8821aefw_wowlan.bin +lib/firmware/s5p-mfc.fw +lib/firmware/s5p-mfc-v6.fw +lib/firmware/s5p-mfc-v6-v2.fw +lib/firmware/s5p-mfc-v7.fw +lib/firmware/s5p-mfc-v8.fw +lib/firmware/sms1xxx-hcw-55xxx-dvbt-02.fw +lib/firmware/sms1xxx-hcw-55xxx-isdbt-02.fw +lib/firmware/sms1xxx-nova-a-dvbt-01.fw +lib/firmware/sms1xxx-nova-b-dvbt-01.fw +lib/firmware/sms1xxx-stellar-dvbt-01.fw +lib/firmware/tdmb_nova_12mhz.inp +lib/firmware/ti-connectivity/wl18xx-fw-3.bin +lib/firmware/ti-connectivity/wl18xx-fw-4.bin +lib/firmware/v4l-cx23885-enc-broken.fw +lib/firmware/WHENCE diff --git a/config/rootfiles/core/86/filelists/wireless-regdb b/config/rootfiles/core/86/filelists/wireless-regdb new file mode 120000 index 0000000..c9205b3 --- /dev/null +++ b/config/rootfiles/core/86/filelists/wireless-regdb @@ -0,0 +1 @@ +../../../common/wireless-regdb \ No newline at end of file diff --git a/config/rootfiles/core/86/filelists/wpa_supplicant b/config/rootfiles/core/86/filelists/wpa_supplicant new file mode 120000 index 0000000..1d04c03 --- /dev/null +++ b/config/rootfiles/core/86/filelists/wpa_supplicant @@ -0,0 +1 @@ +../../../common/wpa_supplicant \ No newline at end of file diff --git a/config/rootfiles/core/86/update.sh b/config/rootfiles/core/86/update.sh index c1ea59c..bdb96fc 100644 --- a/config/rootfiles/core/86/update.sh +++ b/config/rootfiles/core/86/update.sh @@ -100,6 +100,7 @@ echo Update Kernel to $KVER ... rm -rf /boot/System.map-* rm -rf /boot/config-* rm -rf /boot/ipfirerd-* +rm -rf /boot/initramfs-* rm -rf /boot/vmlinuz-* rm -rf /boot/uImage-ipfire-* rm -rf /boot/uInit-ipfire-* @@ -125,6 +126,10 @@ esac #Extract files tar xavf /opt/pakfire/tmp/files* --no-overwrite-dir -p --numeric-owner -C /
+# +#restart init because glibc was updated. +telinit u + # Check diskspace on boot BOOTSPACE=`df /boot -Pk | sed "s| * | |g" | cut -d" " -f4 | tail -n 1`
@@ -175,16 +180,10 @@ case "$(uname -m)" in echo "GRUB_TERMINAL="serial"" >> /etc/default/grub echo "GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200"" >> /etc/default/grub fi - grub-mkconfig -o /boot/grub/grub.cfg - - ROOT=$(mount | grep " / " | cut -d" " -f1) - ROOT=${ROOT::-1}
- if ! grub-install --no-floppy --recheck "${ROOT}"; then - if ! grub-install --no-floppy --recheck --force "${ROOT}"; then - logger -p syslog.emerg -t ipfire \ - "Could not update the bootloader!" - fi + if ! /usr/local/bin/update-bootloader; then + logger -p syslog.emerg -t ipfire \ + "Could not update the bootloader!" fi ;; esac diff --git a/config/rootfiles/packages/lynis b/config/rootfiles/packages/lynis index d4e3237..6199853 100644 --- a/config/rootfiles/packages/lynis +++ b/config/rootfiles/packages/lynis @@ -1,63 +1,79 @@ -var/ipfire/lynis-1.2.9 -var/ipfire/lynis-1.2.9/db -var/ipfire/lynis-1.2.9/db/fileperms.db -var/ipfire/lynis-1.2.9/db/hints.db -var/ipfire/lynis-1.2.9/db/integrity.db -var/ipfire/lynis-1.2.9/db/malware-susp.db -var/ipfire/lynis-1.2.9/db/malware.db -var/ipfire/lynis-1.2.9/db/sbl.db -var/ipfire/lynis-1.2.9/default.prf -var/ipfire/lynis-1.2.9/include -var/ipfire/lynis-1.2.9/include/binaries -var/ipfire/lynis-1.2.9/include/consts -var/ipfire/lynis-1.2.9/include/functions -var/ipfire/lynis-1.2.9/include/osdetection -var/ipfire/lynis-1.2.9/include/parameters -var/ipfire/lynis-1.2.9/include/profiles -var/ipfire/lynis-1.2.9/include/report -var/ipfire/lynis-1.2.9/include/tests_accounting -var/ipfire/lynis-1.2.9/include/tests_authentication -var/ipfire/lynis-1.2.9/include/tests_banners -var/ipfire/lynis-1.2.9/include/tests_boot_services -var/ipfire/lynis-1.2.9/include/tests_crypto -var/ipfire/lynis-1.2.9/include/tests_databases -var/ipfire/lynis-1.2.9/include/tests_file_integrity -var/ipfire/lynis-1.2.9/include/tests_file_permissions -var/ipfire/lynis-1.2.9/include/tests_filesystems -var/ipfire/lynis-1.2.9/include/tests_firewalls -var/ipfire/lynis-1.2.9/include/tests_hardening -var/ipfire/lynis-1.2.9/include/tests_hardening_tools -var/ipfire/lynis-1.2.9/include/tests_homedirs -var/ipfire/lynis-1.2.9/include/tests_insecure_services -var/ipfire/lynis-1.2.9/include/tests_kernel -var/ipfire/lynis-1.2.9/include/tests_kernel_hardening -var/ipfire/lynis-1.2.9/include/tests_ldap -var/ipfire/lynis-1.2.9/include/tests_logging -var/ipfire/lynis-1.2.9/include/tests_mac_frameworks -var/ipfire/lynis-1.2.9/include/tests_mail_messaging -var/ipfire/lynis-1.2.9/include/tests_malware -var/ipfire/lynis-1.2.9/include/tests_memory_processes -var/ipfire/lynis-1.2.9/include/tests_nameservices -var/ipfire/lynis-1.2.9/include/tests_networking -var/ipfire/lynis-1.2.9/include/tests_php -var/ipfire/lynis-1.2.9/include/tests_ports_packages -var/ipfire/lynis-1.2.9/include/tests_printers_spools -var/ipfire/lynis-1.2.9/include/tests_scheduling -var/ipfire/lynis-1.2.9/include/tests_shells -var/ipfire/lynis-1.2.9/include/tests_snmp -var/ipfire/lynis-1.2.9/include/tests_solaris -var/ipfire/lynis-1.2.9/include/tests_squid -var/ipfire/lynis-1.2.9/include/tests_ssh -var/ipfire/lynis-1.2.9/include/tests_storage -var/ipfire/lynis-1.2.9/include/tests_storage_nfs -var/ipfire/lynis-1.2.9/include/tests_time -var/ipfire/lynis-1.2.9/include/tests_virtualization -var/ipfire/lynis-1.2.9/include/tests_webservers -var/ipfire/lynis-1.2.9/lynis -var/ipfire/lynis-1.2.9/lynis.8 -var/ipfire/lynis-1.2.9/plugins -var/ipfire/lynis-1.2.9/plugins/README -var/ipfire/lynis-1.2.9/plugins/plugin_access_files -var/ipfire/lynis-1.2.9/plugins/plugin_compliance_pci -var/ipfire/lynis-1.2.9/plugins/plugin_homedirs -var/ipfire/lynis-1.2.9/plugins/plugin_webserver_data \ No newline at end of file +var/ipfire/lynis +#var/ipfire/lynis/CONTRIBUTORS +#var/ipfire/lynis/db +var/ipfire/lynis/db/fileperms.db +var/ipfire/lynis/db/hints.db +var/ipfire/lynis/db/integrity.db +var/ipfire/lynis/db/malware-susp.db +var/ipfire/lynis/db/malware.db +var/ipfire/lynis/db/sbl.db +var/ipfire/lynis/default.prf +#var/ipfire/lynis/extras +var/ipfire/lynis/extras/.bzrignore +#var/ipfire/lynis/extras/README +#var/ipfire/lynis/extras/bash_completion.d +var/ipfire/lynis/extras/bash_completion.d/lynis +var/ipfire/lynis/extras/build-lynis.sh +var/ipfire/lynis/extras/check-lynis.sh +var/ipfire/lynis/extras/files.dat +var/ipfire/lynis/extras/lynis.spec +#var/ipfire/lynis/extras/openbsd +#var/ipfire/lynis/extras/openbsd/+CONTENTS +#var/ipfire/lynis/extras/systemd +#var/ipfire/lynis/extras/systemd/lynis.service +#var/ipfire/lynis/extras/systemd/lynis.timer +#var/ipfire/lynis/include +var/ipfire/lynis/include/binaries +var/ipfire/lynis/include/consts +var/ipfire/lynis/include/data_upload +var/ipfire/lynis/include/functions +var/ipfire/lynis/include/osdetection +var/ipfire/lynis/include/parameters +var/ipfire/lynis/include/profiles +var/ipfire/lynis/include/report +var/ipfire/lynis/include/tests_accounting +var/ipfire/lynis/include/tests_authentication +var/ipfire/lynis/include/tests_banners +var/ipfire/lynis/include/tests_boot_services +var/ipfire/lynis/include/tests_crypto +var/ipfire/lynis/include/tests_custom.template +var/ipfire/lynis/include/tests_databases +var/ipfire/lynis/include/tests_file_integrity +var/ipfire/lynis/include/tests_file_permissions +var/ipfire/lynis/include/tests_filesystems +var/ipfire/lynis/include/tests_firewalls +var/ipfire/lynis/include/tests_hardening +var/ipfire/lynis/include/tests_hardening_tools +var/ipfire/lynis/include/tests_homedirs +var/ipfire/lynis/include/tests_insecure_services +var/ipfire/lynis/include/tests_kernel +var/ipfire/lynis/include/tests_kernel_hardening +var/ipfire/lynis/include/tests_ldap +var/ipfire/lynis/include/tests_logging +var/ipfire/lynis/include/tests_mac_frameworks +var/ipfire/lynis/include/tests_mail_messaging +var/ipfire/lynis/include/tests_malware +var/ipfire/lynis/include/tests_memory_processes +var/ipfire/lynis/include/tests_nameservices +var/ipfire/lynis/include/tests_networking +var/ipfire/lynis/include/tests_php +var/ipfire/lynis/include/tests_ports_packages +var/ipfire/lynis/include/tests_printers_spools +var/ipfire/lynis/include/tests_scheduling +var/ipfire/lynis/include/tests_shells +var/ipfire/lynis/include/tests_snmp +#var/ipfire/lynis/include/tests_solaris +var/ipfire/lynis/include/tests_squid +var/ipfire/lynis/include/tests_ssh +var/ipfire/lynis/include/tests_storage +var/ipfire/lynis/include/tests_storage_nfs +var/ipfire/lynis/include/tests_tcpwrappers +var/ipfire/lynis/include/tests_time +var/ipfire/lynis/include/tests_tooling +var/ipfire/lynis/include/tests_virtualization +var/ipfire/lynis/include/tests_webservers +var/ipfire/lynis/lynis +var/ipfire/lynis/lynis.8 +#var/ipfire/lynis/plugins +var/ipfire/lynis/plugins/README +var/ipfire/lynis/plugins/custom_plugin.template diff --git a/config/rootfiles/packages/monit b/config/rootfiles/packages/monit new file mode 100644 index 0000000..049bab3 --- /dev/null +++ b/config/rootfiles/packages/monit @@ -0,0 +1,8 @@ +etc/monitrc +usr/bin/monit +#usr/share/man/man1/monit.1 +var/ipfire/backup/addons/includes/monit +etc/rc.d/init.d/monit +etc/rc.d/rc0.d/K40monit +etc/rc.d/rc3.d/S60monit +etc/rc.d/rc6.d/K40monit diff --git a/config/rootfiles/packages/nmap b/config/rootfiles/packages/nmap index 8f39897..3370600 100644 --- a/config/rootfiles/packages/nmap +++ b/config/rootfiles/packages/nmap @@ -2,6 +2,8 @@ usr/bin/ncat usr/bin/ndiff usr/bin/nmap usr/bin/nping +usr/lib/python2.7/site-packages/ndiff.py +usr/lib/python2.7/site-packages/ndiff.pyc #usr/share/man/de/man1/nmap.1 #usr/share/man/es/man1/nmap.1 #usr/share/man/fr/man1/nmap.1 @@ -12,9 +14,7 @@ usr/bin/nping #usr/share/man/hu/man1 #usr/share/man/hu/man1/nmap.1 #usr/share/man/it/man1/nmap.1 -#usr/share/man/jp -#usr/share/man/jp/man1 -#usr/share/man/jp/man1/nmap.1 +#usr/share/man/ja/man1/nmap.1 #usr/share/man/man1/ncat.1 #usr/share/man/man1/ndiff.1 #usr/share/man/man1/nmap.1 @@ -41,7 +41,7 @@ usr/bin/nping #usr/share/man/zh/man1 #usr/share/man/zh/man1/nmap.1 #usr/share/ncat -usr/share/ncat/ca-bundle.crt +#usr/share/ncat/ca-bundle.crt #usr/share/nmap usr/share/nmap/nmap-mac-prefixes usr/share/nmap/nmap-os-db @@ -53,30 +53,50 @@ usr/share/nmap/nmap-services usr/share/nmap/nmap.dtd usr/share/nmap/nmap.xsl usr/share/nmap/nse_main.lua -#usr/share/nmap/nselib +usr/share/nmap/nselib usr/share/nmap/nselib/afp.lua +usr/share/nmap/nselib/ajp.lua usr/share/nmap/nselib/amqp.lua usr/share/nmap/nselib/asn1.lua +usr/share/nmap/nselib/base32.lua usr/share/nmap/nselib/base64.lua +usr/share/nmap/nselib/bin.luadoc +usr/share/nmap/nselib/bit.luadoc usr/share/nmap/nselib/bitcoin.lua usr/share/nmap/nselib/bittorrent.lua +usr/share/nmap/nselib/bjnp.lua usr/share/nmap/nselib/brute.lua +usr/share/nmap/nselib/cassandra.lua usr/share/nmap/nselib/citrixxml.lua usr/share/nmap/nselib/comm.lua usr/share/nmap/nselib/creds.lua usr/share/nmap/nselib/cvs.lua -#usr/share/nmap/nselib/data +usr/share/nmap/nselib/data +usr/share/nmap/nselib/data/dns-srv-names +usr/share/nmap/nselib/data/drupal-modules.lst usr/share/nmap/nselib/data/favicon-db usr/share/nmap/nselib/data/http-default-accounts-fingerprints.lua +usr/share/nmap/nselib/data/http-devframework-fingerprints.lua usr/share/nmap/nselib/data/http-fingerprints.lua usr/share/nmap/nselib/data/http-folders.txt +usr/share/nmap/nselib/data/http-sql-errors.lst +usr/share/nmap/nselib/data/http-web-files-extensions.lst +usr/share/nmap/nselib/data/ike-fingerprints.lua +#usr/share/nmap/nselib/data/jdwp-class +#usr/share/nmap/nselib/data/jdwp-class/JDWPExecCmd.class +#usr/share/nmap/nselib/data/jdwp-class/JDWPExecCmd.java +#usr/share/nmap/nselib/data/jdwp-class/JDWPSystemInfo.class +#usr/share/nmap/nselib/data/jdwp-class/JDWPSystemInfo.java +#usr/share/nmap/nselib/data/jdwp-class/README.txt +usr/share/nmap/nselib/data/mgroupnames.db usr/share/nmap/nselib/data/mysql-cis.audit usr/share/nmap/nselib/data/oracle-default-accounts.lst usr/share/nmap/nselib/data/oracle-sids usr/share/nmap/nselib/data/packetdecoders.lua usr/share/nmap/nselib/data/passwords.lst +#usr/share/nmap/nselib/data/pixel.gif #usr/share/nmap/nselib/data/psexec -usr/share/nmap/nselib/data/psexec/README +#usr/share/nmap/nselib/data/psexec/README usr/share/nmap/nselib/data/psexec/backdoor.lua usr/share/nmap/nselib/data/psexec/default.lua usr/share/nmap/nselib/data/psexec/drives.lua @@ -92,6 +112,8 @@ usr/share/nmap/nselib/data/ssl-ciphers usr/share/nmap/nselib/data/ssl-fingerprints usr/share/nmap/nselib/data/tftplist.txt usr/share/nmap/nselib/data/usernames.lst +usr/share/nmap/nselib/data/vhosts-default.lst +usr/share/nmap/nselib/data/vhosts-full.lst usr/share/nmap/nselib/data/wp-plugins.lst usr/share/nmap/nselib/datafiles.lua usr/share/nmap/nselib/dhcp.lua @@ -101,20 +123,29 @@ usr/share/nmap/nselib/dnsbl.lua usr/share/nmap/nselib/dnssd.lua usr/share/nmap/nselib/drda.lua usr/share/nmap/nselib/eap.lua +usr/share/nmap/nselib/eigrp.lua +usr/share/nmap/nselib/formulas.lua usr/share/nmap/nselib/ftp.lua usr/share/nmap/nselib/giop.lua +usr/share/nmap/nselib/gps.lua usr/share/nmap/nselib/http.lua usr/share/nmap/nselib/httpspider.lua usr/share/nmap/nselib/iax2.lua +usr/share/nmap/nselib/ike.lua usr/share/nmap/nselib/imap.lua usr/share/nmap/nselib/informix.lua usr/share/nmap/nselib/ipOps.lua +usr/share/nmap/nselib/ipp.lua usr/share/nmap/nselib/iscsi.lua +usr/share/nmap/nselib/isns.lua +usr/share/nmap/nselib/jdwp.lua usr/share/nmap/nselib/json.lua usr/share/nmap/nselib/ldap.lua +usr/share/nmap/nselib/lfs.luadoc usr/share/nmap/nselib/listop.lua usr/share/nmap/nselib/match.lua usr/share/nmap/nselib/membase.lua +usr/share/nmap/nselib/mobileme.lua usr/share/nmap/nselib/mongodb.lua usr/share/nmap/nselib/msrpc.lua usr/share/nmap/nselib/msrpcperformance.lua @@ -125,14 +156,19 @@ usr/share/nmap/nselib/natpmp.lua usr/share/nmap/nselib/ncp.lua usr/share/nmap/nselib/ndmp.lua usr/share/nmap/nselib/netbios.lua +usr/share/nmap/nselib/nmap.luadoc usr/share/nmap/nselib/nrpc.lua usr/share/nmap/nselib/nsedebug.lua usr/share/nmap/nselib/omp2.lua +usr/share/nmap/nselib/openssl.luadoc +usr/share/nmap/nselib/ospf.lua usr/share/nmap/nselib/packet.lua +usr/share/nmap/nselib/pcre.luadoc usr/share/nmap/nselib/pgsql.lua usr/share/nmap/nselib/pop3.lua usr/share/nmap/nselib/pppoe.lua usr/share/nmap/nselib/proxy.lua +usr/share/nmap/nselib/rdp.lua usr/share/nmap/nselib/redis.lua usr/share/nmap/nselib/rmi.lua usr/share/nmap/nselib/rpc.lua @@ -158,7 +194,10 @@ usr/share/nmap/nselib/stun.lua usr/share/nmap/nselib/tab.lua usr/share/nmap/nselib/target.lua usr/share/nmap/nselib/tftp.lua +usr/share/nmap/nselib/tls.lua usr/share/nmap/nselib/tns.lua +usr/share/nmap/nselib/unicode.lua +usr/share/nmap/nselib/unittest.lua usr/share/nmap/nselib/unpwdb.lua usr/share/nmap/nselib/upnp.lua usr/share/nmap/nselib/url.lua @@ -177,6 +216,12 @@ usr/share/nmap/scripts/afp-ls.nse usr/share/nmap/scripts/afp-path-vuln.nse usr/share/nmap/scripts/afp-serverinfo.nse usr/share/nmap/scripts/afp-showmount.nse +usr/share/nmap/scripts/ajp-auth.nse +usr/share/nmap/scripts/ajp-brute.nse +usr/share/nmap/scripts/ajp-headers.nse +usr/share/nmap/scripts/ajp-methods.nse +usr/share/nmap/scripts/ajp-request.nse +usr/share/nmap/scripts/allseeingeye-info.nse usr/share/nmap/scripts/amqp-info.nse usr/share/nmap/scripts/asn-query.nse usr/share/nmap/scripts/auth-owners.nse @@ -188,12 +233,17 @@ usr/share/nmap/scripts/bitcoin-getaddr.nse usr/share/nmap/scripts/bitcoin-info.nse usr/share/nmap/scripts/bitcoinrpc-info.nse usr/share/nmap/scripts/bittorrent-discovery.nse +usr/share/nmap/scripts/bjnp-discover.nse +usr/share/nmap/scripts/broadcast-ataoe-discover.nse usr/share/nmap/scripts/broadcast-avahi-dos.nse +usr/share/nmap/scripts/broadcast-bjnp-discover.nse usr/share/nmap/scripts/broadcast-db2-discover.nse usr/share/nmap/scripts/broadcast-dhcp-discover.nse usr/share/nmap/scripts/broadcast-dhcp6-discover.nse usr/share/nmap/scripts/broadcast-dns-service-discovery.nse usr/share/nmap/scripts/broadcast-dropbox-listener.nse +usr/share/nmap/scripts/broadcast-eigrp-discovery.nse +usr/share/nmap/scripts/broadcast-igmp-discovery.nse usr/share/nmap/scripts/broadcast-listener.nse usr/share/nmap/scripts/broadcast-ms-sql-discover.nse usr/share/nmap/scripts/broadcast-netbios-master-browser.nse @@ -201,17 +251,21 @@ usr/share/nmap/scripts/broadcast-networker-discover.nse usr/share/nmap/scripts/broadcast-novell-locate.nse usr/share/nmap/scripts/broadcast-pc-anywhere.nse usr/share/nmap/scripts/broadcast-pc-duo.nse +usr/share/nmap/scripts/broadcast-pim-discovery.nse usr/share/nmap/scripts/broadcast-ping.nse usr/share/nmap/scripts/broadcast-pppoe-discover.nse usr/share/nmap/scripts/broadcast-rip-discover.nse usr/share/nmap/scripts/broadcast-ripng-discover.nse usr/share/nmap/scripts/broadcast-sybase-asa-discover.nse +usr/share/nmap/scripts/broadcast-tellstick-discover.nse usr/share/nmap/scripts/broadcast-upnp-info.nse usr/share/nmap/scripts/broadcast-versant-locate.nse usr/share/nmap/scripts/broadcast-wake-on-lan.nse usr/share/nmap/scripts/broadcast-wpad-discover.nse usr/share/nmap/scripts/broadcast-wsdd-discover.nse usr/share/nmap/scripts/broadcast-xdmcp-discover.nse +usr/share/nmap/scripts/cassandra-brute.nse +usr/share/nmap/scripts/cassandra-info.nse usr/share/nmap/scripts/cccam-version.nse usr/share/nmap/scripts/citrix-brute-xml.nse usr/share/nmap/scripts/citrix-enum-apps-xml.nse @@ -221,6 +275,8 @@ usr/share/nmap/scripts/citrix-enum-servers.nse usr/share/nmap/scripts/couchdb-databases.nse usr/share/nmap/scripts/couchdb-stats.nse usr/share/nmap/scripts/creds-summary.nse +usr/share/nmap/scripts/cups-info.nse +usr/share/nmap/scripts/cups-queue-info.nse usr/share/nmap/scripts/cvs-brute-repository.nse usr/share/nmap/scripts/cvs-brute.nse usr/share/nmap/scripts/daap-get-library.nse @@ -228,12 +284,17 @@ usr/share/nmap/scripts/daytime.nse usr/share/nmap/scripts/db2-das-info.nse usr/share/nmap/scripts/db2-discover.nse usr/share/nmap/scripts/dhcp-discover.nse +usr/share/nmap/scripts/dict-info.nse +usr/share/nmap/scripts/distcc-cve2004-2687.nse usr/share/nmap/scripts/dns-blacklist.nse usr/share/nmap/scripts/dns-brute.nse usr/share/nmap/scripts/dns-cache-snoop.nse +usr/share/nmap/scripts/dns-check-zone.nse usr/share/nmap/scripts/dns-client-subnet-scan.nse usr/share/nmap/scripts/dns-fuzz.nse +usr/share/nmap/scripts/dns-ip6-arpa-scan.nse usr/share/nmap/scripts/dns-nsec-enum.nse +usr/share/nmap/scripts/dns-nsec3-enum.nse usr/share/nmap/scripts/dns-nsid.nse usr/share/nmap/scripts/dns-random-srcport.nse usr/share/nmap/scripts/dns-random-txid.nse @@ -252,8 +313,12 @@ usr/share/nmap/scripts/drda-info.nse usr/share/nmap/scripts/duplicates.nse usr/share/nmap/scripts/eap-info.nse usr/share/nmap/scripts/epmd-info.nse +usr/share/nmap/scripts/eppc-enum-processes.nse usr/share/nmap/scripts/finger.nse usr/share/nmap/scripts/firewalk.nse +usr/share/nmap/scripts/firewall-bypass.nse +usr/share/nmap/scripts/flume-master-info.nse +usr/share/nmap/scripts/freelancer-info.nse usr/share/nmap/scripts/ftp-anon.nse usr/share/nmap/scripts/ftp-bounce.nse usr/share/nmap/scripts/ftp-brute.nse @@ -263,7 +328,9 @@ usr/share/nmap/scripts/ftp-vsftpd-backdoor.nse usr/share/nmap/scripts/ftp-vuln-cve2010-4221.nse usr/share/nmap/scripts/ganglia-info.nse usr/share/nmap/scripts/giop-info.nse +usr/share/nmap/scripts/gkrellm-info.nse usr/share/nmap/scripts/gopher-ls.nse +usr/share/nmap/scripts/gpsd-info.nse usr/share/nmap/scripts/hadoop-datanode-info.nse usr/share/nmap/scripts/hadoop-jobtracker-info.nse usr/share/nmap/scripts/hadoop-namenode-info.nse @@ -273,6 +340,9 @@ usr/share/nmap/scripts/hbase-master-info.nse usr/share/nmap/scripts/hbase-region-info.nse usr/share/nmap/scripts/hddtemp-info.nse usr/share/nmap/scripts/hostmap-bfk.nse +usr/share/nmap/scripts/hostmap-ip2hosts.nse +usr/share/nmap/scripts/hostmap-robtex.nse +usr/share/nmap/scripts/http-adobe-coldfusion-apsa1301.nse usr/share/nmap/scripts/http-affiliate-id.nse usr/share/nmap/scripts/http-apache-negotiation.nse usr/share/nmap/scripts/http-auth-finder.nse @@ -284,19 +354,39 @@ usr/share/nmap/scripts/http-barracuda-dir-traversal.nse usr/share/nmap/scripts/http-brute.nse usr/share/nmap/scripts/http-cakephp-version.nse usr/share/nmap/scripts/http-chrono.nse +usr/share/nmap/scripts/http-coldfusion-subzero.nse +usr/share/nmap/scripts/http-comments-displayer.nse usr/share/nmap/scripts/http-config-backup.nse usr/share/nmap/scripts/http-cors.nse +usr/share/nmap/scripts/http-csrf.nse usr/share/nmap/scripts/http-date.nse usr/share/nmap/scripts/http-default-accounts.nse +usr/share/nmap/scripts/http-devframework.nse +usr/share/nmap/scripts/http-dlink-backdoor.nse +usr/share/nmap/scripts/http-dombased-xss.nse usr/share/nmap/scripts/http-domino-enum-passwords.nse +usr/share/nmap/scripts/http-drupal-enum-users.nse +usr/share/nmap/scripts/http-drupal-modules.nse usr/share/nmap/scripts/http-email-harvest.nse usr/share/nmap/scripts/http-enum.nse +usr/share/nmap/scripts/http-errors.nse +usr/share/nmap/scripts/http-exif-spider.nse usr/share/nmap/scripts/http-favicon.nse +usr/share/nmap/scripts/http-feed.nse +usr/share/nmap/scripts/http-fileupload-exploiter.nse usr/share/nmap/scripts/http-form-brute.nse +usr/share/nmap/scripts/http-form-fuzzer.nse +usr/share/nmap/scripts/http-frontpage-login.nse usr/share/nmap/scripts/http-generator.nse +usr/share/nmap/scripts/http-git.nse +usr/share/nmap/scripts/http-gitweb-projects-enum.nse usr/share/nmap/scripts/http-google-malware.nse usr/share/nmap/scripts/http-grep.nse usr/share/nmap/scripts/http-headers.nse +usr/share/nmap/scripts/http-huawei-hg5xx-vuln.nse +usr/share/nmap/scripts/http-icloud-findmyiphone.nse +usr/share/nmap/scripts/http-icloud-sendmsg.nse +usr/share/nmap/scripts/http-iis-short-name-brute.nse usr/share/nmap/scripts/http-iis-webdav-vuln.nse usr/share/nmap/scripts/http-joomla-brute.nse usr/share/nmap/scripts/http-litespeed-sourcecode-download.nse @@ -304,49 +394,81 @@ usr/share/nmap/scripts/http-majordomo2-dir-traversal.nse usr/share/nmap/scripts/http-malware-host.nse usr/share/nmap/scripts/http-method-tamper.nse usr/share/nmap/scripts/http-methods.nse +usr/share/nmap/scripts/http-mobileversion-checker.nse +usr/share/nmap/scripts/http-ntlm-info.nse usr/share/nmap/scripts/http-open-proxy.nse usr/share/nmap/scripts/http-open-redirect.nse usr/share/nmap/scripts/http-passwd.nse usr/share/nmap/scripts/http-php-version.nse +usr/share/nmap/scripts/http-phpmyadmin-dir-traversal.nse +usr/share/nmap/scripts/http-phpself-xss.nse usr/share/nmap/scripts/http-proxy-brute.nse usr/share/nmap/scripts/http-put.nse usr/share/nmap/scripts/http-qnap-nas-info.nse +usr/share/nmap/scripts/http-referer-checker.nse +usr/share/nmap/scripts/http-rfi-spider.nse usr/share/nmap/scripts/http-robots.txt.nse usr/share/nmap/scripts/http-robtex-reverse-ip.nse +usr/share/nmap/scripts/http-robtex-shared-ns.nse +usr/share/nmap/scripts/http-server-header.nse +usr/share/nmap/scripts/http-sitemap-generator.nse +usr/share/nmap/scripts/http-slowloris-check.nse +usr/share/nmap/scripts/http-slowloris.nse +usr/share/nmap/scripts/http-sql-injection.nse +usr/share/nmap/scripts/http-stored-xss.nse usr/share/nmap/scripts/http-title.nse +usr/share/nmap/scripts/http-tplink-dir-traversal.nse usr/share/nmap/scripts/http-trace.nse +usr/share/nmap/scripts/http-traceroute.nse usr/share/nmap/scripts/http-unsafe-output-escaping.nse +usr/share/nmap/scripts/http-useragent-tester.nse usr/share/nmap/scripts/http-userdir-enum.nse usr/share/nmap/scripts/http-vhosts.nse +usr/share/nmap/scripts/http-virustotal.nse +usr/share/nmap/scripts/http-vlcstreamer-ls.nse usr/share/nmap/scripts/http-vmware-path-vuln.nse usr/share/nmap/scripts/http-vuln-cve2009-3960.nse +usr/share/nmap/scripts/http-vuln-cve2010-0738.nse usr/share/nmap/scripts/http-vuln-cve2010-2861.nse usr/share/nmap/scripts/http-vuln-cve2011-3192.nse usr/share/nmap/scripts/http-vuln-cve2011-3368.nse usr/share/nmap/scripts/http-vuln-cve2012-1823.nse +usr/share/nmap/scripts/http-vuln-cve2013-0156.nse +usr/share/nmap/scripts/http-vuln-zimbra-lfi.nse usr/share/nmap/scripts/http-waf-detect.nse +usr/share/nmap/scripts/http-waf-fingerprint.nse usr/share/nmap/scripts/http-wordpress-brute.nse usr/share/nmap/scripts/http-wordpress-enum.nse usr/share/nmap/scripts/http-wordpress-plugins.nse +usr/share/nmap/scripts/http-xssed.nse usr/share/nmap/scripts/iax2-brute.nse usr/share/nmap/scripts/iax2-version.nse +usr/share/nmap/scripts/icap-info.nse +usr/share/nmap/scripts/ike-version.nse usr/share/nmap/scripts/imap-brute.nse usr/share/nmap/scripts/imap-capabilities.nse usr/share/nmap/scripts/informix-brute.nse usr/share/nmap/scripts/informix-query.nse usr/share/nmap/scripts/informix-tables.nse +usr/share/nmap/scripts/ip-forwarding.nse usr/share/nmap/scripts/ip-geolocation-geobytes.nse usr/share/nmap/scripts/ip-geolocation-geoplugin.nse usr/share/nmap/scripts/ip-geolocation-ipinfodb.nse usr/share/nmap/scripts/ip-geolocation-maxmind.nse usr/share/nmap/scripts/ipidseq.nse usr/share/nmap/scripts/ipv6-node-info.nse +usr/share/nmap/scripts/ipv6-ra-flood.nse usr/share/nmap/scripts/irc-botnet-channels.nse usr/share/nmap/scripts/irc-brute.nse usr/share/nmap/scripts/irc-info.nse +usr/share/nmap/scripts/irc-sasl-brute.nse usr/share/nmap/scripts/irc-unrealircd-backdoor.nse usr/share/nmap/scripts/iscsi-brute.nse usr/share/nmap/scripts/iscsi-info.nse +usr/share/nmap/scripts/isns-info.nse +usr/share/nmap/scripts/jdwp-exec.nse +usr/share/nmap/scripts/jdwp-info.nse +usr/share/nmap/scripts/jdwp-inject.nse usr/share/nmap/scripts/jdwp-version.nse usr/share/nmap/scripts/krb5-enum-users.nse usr/share/nmap/scripts/ldap-brute.nse @@ -354,18 +476,26 @@ usr/share/nmap/scripts/ldap-novell-getpass.nse usr/share/nmap/scripts/ldap-rootdse.nse usr/share/nmap/scripts/ldap-search.nse usr/share/nmap/scripts/lexmark-config.nse +usr/share/nmap/scripts/llmnr-resolve.nse usr/share/nmap/scripts/lltd-discovery.nse usr/share/nmap/scripts/maxdb-info.nse +usr/share/nmap/scripts/mcafee-epo-agent.nse usr/share/nmap/scripts/membase-brute.nse usr/share/nmap/scripts/membase-http-info.nse usr/share/nmap/scripts/memcached-info.nse +usr/share/nmap/scripts/metasploit-info.nse +usr/share/nmap/scripts/metasploit-msgrpc-brute.nse usr/share/nmap/scripts/metasploit-xmlrpc-brute.nse +usr/share/nmap/scripts/mmouse-brute.nse +usr/share/nmap/scripts/mmouse-exec.nse usr/share/nmap/scripts/modbus-discover.nse usr/share/nmap/scripts/mongodb-brute.nse usr/share/nmap/scripts/mongodb-databases.nse usr/share/nmap/scripts/mongodb-info.nse +usr/share/nmap/scripts/mrinfo.nse usr/share/nmap/scripts/ms-sql-brute.nse usr/share/nmap/scripts/ms-sql-config.nse +usr/share/nmap/scripts/ms-sql-dac.nse usr/share/nmap/scripts/ms-sql-dump-hashes.nse usr/share/nmap/scripts/ms-sql-empty-password.nse usr/share/nmap/scripts/ms-sql-hasdbaccess.nse @@ -373,13 +503,20 @@ usr/share/nmap/scripts/ms-sql-info.nse usr/share/nmap/scripts/ms-sql-query.nse usr/share/nmap/scripts/ms-sql-tables.nse usr/share/nmap/scripts/ms-sql-xp-cmdshell.nse +usr/share/nmap/scripts/msrpc-enum.nse +usr/share/nmap/scripts/mtrace.nse +usr/share/nmap/scripts/murmur-version.nse usr/share/nmap/scripts/mysql-audit.nse usr/share/nmap/scripts/mysql-brute.nse usr/share/nmap/scripts/mysql-databases.nse +usr/share/nmap/scripts/mysql-dump-hashes.nse usr/share/nmap/scripts/mysql-empty-password.nse +usr/share/nmap/scripts/mysql-enum.nse usr/share/nmap/scripts/mysql-info.nse +usr/share/nmap/scripts/mysql-query.nse usr/share/nmap/scripts/mysql-users.nse usr/share/nmap/scripts/mysql-variables.nse +usr/share/nmap/scripts/mysql-vuln-cve2012-2122.nse usr/share/nmap/scripts/nat-pmp-info.nse usr/share/nmap/scripts/nat-pmp-mapport.nse usr/share/nmap/scripts/nbstat.nse @@ -405,20 +542,25 @@ usr/share/nmap/scripts/omp2-brute.nse usr/share/nmap/scripts/omp2-enum-targets.nse usr/share/nmap/scripts/openlookup-info.nse usr/share/nmap/scripts/openvas-otp-brute.nse +usr/share/nmap/scripts/oracle-brute-stealth.nse usr/share/nmap/scripts/oracle-brute.nse usr/share/nmap/scripts/oracle-enum-users.nse usr/share/nmap/scripts/oracle-sid-brute.nse usr/share/nmap/scripts/ovs-agent-version.nse usr/share/nmap/scripts/p2p-conficker.nse usr/share/nmap/scripts/path-mtu.nse +usr/share/nmap/scripts/pcanywhere-brute.nse usr/share/nmap/scripts/pgsql-brute.nse usr/share/nmap/scripts/pjl-ready-message.nse usr/share/nmap/scripts/pop3-brute.nse usr/share/nmap/scripts/pop3-capabilities.nse usr/share/nmap/scripts/pptp-version.nse +usr/share/nmap/scripts/qconn-exec.nse usr/share/nmap/scripts/qscan.nse +usr/share/nmap/scripts/quake1-info.nse usr/share/nmap/scripts/quake3-info.nse usr/share/nmap/scripts/quake3-master-getservers.nse +usr/share/nmap/scripts/rdp-enum-encryption.nse usr/share/nmap/scripts/rdp-vuln-ms12-020.nse usr/share/nmap/scripts/realvnc-auth-bypass.nse usr/share/nmap/scripts/redis-brute.nse @@ -426,9 +568,12 @@ usr/share/nmap/scripts/redis-info.nse usr/share/nmap/scripts/resolveall.nse usr/share/nmap/scripts/reverse-index.nse usr/share/nmap/scripts/rexec-brute.nse +usr/share/nmap/scripts/rfc868-time.nse usr/share/nmap/scripts/riak-http-info.nse usr/share/nmap/scripts/rlogin-brute.nse usr/share/nmap/scripts/rmi-dumpregistry.nse +usr/share/nmap/scripts/rmi-vuln-classloader.nse +usr/share/nmap/scripts/rpc-grind.nse usr/share/nmap/scripts/rpcap-brute.nse usr/share/nmap/scripts/rpcap-info.nse usr/share/nmap/scripts/rpcinfo.nse @@ -440,7 +585,9 @@ usr/share/nmap/scripts/samba-vuln-cve-2012-1182.nse usr/share/nmap/scripts/script.db usr/share/nmap/scripts/servicetags.nse usr/share/nmap/scripts/sip-brute.nse +usr/share/nmap/scripts/sip-call-spoof.nse usr/share/nmap/scripts/sip-enum-users.nse +usr/share/nmap/scripts/sip-methods.nse usr/share/nmap/scripts/skypev2-version.nse usr/share/nmap/scripts/smb-brute.nse usr/share/nmap/scripts/smb-check-vulns.nse @@ -451,12 +598,16 @@ usr/share/nmap/scripts/smb-enum-sessions.nse usr/share/nmap/scripts/smb-enum-shares.nse usr/share/nmap/scripts/smb-enum-users.nse usr/share/nmap/scripts/smb-flood.nse +usr/share/nmap/scripts/smb-ls.nse usr/share/nmap/scripts/smb-mbenum.nse usr/share/nmap/scripts/smb-os-discovery.nse +usr/share/nmap/scripts/smb-print-text.nse usr/share/nmap/scripts/smb-psexec.nse usr/share/nmap/scripts/smb-security-mode.nse usr/share/nmap/scripts/smb-server-stats.nse usr/share/nmap/scripts/smb-system-info.nse +usr/share/nmap/scripts/smb-vuln-ms10-054.nse +usr/share/nmap/scripts/smb-vuln-ms10-061.nse usr/share/nmap/scripts/smbv2-enabled.nse usr/share/nmap/scripts/smtp-brute.nse usr/share/nmap/scripts/smtp-commands.nse @@ -468,6 +619,7 @@ usr/share/nmap/scripts/smtp-vuln-cve2011-1720.nse usr/share/nmap/scripts/smtp-vuln-cve2011-1764.nse usr/share/nmap/scripts/sniffer-detect.nse usr/share/nmap/scripts/snmp-brute.nse +usr/share/nmap/scripts/snmp-hh3c-logins.nse usr/share/nmap/scripts/snmp-interfaces.nse usr/share/nmap/scripts/snmp-ios-config.nse usr/share/nmap/scripts/snmp-netstat.nse @@ -480,15 +632,17 @@ usr/share/nmap/scripts/snmp-win32-users.nse usr/share/nmap/scripts/socks-auth-info.nse usr/share/nmap/scripts/socks-brute.nse usr/share/nmap/scripts/socks-open-proxy.nse -usr/share/nmap/scripts/sql-injection.nse usr/share/nmap/scripts/ssh-hostkey.nse usr/share/nmap/scripts/ssh2-enum-algos.nse usr/share/nmap/scripts/sshv1.nse usr/share/nmap/scripts/ssl-cert.nse +usr/share/nmap/scripts/ssl-date.nse usr/share/nmap/scripts/ssl-enum-ciphers.nse usr/share/nmap/scripts/ssl-google-cert-catalog.nse +usr/share/nmap/scripts/ssl-heartbleed.nse usr/share/nmap/scripts/ssl-known-key.nse usr/share/nmap/scripts/sslv2.nse +usr/share/nmap/scripts/sstp-discover.nse usr/share/nmap/scripts/stun-info.nse usr/share/nmap/scripts/stun-version.nse usr/share/nmap/scripts/stuxnet-detect.nse @@ -500,12 +654,17 @@ usr/share/nmap/scripts/targets-ipv6-multicast-mld.nse usr/share/nmap/scripts/targets-ipv6-multicast-slaac.nse usr/share/nmap/scripts/targets-sniffer.nse usr/share/nmap/scripts/targets-traceroute.nse +usr/share/nmap/scripts/teamspeak2-version.nse usr/share/nmap/scripts/telnet-brute.nse usr/share/nmap/scripts/telnet-encryption.nse usr/share/nmap/scripts/tftp-enum.nse +usr/share/nmap/scripts/tls-nextprotoneg.nse +usr/share/nmap/scripts/traceroute-geolocation.nse +usr/share/nmap/scripts/unittest.nse usr/share/nmap/scripts/unusual-port.nse usr/share/nmap/scripts/upnp-info.nse usr/share/nmap/scripts/url-snarf.nse +usr/share/nmap/scripts/ventrilo-info.nse usr/share/nmap/scripts/versant-info.nse usr/share/nmap/scripts/vmauthd-brute.nse usr/share/nmap/scripts/vnc-brute.nse @@ -513,7 +672,9 @@ usr/share/nmap/scripts/vnc-info.nse usr/share/nmap/scripts/voldemort-info.nse usr/share/nmap/scripts/vuze-dht-info.nse usr/share/nmap/scripts/wdb-version.nse -usr/share/nmap/scripts/whois.nse +usr/share/nmap/scripts/weblogic-t3-info.nse +usr/share/nmap/scripts/whois-domain.nse +usr/share/nmap/scripts/whois-ip.nse usr/share/nmap/scripts/wsdd-discover.nse usr/share/nmap/scripts/x11-access.nse usr/share/nmap/scripts/xdmcp-discover.nse diff --git a/config/u-boot/boot.scr b/config/u-boot/boot.scr deleted file mode 100755 index 0fb1193..0000000 Binary files a/config/u-boot/boot.scr and /dev/null differ diff --git a/config/u-boot/boot.script b/config/u-boot/boot.script deleted file mode 100755 index 2017e71..0000000 --- a/config/u-boot/boot.script +++ /dev/null @@ -1,7 +0,0 @@ -setenv initrd_high 90000000 -fatload mmc 0:1 0x82000000 zImage-ipfire-multi -#fatload mmc 0:1 0x85000000 uInit-ipfire-multi -fatload mmc 0:1 ${fdtaddr} omap4-${board_name}.dtb -setenv bootargs video=800x600 console=tty1 rootwait smsc95xx.macaddr=$usbethaddr root=/dev/mmcblk0p3 ro -#bootz 0x82000000 0x85000000 ${fdtaddr} -bootz 0x82000000 - ${fdtaddr} diff --git a/config/u-boot/convert_bootscript b/config/u-boot/convert_bootscript deleted file mode 100755 index 962191f..0000000 --- a/config/u-boot/convert_bootscript +++ /dev/null @@ -1 +0,0 @@ -mkimage -A arm -T script -C none -d boot.script boot.scr diff --git a/config/u-boot/uEnv.txt b/config/u-boot/uEnv.txt new file mode 100755 index 0000000..bc3facc --- /dev/null +++ b/config/u-boot/uEnv.txt @@ -0,0 +1,4 @@ +uenvcmd=if test "$board" = "panda" ;then run bootpanda; else run bootbananapi; fi; +KVER=xxxKVERxxx +bootpanda=setenv initrd_high 90000000; fatload mmc 0:1 0x82000000 zImage-ipfire-multi; fatload mmc 0:1 ${fdtaddr} dtb-${KVER}-ipfire-multi/${fdtfile}; setenv bootargs video=800x600 console=tty1 rootwait smsc95xx.macaddr=$usbethaddr root=/dev/mmcblk0p3 ro; bootz 0x82000000 - ${fdtaddr}; +bootbananapi=setenv fdt_high ffffffff; fatload mmc 0:1 0x46000000 zImage-ipfire-multi; fatload mmc 0:1 0x49000000 dtb-${KVER}-ipfire-multi/sun7i-a20-bananapi.dtb; setenv bootargs console=ttyS0,115200n8 rootwait root=/dev/mmcblk0p3 rootwait; bootz 0x46000000 - 0x49000000; diff --git a/html/cgi-bin/wlanap.cgi b/html/cgi-bin/wlanap.cgi index 50806ac..c78a3c4 100644 --- a/html/cgi-bin/wlanap.cgi +++ b/html/cgi-bin/wlanap.cgi @@ -65,7 +65,7 @@ $wlanapsettings{'SSID'} = 'IPFire'; $wlanapsettings{'HIDESSID'} = 'off'; $wlanapsettings{'ENC'} = 'wpa2'; # none / wpa1 /wpa2 $wlanapsettings{'TXPOWER'} = 'auto'; -$wlanapsettings{'CHANNEL'} = '05'; +$wlanapsettings{'CHANNEL'} = '6'; $wlanapsettings{'COUNTRY'} = '00'; $wlanapsettings{'HW_MODE'} = 'g'; $wlanapsettings{'PWD'} = 'IPFire-2.x'; @@ -291,7 +291,7 @@ if ( $channel =~ /\d+/ ){push(@temp,$channel);} my @countrylist_cmd = `regdbdump /usr/lib/crda/regulatory.bin 2>/dev/null`; # get available country codes
-my @temp; +my @temp = "00"; foreach (@countrylist_cmd){ $_ =~ /country (.*):/; $country = $1;chomp $country; diff --git a/lfs/backports b/lfs/backports new file mode 100644 index 0000000..cd48700 --- /dev/null +++ b/lfs/backports @@ -0,0 +1,124 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007-2015 IPFire Team info@ipfire.org # +# # +# 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 3 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 http://www.gnu.org/licenses/. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include Config + +VERSUFIX = ipfire$(KCFG) + +VER = 3.18.1-1 + +THISAPP = backports-$(VER) +DL_FILE = $(THISAPP).tar.xz +DL_FROM = $(URL_IPFIRE) +DIR_APP = $(DIR_SRC)/$(THISAPP) +TARGET = $(DIR_INFO)/$(THISAPP)-kmod-$(KVER)-$(VERSUFIX) + +#ifeq "$(MACHINE_TYPE)" "arm" +CFLAGS += -fno-PIC +#endif + +############################################################################### +# Top-level Rules +############################################################################### + +objects = $(DL_FILE) + +$(DL_FILE) = $(DL_FROM)/$(DL_FILE) + +$(DL_FILE)_MD5 = 6cef5f2c800e12441d2cba9fa42b6a5b + +install : $(TARGET) + +check : $(patsubst %,$(DIR_CHK)/%,$(objects)) + +download :$(patsubst %,$(DIR_DL)/%,$(objects)) + +md5 : $(subst %,%_MD5,$(objects)) + +dist: + $(PAK) + +############################################################################### +# Downloading, checking, md5sum +############################################################################### + +$(patsubst %,$(DIR_CHK)/%,$(objects)) : + @$(CHECK) + +$(patsubst %,$(DIR_DL)/%,$(objects)) : + @$(LOAD) + +$(subst %,%_MD5,$(objects)) : + @$(MD5) + +############################################################################### +# Installation Details +############################################################################### + +$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) + @$(PREBUILD) + @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar Jxf $(DIR_DL)/$(DL_FILE) + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/backports-3.18.1-1-ipfire-build.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/backports-3.18.1-1-grsecurity.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/backports-3.18.1-1-add_usbnet_modules.patch + + # DVB patches + cd $(DIR_APP) && patch -Np2 < $(DIR_SRC)/src/patches/v4l-dvb_fix_tua6034_pll.patch + + # Wlan patches + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/compat-drivers-3.8.3-ath_ignore_eeprom_regdomain.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.14.22-iwlwifi-noibss_only_on_radar_chan.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.10.37-rt2800usb_add_dlink_dwa137_usbid.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/backports-3.18.1-1_add_libertas_uap.patch + + # generate config + cd $(DIR_APP) && make KLIB=/lib/modules/$(KVER)-$(VERSUFIX)/ allmodconfig + + # Disable some settings + cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_DEVELOPER_WARNINGS=y/# CPTCFG_CFG80211_DEVELOPER_WARNINGS is not set/g" .config + cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_CERTIFICATION_ONUS=y/# CPTCFG_CFG80211_CERTIFICATION_ONUS is not set/g" .config + cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_REG_CELLULAR_HINTS=y/# CPTCFG_CFG80211_REG_CELLULAR_HINTS is not set/g" .config + cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_REG_RELAX_NO_IR=y/# CPTCFG_CFG80211_REG_RELAX_NO_IR is not set/g" .config + cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_INTERNAL_REGDB=y/# CPTCFG_CFG80211_INTERNAL_REGDB is not set/g" .config + cd $(DIR_APP) && sed -i -e "s/CPTCFG_CFG80211_DEFAULT_PS=y/# CPTCFG_CFG80211_DEFAULT_PS is not set/g" .config + cd $(DIR_APP) && sed -i -e "s/CPTCFG_NFC=m/# CPTCFG_NFC is not set/g" .config + + # Disable some modules (build fail) + cd $(DIR_APP) && sed -i -e "s/CPTCFG_VIDEO_VIA_CAMERA=m/# CPTCFG_VIDEO_VIA_CAMERA is not set/g" .config + + # Disable DEBUG + cd $(DIR_APP) && sed -i -e "s/.*DEBUG=y/# & is not set/g" .config + cd $(DIR_APP) && sed -i -e "s/.*DEBUGFS=y/# & is not set/g" .config + cd $(DIR_APP) && sed -i -e "s/=y is not set/ is not set/g" .config + + # Disable OF_GRAPH (not supported by kernel 3.14) + cd $(DIR_APP) && sed -i -e "s/CONFIG_OF/CONFIG_OF_IGNORE/g" include/linux/of_graph.h + + cd $(DIR_APP) && make $(MAKETUNING) KLIB=/lib/modules/$(KVER)-$(VERSUFIX)/ install + + # Remove vsp1 module (not mach to our platforms) + rm -rf /lib/modules/$(KVER)-$(VERSUFIX)/kernel/drivers/media/platform/vsp1 + + @rm -rf $(DIR_APP) + @$(POSTBUILD) diff --git a/lfs/crda b/lfs/crda index e87b7ad..2b1aff8 100644 --- a/lfs/crda +++ b/lfs/crda @@ -24,10 +24,10 @@
include Config
-VER = 1.1.3 +VER = 3.13
THISAPP = crda-$(VER) -DL_FILE = $(THISAPP).tar.bz2 +DL_FILE = $(THISAPP).tar.xz DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP)
@@ -41,7 +41,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 29579185e06a75675507527243d28e5c +$(DL_FILE)_MD5 = 66b1b0417c1ad19f0009a5c0c0c1aebc
install : $(TARGET)
@@ -70,8 +70,9 @@ $(subst %,%_MD5,$(objects)) :
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @$(PREBUILD) - @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar jxf $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && USE_OPENSSL=1 make $(MAKETUNING) - cd $(DIR_APP) && USE_OPENSSL=1 make install + @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE) + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/crda-3.13-crypto_use_optional.patch + cd $(DIR_APP) && make $(MAKETUNING) + cd $(DIR_APP) && make install @rm -rf $(DIR_APP) @$(POSTBUILD) diff --git a/lfs/dvb-firmwares b/lfs/dvb-firmwares index cd029e2..a3833da 100644 --- a/lfs/dvb-firmwares +++ b/lfs/dvb-firmwares @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2012 IPFire Team info@ipfire.org # +# Copyright (C) 2007-2015 IPFire Team info@ipfire.org # # # # 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 # @@ -24,10 +24,10 @@
include Config
-VER = 20110802 +VER = 20141125
THISAPP = dvb-firmwares-$(VER) -DL_FILE = $(THISAPP).tar.bz2 +DL_FILE = $(THISAPP).tar.xz DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/dvb-firmwares TARGET = $(DIR_INFO)/$(THISAPP) @@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 330e19f9444a03f5338bab590ab9d728 +$(DL_FILE)_MD5 = 3c7182522dc091b506d2120d71a6a360
install : $(TARGET)
diff --git a/lfs/flash-images b/lfs/flash-images index d2050b4..6c88180 100644 --- a/lfs/flash-images +++ b/lfs/flash-images @@ -75,9 +75,9 @@ else endif
# /boot: 64MB - OFFSET -# / : 700MB +# / : 750MB S_BOOT := $(shell echo $$(( 131072 - $(S_OFFSET) ))) -S_ROOT := 1433600 +S_ROOT := 1536000
PADDING = 100 # MB
@@ -116,11 +116,14 @@ endif mkdir -pv $(MNThdd)/boot mount $(PART_BOOT) $(MNThdd)/boot
- # Install MLO and uboot first + # Install Pandaboard MLO and uboot first ifeq "$(MACHINE_TYPE)" "arm" cp -v /boot/MLO $(MNThdd)/boot/ cp -v /boot/u-boot.img $(MNThdd)/boot/ cp -v /boot/zImage-ipfire-multi $(MNThdd)/boot/ + # work around a u-boot bug not find the folders sometimes + mkdir -pv $(MNThdd)/boot/dtb-$(KVER)-ipfire-multi + mkdir -pv $(MNThdd)/boot/dtb-$(KVER)-ipfire-kirkwood sync umount $(MNThdd)/boot mount $(PART_BOOT) $(MNThdd)/boot @@ -148,8 +151,7 @@ ifeq "$(SCON)" "1"
ifeq "$(MACHINE_TYPE)" "arm" sed -i -e "s| console=tty1 | console=ttyAMA0,115200n8 |g" $(MNThdd)/boot/cmdline.txt - sed -i -e "s| console=tty1 | console=ttyO2,115200n8 |g" $(MNThdd)/boot/boot.script - cd $(MNThdd)/boot && ./convert_bootscript + sed -i -e "s| console=tty1 | console=ttyO2,115200n8 |g" $(MNThdd)/boot/uEnv.txt endif endif
@@ -216,6 +218,11 @@ endif # not copied to a block device) dd if=/dev/zero bs=1M count=$(PADDING) >> $(IMG)
+ifeq "$(MACHINE_TYPE)" "arm" + # Install u-boot for LeMaker Banana Pi into image 8KB + dd if=/usr/share/u-boot/banana_pi/u-boot-sunxi-with-spl.bin of=$(IMG) bs=1K seek=8 conv=notrunc +endif + # Compress Image pigz -f9 < $(IMG) > $(IMAGE_FILE) rm -rf $(IMG) $(MNThdd) diff --git a/lfs/hostapd b/lfs/hostapd index dbf909d..c381a0a 100644 --- a/lfs/hostapd +++ b/lfs/hostapd @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2014 IPFire Team info@ipfire.org # +# Copyright (C) 2007-2015 IPFire Team info@ipfire.org # # # # 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 # @@ -24,7 +24,7 @@
include Config
-VER = 2.2 +VER = 2.3
THISAPP = hostapd-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = hostapd -PAK_VER = 30 +PAK_VER = 31
DEPS = ""
@@ -44,7 +44,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 23c1f78a693c3288802d516adb7fd289 +$(DL_FILE)_MD5 = 40b89c61036add0c2dd1fc10767d3b5f
install : $(TARGET)
diff --git a/lfs/initscripts b/lfs/initscripts old mode 100644 new mode 100755 diff --git a/lfs/iw b/lfs/iw index e55bc5c..2d4ad34 100644 --- a/lfs/iw +++ b/lfs/iw @@ -24,7 +24,7 @@
include Config
-VER = 3.10 +VER = 3.14
THISAPP = iw-$(VER) DL_FILE = $(THISAPP).tar.xz @@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 07219ad06535bc270f7a8873aba6d5fa +$(DL_FILE)_MD5 = 66e41053f6fc0781b683b5b688442de6
install : $(TARGET)
diff --git a/lfs/kbd b/lfs/kbd index 1c99242..bb9d261 100644 --- a/lfs/kbd +++ b/lfs/kbd @@ -35,13 +35,18 @@ TARGET = $(DIR_INFO)/$(THISAPP) ############################################################################### # Top-level Rules ############################################################################### -objects = $(DL_FILE) $(THISAPP)-more-programs-1.patch +objects = $(DL_FILE) $(THISAPP)-more-programs-1.patch \ + kbd-latarcyrheb-16-fixed.tar.bz2 kbd-latsun-fonts.tar.bz2
$(DL_FILE) = $(DL_FROM)/$(DL_FILE) $(THISAPP)-more-programs-1.patch = $(DL_FROM)/kbd-$(VER)-more-programs-1.patch +kbd-latarcyrheb-16-fixed.tar.bz2 = $(DL_FROM)/kbd-latarcyrheb-16-fixed.tar.bz2 +kbd-latsun-fonts.tar.bz2 = $(DL_FROM)/kbd-latsun-fonts.tar.bz2
$(DL_FILE)_MD5 = 069d1175b4891343b107a8ac2b4a39f6 $(THISAPP)-more-programs-1.patch_MD5 = dc70180a6bc0afa2b741cd38e3cc2e18 +kbd-latarcyrheb-16-fixed.tar.bz2_MD5 = 884fdbb0b952b2e3e8389a0c40a3e301 +kbd-latsun-fonts.tar.bz2_MD5 = e22ee88353968df8d4a4b1bf1fa8fc31
install : $(TARGET)
@@ -74,6 +79,11 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/$(THISAPP)-more-programs-1.patch cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/$(THISAPP)-backspace-1.patch cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/$(THISAPP)-gcc4_fixes-1.patch + + # Extract our own fonts + cd $(DIR_APP) && tar xvfa $(DIR_DL)/kbd-latarcyrheb-16-fixed.tar.bz2 + cd $(DIR_APP) && tar xvfa $(DIR_DL)/kbd-latsun-fonts.tar.bz2 + cd $(DIR_APP) && ./configure --datadir=/lib/kbd --disable-nls cd $(DIR_APP) && make $(MAKETUNING) cd $(DIR_APP) && make install diff --git a/lfs/linux b/lfs/linux index 2644711..5b0de46 100644 --- a/lfs/linux +++ b/lfs/linux @@ -24,11 +24,11 @@
include Config
-VER = 3.14.25 +VER = 3.14.27
-RPI_PATCHES = 3.14.25-grsec-ipfire1 -A7M_PATCHES = 3.14.25-grsec-ipfire1 -GRS_PATCHES = grsecurity-3.0-3.14.25-201411220954.patch.xz +RPI_PATCHES = 3.14.27-grsec-ipfire1 +A7M_PATCHES = 3.14.27-grsec-ipfire1 +GRS_PATCHES = grsecurity-3.0-3.14.27-201412170659.patch.xz
THISAPP = linux-$(VER) DL_FILE = linux-$(VER).tar.xz @@ -37,7 +37,7 @@ DIR_APP = $(DIR_SRC)/$(THISAPP) CFLAGS = CXXFLAGS =
-PAK_VER = 53 +PAK_VER = 55 DEPS = ""
VERSUFIX=ipfire$(KCFG) @@ -77,10 +77,10 @@ rpi-patches-$(RPI_PATCHES).patch.xz = $(URL_IPFIRE)/rpi-patches-$(RPI_PATCHES). arm7-multi-patches-$(A7M_PATCHES).patch.xz = $(URL_IPFIRE)/arm7-multi-patches-$(A7M_PATCHES).patch.xz $(GRS_PATCHES) = $(URL_IPFIRE)/$(GRS_PATCHES)
-$(DL_FILE)_MD5 = 3ae910d35292706d85870c3939547123 -rpi-patches-$(RPI_PATCHES).patch.xz_MD5 = b573af847c28ebed8c15a74542360db1 -arm7-multi-patches-$(A7M_PATCHES).patch.xz_MD5 = 8b47b81a530db68cb2c2f6bb6418ca28 -$(GRS_PATCHES)_MD5 = 6b2c8669e39304cfe647f9de16260929 +$(DL_FILE)_MD5 = 0af2d0702df6ee6d7181e697e0af3481 +rpi-patches-$(RPI_PATCHES).patch.xz_MD5 = 543a77d5602829f78b18788e5cb82188 +arm7-multi-patches-$(A7M_PATCHES).patch.xz_MD5 = 7014ce20d9ede588ea2c244d901cbeeb +$(GRS_PATCHES)_MD5 = 66af1d48af9dce2d0eb363bbc6bfb668
install : $(TARGET)
@@ -140,6 +140,8 @@ endif cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.14.22-iwlwifi-noibss_only_on_radar_chan.patch cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.10.37-rt2800usb_add_dlink_dwa137_usbid.patch cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.10.55-rt2800usb-change_queue_warn_to_debug.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.14.25_rt2x00_fix_bss_bcn_num.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.14.25-rt5592_no_special_txop_init.patch cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.10.39-add_libertas_uap.patch
# mISDN Patches diff --git a/lfs/linux-firmware b/lfs/linux-firmware index 1dbfc7e..1378f32 100644 --- a/lfs/linux-firmware +++ b/lfs/linux-firmware @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2014 IPFire Team info@ipfire.org # +# Copyright (C) 2007-2015 IPFire Team info@ipfire.org # # # # 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 # @@ -24,7 +24,7 @@
include Config
-VER = 52d77db +VER = 78535e8
THISAPP = linux-firmware-$(VER) DL_FILE = $(THISAPP).tar.xz @@ -40,7 +40,8 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 3f6f1e78af3ee67a5540355f2ed8ba14 +$(DL_FILE)_MD5 = a4cafb924fbcaeb34d1b464be0e4d089 + install : $(TARGET)
check : $(patsubst %,$(DIR_CHK)/%,$(objects)) diff --git a/lfs/lynis b/lfs/lynis index 5cfd184..b3cabd7 100644 --- a/lfs/lynis +++ b/lfs/lynis @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007 Michael Tremer & Christian Schmidt # +# Copyright (C) 2015 IPfire Team info@ipfire.org # # # # 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 # @@ -24,16 +24,16 @@
include Config
-VER = 1.2.9 +VER = 1.6.4
THISAPP = lynis-$(VER) DL_FILE = $(THISAPP).tar.gz DL_FROM = $(URL_IPFIRE) -DIR_APP = $(DIR_SRC)/$(THISAPP) +DIR_APP = $(DIR_SRC)/lynis TARGET = $(DIR_INFO)/$(THISAPP)
PROG = lynis -PAK_VER = 4 +PAK_VER = 5 DEPS = ""
############################################################################### @@ -44,7 +44,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 69b369173ffc0f10f021035f73857e1f +$(DL_FILE)_MD5 = dfa946388af8926bd24f772d4fa4830a
install : $(TARGET)
diff --git a/lfs/monit b/lfs/monit new file mode 100644 index 0000000..6c35c6c --- /dev/null +++ b/lfs/monit @@ -0,0 +1,96 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2009 Michael Tremer & Christian Schmidt # +# # +# 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 3 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 http://www.gnu.org/licenses/. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include Config + +VER = 5.11 + +THISAPP = monit-$(VER) +DL_FILE = $(THISAPP).tar.gz +DL_FROM = $(URL_IPFIRE) +DIR_APP = $(DIR_SRC)/$(THISAPP) +TARGET = $(DIR_INFO)/$(THISAPP) +PROG = monit +PAK_VER = 3 + +DEPS = "" + +############################################################################### +# Top-level Rules +############################################################################### + +objects = $(DL_FILE) + +$(DL_FILE) = $(DL_FROM)/$(DL_FILE) + +$(DL_FILE)_MD5 = ff00f39d248ed7068932ed82211da9e6 + +install : $(TARGET) + +check : $(patsubst %,$(DIR_CHK)/%,$(objects)) + +download :$(patsubst %,$(DIR_DL)/%,$(objects)) + +md5 : $(subst %,%_MD5,$(objects)) + +dist: + @$(PAK) + +############################################################################### +# Downloading, checking, md5sum +############################################################################### + +$(patsubst %,$(DIR_CHK)/%,$(objects)) : + @$(CHECK) + +$(patsubst %,$(DIR_DL)/%,$(objects)) : + @$(LOAD) + +$(subst %,%_MD5,$(objects)) : + @$(MD5) + +############################################################################### +# Installation Details +############################################################################### + +$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) + @$(PREBUILD) + @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE) + cd $(DIR_APP) && ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var + cd $(DIR_APP) && make $(MAKETUNING) + cd $(DIR_APP) && make install + + install -v -m 644 $(DIR_SRC)/config/backup/includes/monit \ + /var/ipfire/backup/addons/includes/monit + + # Install default configuration + install -v -m 600 $(DIR_SRC)/config/monit/monitrc /etc + + # Install start links and backup include file. + ln -sf ../init.d/monit /etc/rc.d/rc3.d/S60monit + ln -sf ../init.d/monit /etc/rc.d/rc0.d/K40monit + ln -sf ../init.d/monit /etc/rc.d/rc6.d/K40monit + + @rm -rf $(DIR_APP) + @$(POSTBUILD) diff --git a/lfs/nmap b/lfs/nmap index 38b6da9..a7870da 100644 --- a/lfs/nmap +++ b/lfs/nmap @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2011 IPFire Team info@ipfire.org # +# Copyright (C) 2015 IPFire Team info@ipfire.org # # # # 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 # @@ -24,7 +24,7 @@
include Config
-VER = 6.01 +VER = 6.47
THISAPP = nmap-$(VER) DL_FILE = $(THISAPP).tar.bz2 @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = nmap -PAK_VER = 6 +PAK_VER = 7
DEPS = ""
@@ -44,7 +44,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = a1a71940f238abb835dbf3ee7412bcea +$(DL_FILE)_MD5 = edfe81f6763223c0a29bfa15a8526e2a
install : $(TARGET)
diff --git a/lfs/ntp b/lfs/ntp index a6f7ff6..c3d8d58 100644 --- a/lfs/ntp +++ b/lfs/ntp @@ -24,7 +24,7 @@
include Config
-VER = 4.2.6p5 +VER = 4.2.8
THISAPP = ntp-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 00df80a84ec9528fcfb09498075525bc +$(DL_FILE)_MD5 = 6972a626be6150db8cfbd0b63d8719e7
install : $(TARGET)
diff --git a/lfs/openssl b/lfs/openssl index 186ea6c..82f26bd 100644 --- a/lfs/openssl +++ b/lfs/openssl @@ -24,7 +24,7 @@
include Config
-VER = 1.0.1j +VER = 1.0.1k
THISAPP = openssl-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -51,7 +51,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = f7175c9cd3c39bb1907ac8bba9df8ed3 +$(DL_FILE)_MD5 = d4f002bd22a56881340105028842ae1f
install : $(TARGET)
@@ -105,6 +105,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) no-mdc2 \ no-rc5 \ no-srp \ + no-ssl2 \ + no-ssl3 \ $(CONFIGURE_ARGS) \ -DSSL_FORBID_ENULL \ -DHAVE_CRYPTODEV \ diff --git a/lfs/openssl-compat b/lfs/openssl-compat index 683d979..52a8e91 100644 --- a/lfs/openssl-compat +++ b/lfs/openssl-compat @@ -24,7 +24,7 @@
include Config
-VER = 0.9.8zc +VER = 0.9.8zd
THISAPP = openssl-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 1b239eea3a60d67863e7b66700e47a16 +$(DL_FILE)_MD5 = e9b9ee12f2911e1a378e2458d9bfff77
install : $(TARGET)
diff --git a/lfs/squid-accounting b/lfs/squid-accounting index 184c922..7eae4fb 100644 --- a/lfs/squid-accounting +++ b/lfs/squid-accounting @@ -15,7 +15,7 @@ THISAPP = squid-accounting-$(VER) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = squid-accounting -PAK_VER = 3 +PAK_VER = 4
DEPS = "perl-DBI perl-DBD-SQLite perl-File-ReadBackwards perl-PDF-API2 sendEmail"
diff --git a/lfs/u-boot b/lfs/u-boot index eafb592..28f6508 100644 --- a/lfs/u-boot +++ b/lfs/u-boot @@ -24,7 +24,7 @@
include Config
-VER = 2013.10 +VER = 2014.04
THISAPP = u-boot-$(VER) DL_FILE = $(THISAPP).tar.bz2 @@ -41,7 +41,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = a076a044b64371edc52f7e562b13f6b2 +$(DL_FILE)_MD5 = 6d2116d1385a66e9a59742caa9d62a54
install : $(TARGET)
@@ -84,7 +84,6 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) # Install pandaboard uboot as default cd $(DIR_APP) && install MLO /boot/ cd $(DIR_APP) && install u-boot.img /boot/ - cp -vf $(DIR_SRC)/config/u-boot/* /boot/ cd $(DIR_APP) && make distclean
# Wandboard Quad @@ -111,9 +110,24 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) /usr/share/u-boot/wandboard_solo cd $(DIR_APP) && make distclean
+ # LeMaker Banana Pi + -mkdir -pv /usr/share/u-boot/banana_pi + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/u-boot/sunxi/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/u-boot/sunxi/002-uboot-jwrdegoede-psci-support.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/u-boot/sunxi/003-uboot-fix-gmac-not-working-reliable-on-bananapi.patch + cd $(DIR_APP) && make CROSS_COMPILE="" Bananapi_config + cd $(DIR_APP) && make CROSS_COMPILE="" HOSTCC="gcc $(CFLAGS)" + cd $(DIR_APP) && install -v -m 644 u-boot-sunxi-with-spl.bin \ + /usr/share/u-boot/banana_pi + # mkimage cd $(DIR_APP) && make CROSS_COMPILE="" HOSTCC="gcc $(CFLAGS)" tools cd $(DIR_APP) && install -v -m 755 tools/mkimage /usr/bin
+ # config (uEnv.txt) + cp -vf $(DIR_SRC)/config/u-boot/* /boot/ + # patch real Kernel version to uEnv.txt + sed -e "s/xxxKVERxxx/$(KVER)/g" -i /boot/uEnv.txt + @rm -rf $(DIR_APP) @$(POSTBUILD) diff --git a/lfs/wireless-regdb b/lfs/wireless-regdb index 7c1dbe8..17a6450 100644 --- a/lfs/wireless-regdb +++ b/lfs/wireless-regdb @@ -24,7 +24,7 @@
include Config
-VER = 2013.02.13 +VER = 2014.11.18
THISAPP = wireless-regdb-$(VER) DL_FILE = $(THISAPP).tar.xz @@ -41,7 +41,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 46a4aa49282ea6713c3cf28cc2fc600f +$(DL_FILE)_MD5 = d750c402c5510add7380edcb1d9b75b2
install : $(TARGET)
diff --git a/lfs/wpa_supplicant b/lfs/wpa_supplicant index 5b1125c..1cebaab 100644 --- a/lfs/wpa_supplicant +++ b/lfs/wpa_supplicant @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2014 IPFire Team info@ipfire.org # +# Copyright (C) 2007-2015 IPFire Team info@ipfire.org # # # # 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 # @@ -24,7 +24,7 @@
include Config
-VER = 2.2 +VER = 2.3
THISAPP = wpa_supplicant-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -41,7 +41,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 238e8e888bbd558e1a57e3eb28d1dd07 +$(DL_FILE)_MD5 = f2ed8fef72cf63d8d446a2d0a6da630a
install : $(TARGET)
diff --git a/make.sh b/make.sh index 575380d..ec88aba 100755 --- a/make.sh +++ b/make.sh @@ -408,6 +408,7 @@ buildipfire() { i586) # x86-pae (Native and new XEN) kernel build ipfiremake linux KCFG="-pae" + ipfiremake backports KCFG="-pae" ipfiremake cryptodev KCFG="-pae" ipfiremake e1000e KCFG="-pae" ipfiremake igb KCFG="-pae" @@ -416,6 +417,7 @@ buildipfire() {
# x86 kernel build ipfiremake linux KCFG="" + ipfiremake backports KCFG="" ipfiremake cryptodev KCFG="" ipfiremake e1000e KCFG="" ipfiremake igb KCFG="" @@ -426,11 +428,13 @@ buildipfire() { armv5tel) # arm-rpi (Raspberry Pi) kernel build ipfiremake linux KCFG="-rpi" + ipfiremake backports KCFG="-rpi" ipfiremake cryptodev KCFG="-rpi" ipfiremake linux-initrd KCFG="-rpi"
# arm multi platform (Panda, Wandboard ...) kernel build ipfiremake linux KCFG="-multi" + ipfiremake backports KCFG="-multi" ipfiremake cryptodev KCFG="-multi" ipfiremake e1000e KCFG="-multi" ipfiremake igb KCFG="-multi" @@ -439,6 +443,7 @@ buildipfire() {
# arm-kirkwood (Dreamplug, ICY-Box ...) kernel build ipfiremake linux KCFG="-kirkwood" + ipfiremake backports KCFG="-kirkwood" ipfiremake cryptodev KCFG="-kirkwood" ipfiremake e1000e KCFG="-kirkwood" ipfiremake igb KCFG="-kirkwood" @@ -728,6 +733,7 @@ buildipfire() { ipfiremake iftop ipfiremake motion ipfiremake joe + ipfiremake monit ipfiremake nut ipfiremake watchdog ipfiremake libpri diff --git a/src/initscripts/init.d/console b/src/initscripts/init.d/console index 7381a69..8757b4d 100644 --- a/src/initscripts/init.d/console +++ b/src/initscripts/init.d/console @@ -17,7 +17,7 @@ . ${rc_functions} eval $(/usr/local/bin/readhash /var/ipfire/main/settings)
-FONT="LatArCyrHeb-16" +FONT="latarcyrheb-sun16" KEYMAP_CORRECTIONS="euro2" UNICODE="1" BROKEN_COMPOSE="0" diff --git a/src/initscripts/init.d/monit b/src/initscripts/init.d/monit new file mode 100644 index 0000000..02f47e4 --- /dev/null +++ b/src/initscripts/init.d/monit @@ -0,0 +1,39 @@ +#!/bin/sh +######################################################################## +# Begin $rc_base/init.d/monit +# +# Description : monit monitoring daemon +# +######################################################################## + +. /etc/sysconfig/rc +. ${rc_functions} + +case "${1}" in + start) + boot_mesg "Starting monit..." + loadproc /usr/bin/monit + ;; + + stop) + boot_mesg "Stopping monit..." + killproc /usr/bin/monit + ;; + + restart) + ${0} stop + sleep 1 + ${0} start + ;; + + status) + statusproc /usr/bin/monit + ;; + + *) + echo "Usage: ${0} {start|stop|restart|status}" + exit 1 + ;; +esac + +# End $rc_base/init.d/monit diff --git a/src/installer/dracut-module/run-installer.sh b/src/installer/dracut-module/run-installer.sh index ea9669a..33c8c4b 100644 --- a/src/installer/dracut-module/run-installer.sh +++ b/src/installer/dracut-module/run-installer.sh @@ -12,7 +12,7 @@ fi echo -en '\033%G' && kbd_mode -u
# Load default console font -setfont LatArCyrHeb-16 +setfont latarcyrheb-sun16
# Silence the kernel echo >/proc/sys/kernel/printk "1 4 1 7" diff --git a/src/installer/main.c b/src/installer/main.c index d02db28..c97776d 100644 --- a/src/installer/main.c +++ b/src/installer/main.c @@ -216,40 +216,55 @@ static char* get_system_release() { }
static char* center_string(const char* str, int width) { + if (!str) + return NULL; + + char* string = NULL; unsigned int str_len = strlen(str);
- unsigned int indent_length = (width - str_len) / 2; - char indent[indent_length + 1]; + if (str_len == width) { + string = strdup(str);
- for (unsigned int i = 0; i < indent_length; i++) { - indent[i] = ' '; - } - indent[indent_length] = '\0'; + } else if (str_len > width) { + string = strdup(str); + string[width - 1] = '\0';
- char* string = NULL; - if (asprintf(&string, "%s%s", indent, str) < 0) - return NULL; + } else { + unsigned int indent_length = (width - str_len) / 2; + char indent[indent_length + 1]; + + for (unsigned int i = 0; i < indent_length; i++) { + indent[i] = ' '; + } + indent[indent_length] = '\0'; + + if (asprintf(&string, "%s%s", indent, str) < 0) + return NULL; + }
return string; }
-#define DEFAULT_LANG "English" -#define NUM_LANGS 10 +#define DEFAULT_LANG "en_US.utf8" +#define NUM_LANGS 13
static struct lang { const char* code; char* name; } languages[NUM_LANGS + 1] = { - { "da.utf8", "Danish (Dansk)" }, - { "nl_NL.utf8", "Dutch (Nederlands)" }, - { "en_US.utf8", "English" }, - { "fr_FR.utf8", "French (Français)" }, - { "de_DE.utf8", "German (Deutsch)" }, - { "pl_PL.utf8", "Polish (Polski)" }, - { "pt_BR.utf8", "Portuguese (Brasil)" }, - { "ru_RU.utf8", "Russian (Русский)" }, - { "es_ES.utf8", "Spanish (Español)" }, - { "tr_TR.utf8", "Turkish (Türkçe)" }, + { "fa.utf8", "فارسی (Persian)" }, + { "da.utf8", "Dansk (Danish)" }, + { "es.utf8", "Español (Spanish)" }, + { "en.utf8", "English" }, + { "fr.utf8", "Français (French)" }, + { "hr.utf8", "Hrvatski (Croatian)" }, + { "it.utf8", "Italiano (Italian)" }, + { "de.utf8", "Deutsch (German)" }, + { "nl.utf8", "Nederlands (Dutch)" }, + { "pl.utf8", "Polski (Polish)" }, + { "pt.utf8", "Portuguese (Brasil)" }, + { "ru.utf8", "Русский (Russian)" }, + { "tr.utf8", "Türkçe (Turkish)" }, { NULL, NULL }, };
@@ -261,6 +276,7 @@ static struct config { int disable_swap; char download_url[STRING_SIZE]; char postinstall[STRING_SIZE]; + char* language; } config = { .unattended = 0, .serial_console = 0, @@ -269,6 +285,7 @@ static struct config { .disable_swap = 0, .download_url = DOWNLOAD_URL, .postinstall = "\0", + .language = DEFAULT_LANG, };
static void parse_command_line(struct config* c) { @@ -340,7 +357,6 @@ int main(int argc, char *argv[]) { int rc = 0; char commandstring[STRING_SIZE]; int choice; - char language[STRING_SIZE]; char message[STRING_SIZE]; char title[STRING_SIZE]; int allok = 0; @@ -373,7 +389,8 @@ int main(int argc, char *argv[]) {
// Draw title char* roottext = center_string(system_release, screen_cols); - newtDrawRootText(0, 0, roottext); + if (roottext) + newtDrawRootText(0, 0, roottext);
snprintf(title, sizeof(title), "%s - %s", NAME, SLOGAN);
@@ -393,7 +410,7 @@ int main(int argc, char *argv[]) { char* langnames[NUM_LANGS + 1];
for (unsigned int i = 0; i < NUM_LANGS; i++) { - if (strcmp(languages[i].name, DEFAULT_LANG) == 0) + if (strcmp(languages[i].code, DEFAULT_LANG) == 0) choice = i;
langnames[i] = languages[i].name; @@ -406,10 +423,10 @@ int main(int argc, char *argv[]) { assert(choice <= NUM_LANGS);
fprintf(flog, "Selected language: %s (%s)\n", languages[choice].name, languages[choice].code); - snprintf(language, sizeof(language), "%s", languages[choice].code); + config.language = languages[choice].code;
- setenv("LANGUAGE", language, 1); - setlocale(LC_ALL, language); + setlocale(LC_ALL, config.language); + setenv("LANGUAGE", config.language, 1); }
// Set helpline @@ -419,7 +436,8 @@ int main(int argc, char *argv[]) { else helpline = center_string(_("<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen"), screen_cols);
- newtPushHelpLine(helpline); + if (helpline) + newtPushHelpLine(helpline);
if (!config.unattended) { snprintf(message, sizeof(message), @@ -770,7 +788,7 @@ int main(int argc, char *argv[]) { }
/* Save language und local settings */ - write_lang_configs(language); + write_lang_configs(config.language);
/* Build cache lang file */ snprintf(commandstring, STRING_SIZE, "/usr/sbin/chroot /harddisk /usr/bin/perl -e "require '" CONFIG_ROOT "/lang.pl'; &Lang::BuildCacheLang""); diff --git a/src/installer/po/ar.po b/src/installer/po/ar.po index a10146e..b138c96 100644 --- a/src/installer/po/ar.po +++ b/src/installer/po/ar.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Arabic (http://www.transifex.com/projects/p/ipfire/language/ar/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: ar\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/ca.po b/src/installer/po/ca.po index 54e3699..a7d97cf 100644 --- a/src/installer/po/ca.po +++ b/src/installer/po/ca.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Catalan (http://www.transifex.com/projects/p/ipfire/language/ca/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: ca\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/cs_CZ.po b/src/installer/po/cs_CZ.po index 101c98d..4cfc7aa 100644 --- a/src/installer/po/cs_CZ.po +++ b/src/installer/po/cs_CZ.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/ipfire/language/cs_CZ/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: cs_CZ\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/da.po b/src/installer/po/da.po index d15c917..75918db 100644 --- a/src/installer/po/da.po +++ b/src/installer/po/da.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Danish (http://www.transifex.com/projects/p/ipfire/language/da/)%5Cn" "MIME-Version: 1.0\n" @@ -18,85 +18,145 @@ msgstr "" "Language: da\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr "OK"
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr "Annuller"
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr "Jeg accepterer brugerlicensen"
-#: main.c:312 -msgid "Language selection" +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." msgstr ""
-#: main.c:312 +#: main.c:403 +msgid "Language selection" +msgstr "Vælg sprog" + +#: main.c:403 msgid "Select the language you wish to use for the installation." +msgstr "Vælg det sprog du ønsker at anvende under installationen." + +#: main.c:418 +msgid "Unattended mode" msgstr ""
-#: main.c:323 +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr "<Tab>/<Alt-Tab> mellem elementer | <Space> vælger | <F12> næste skærm"
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" "\n" "Selecting Cancel on any of the following screens will reboot the computer." -msgstr "" +msgstr "Velkommen til %s installationsprogram.\n\nVælg Annuller på ethvert tidspunkt for at genstarte computeren."
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr "Start installationen"
-#: main.c:339 -msgid "No local source media found. Starting download." -msgstr "Fandt ikke en lokal kilde. Henter fra internettet." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." -msgstr "Henter installationsbillede ..." +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr ""
-#: main.c:342 -msgid "Download error" -msgstr "Fejl under hentning" +#: main.c:460 +msgid "Download installation image" +msgstr ""
-#: main.c:376 -msgid "License Agreement" +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" +msgstr "" + +#: main.c:501 +msgid "Downloading installation image..." +msgstr "" + +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" +msgstr "" + +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" msgstr ""
-#: main.c:377 +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 +msgid "License Agreement" +msgstr "Licensaftale" + +#: main.c:544 msgid "License not accepted!" msgstr "Brugerlicensen ikke accepteret!"
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr "Fandt ikke en harddisk."
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr "Vælg harddisk"
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr "Vælg den eller de harddisk(e) du vil installere IPFire på. Diskene bliver først partitioneret og dernæst bliver der oprettet filsystemer.\n\nAL DATA PÅ DISKENE BLIVER SLETTET."
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr "Ingen harddisk valgt.\n\nVælg venligst en eller flere harddiske du vil installere IPFire på."
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -106,15 +166,15 @@ msgid "" "Do you agree to continue?" msgstr "Installationsprogrammet forbereder nu den eller de valgte harddiske:\n\n%s\n\nVil du fortsætte?"
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr "Harddisk opsætning"
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr "Slet alle data"
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -125,119 +185,146 @@ msgid "" "Do you agree to continue?" msgstr "Installationsprogrammet vil nu opsætte RAID konfigurationen på de valgte harddiske:\n\n%s\n%s\n\nVil du fortsætte?"
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr "RAID opsætning"
-#: main.c:466 -msgid "You disk configuration is currently not supported." -msgstr "Din harddisk konfiguration understøttes ikke pt." +#: main.c:640 +msgid "Your disk configuration is currently not supported." +msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr "Din harddisk er for lille."
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." -msgstr "" +msgstr "Din harddisk er meget lille, men du kan fortsætte uden en swap partition."
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr "ext4 filsystem"
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr "ext4 filsystem uden journal"
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr "XFS filsystem"
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr "ReiserFS filsystem"
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr "Vælg filsystem"
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr "Vælg venligst et filsystem:"
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr "Bygger RAID..."
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr "Kunne ikke bygge RAID."
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr "Partitionerer harddisk..."
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr "Kunne ikke partitionere harddisk."
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr "Opretter filsystemer..."
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr "Kunne ikke oprette filsystemer."
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr "Kunne ikke forbinde til filsystemer."
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr "Installerer systemet..."
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr "Kunne ikke installere systemet."
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr "Installerer sprog arkivet..."
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr "Kunne ikke installere sprog arkivet."
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr "Installerer bootloader..."
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." -msgstr "" +msgstr "Kunne ikke gemme til /etc/default/grub."
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr "Kunne ikke installere bootloader."
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" "\n" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." -msgstr "" +msgstr "%s blev installeret korrekt!\n\nFjern venligst installationsmedier fra systemet og vælg Genstart. Efter genstart bliver du bedt om at opsætte netværket og system kodeord. Efter opsætningen, besøg da https://%s:444 (eller hvad du navngav %s) fra din internet browser for at anvende web konsollen."
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr "Tillykke!"
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr "Genstart"
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." -msgstr "" +msgstr "Installationen fejlede. Vælg Ok for at genstarte." diff --git a/src/installer/po/de.po b/src/installer/po/de.po index f4487a0..93893d9 100644 --- a/src/installer/po/de.po +++ b/src/installer/po/de.po @@ -4,14 +4,15 @@ # # Translators: # Michael Tremer michael.tremer@ipfire.org, 2014 +# Peter Cloudstone rmg-mainz@web.de, 2014 # Stefan Schantl stefan.schantl@ipfire.org, 2014 msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 16:04+0000\n" -"Last-Translator: Stefan Schantl stefan.schantl@ipfire.org\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-07 15:02+0000\n" +"Last-Translator: Peter Cloudstone rmg-mainz@web.de\n" "Language-Team: German (http://www.transifex.com/projects/p/ipfire/language/de/)%5Cn" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,31 +20,40 @@ msgstr "" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr "OK"
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr "Abbrechen"
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr "Ich akzeptiere die Lizenz"
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "Warnung: Automatische Installation startet in 10 Sekunden..." + +#: main.c:403 msgid "Language selection" msgstr "Sprachauswahl"
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr "Wählen Sie die gewünschte Sprache für den Installationsprozess aus."
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "Automatikmodus" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr "<Tab>/<Alt-Tab> um zu wechseln | <Leertaste> wählt aus | <F12> nächster Bildschirm"
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -51,53 +61,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr "Willkommen zum %s Installationsprogramm.\n\nWenn Sie auf irgendeiner der folgenden Seiten 'Abbrechen' auswählen, wird der Computer neu gestartet."
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr "Installation beginnen"
-#: main.c:339 -msgid "No local source media found. Starting download." -msgstr "Kein lokales Quellmedium gefunden. Starte Download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "Der Installer versucht nun, das Installationsimage herunterzuladen." + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "Kein Quelllaufwerk gefunden.\n\nBitte versuchen Sie, das erforderliche Installationsabbild herunterzuladen." + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "Bitte stellen Sie sicher, dass der Computer mit einem Netzwerk verbunden ist, danach wird das Installationsprogramm versuchen, eine IP-Adresse zu erhalten." + +#: main.c:460 +msgid "Download installation image" +msgstr "Installationsabbild wird heruntergeladen" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "Versuche, Netzwerk (DHCP) zu starten..." + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "Das Netzwerk konnte nicht gestartet werden, es ist aber für das Fortfahren erforderlich.\n\nBitte verbinden Sie den Computer mit einem Netzwerk mit DHCP und versuchen Sie es erneut." + +#: main.c:487 main.c:516 +msgid "Retry" +msgstr "Erneut versuchen"
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr "Lade Installationsimage herunter..."
-#: main.c:342 -msgid "Download error" -msgstr "Fehler beim Download" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" +msgstr "MD5-Prüfsummen stimmen nicht überein"
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "Das Installationsabbild konnte nicht heruntergeladen werden.\nGrund: %s\n\n%s" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "Konnte %s nicht auf %s mounten:\n%s\n" + +#: main.c:543 msgid "License Agreement" msgstr "Lizenzvereinbarung"
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr "Lizenz nicht akzeptiert!"
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr "Es wurde keine Festplatte gefunden."
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr "Festplattenauswahl"
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr "Wählen Sie die Festplatte(n) auf denen IPFire installiert werden soll. Diese wird/werden zuerst partitioniert und danach mit einem Dateisystem ausgestattet.\n\nSÄMTLICHE DATEN AUF DER FESTPLATTE GEHEN VERLOREN."
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr "Keine Festplatte ausgewählt.\n\nBitte wählen Sie eine oder mehrere Festplatten auf denen IPFire installiert werden soll aus."
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -107,15 +168,15 @@ msgid "" "Do you agree to continue?" msgstr "Das Installationsprogramm wird die folgende Festplatte nun vorbereiten:\n\n%s\n\nMöchten Sie damit fortfahren?"
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr "Disk-Setup"
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr "Alle Daten löschen"
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -126,119 +187,146 @@ msgid "" "Do you agree to continue?" msgstr "Das Installationsprogramm wird nun einen RAID Verbund auf den folgenden Festplatten erstellen:\n\n%s\n%s\n\nMöchten Sie damit fortfahren?"
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr "RAID-Setup"
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr "Die gewählte Festplattenkonstellation wird momentan nicht unterstützt."
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr "Ihre Festplatte ist zu klein."
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr "Die gewählte Festplatte ist sehr klein, die Installation kann aber ohne Swap Partition fortgesetzt werden."
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr "ext4-Dateisystem"
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr "ext4-Dateisystem ohne Journal"
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr "XFS-Dateisystem"
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr "ReiserFS-Dateisystem"
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr "Dateisystemauswahl"
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr "Bitte wählen Sie ein Dateisystem:"
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr "Erstelle RAID..."
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr "Das RAID konnte nicht erstellt werden."
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr "Partitioniere die Festplatte..."
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr "Die Festplatte konnte nicht partitioniert werden."
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr "Erstelle Dateisysteme..."
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr "Die Dateisysteme konnten nicht erstellt werden."
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr "Die Dateisysteme konnten nicht eingehangen werden."
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr "Installiere das System..."
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr "Das System konnte nicht installiert werden."
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr "Installiere den Sprachdateicache..."
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr "Der Sprachdateicache konnte nicht erstellt werden."
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr "Installiere den Bootloader..."
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr "/etc/default/grub konnte nicht geschrieben werden."
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr "Der Bootloader konnte nicht installiert werden."
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "Eine Sicherungskopie wurde auf dem Installationsmedium gefunden.\n\nMöchten Sie die Sicherungskopie wiederherstellen?" + +#: main.c:827 +msgid "Yes" +msgstr "Ja" + +#: main.c:827 +msgid "No" +msgstr "Nein" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "Bei der Wiederherstellung der Sicherungskopie trat ein Fehler auf." + +#: main.c:869 +msgid "Running post-install script..." +msgstr "Führe Post-Installations-Skripte aus..." + +#: main.c:870 +msgid "Post-install script failed." +msgstr "Post-Installations-Skript fehlgeschlagen." + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" "\n" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." -msgstr "%s wurde erfolgreich installiert.\n\nEntfernen Sie bitte alle Installionsmedian aus dem Computer und drücken Sie den "Neustarten" Knopf . \n\nNach dem erfolgten Neustart wird das Setup-Programm gestartet, in dem Sie Netzwerkkarten und die Systempasswörter konfigurieren können. Sobald dies fertiggestellt ist, können Sie in Ihrem Webbrowser die Weboberfläche mit https://%s:444 (oder welchen Namen Sie Ihrem %s auch immer gegeben haben) erreichen." +msgstr "%s wurde erfolgreich installiert.\n\nEntfernen Sie bitte alle Installionsmedien aus dem Computer und drücken Sie "Neustarten". \n\nNach dem erfolgten Neustart wird das Setup-Programm gestartet, in dem Sie Netzwerkkarten und die Systempasswörter konfigurieren können. Sobald dies fertiggestellt ist, können Sie in Ihrem Webbrowser die Weboberfläche über https://%s:444 (oder welchen Namen Sie Ihrem %s auch immer gegeben haben) erreichen."
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr "Herzlichen Glückwunsch!"
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr "Neustarten"
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "Installation fehlgeschlagen. Drücken Sie "OK" für einen Neustart des Systems." diff --git a/src/installer/po/el_GR.po b/src/installer/po/el_GR.po index d27fe7b..cf5ec2b 100644 --- a/src/installer/po/el_GR.po +++ b/src/installer/po/el_GR.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Greek (Greece) (http://www.transifex.com/projects/p/ipfire/language/el_GR/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: el_GR\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/es.po b/src/installer/po/es.po index d4812af..d58cee8 100644 --- a/src/installer/po/es.po +++ b/src/installer/po/es.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Spanish (http://www.transifex.com/projects/p/ipfire/language/es/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/fa.po b/src/installer/po/fa.po index 81d3631..67d4d26 100644 --- a/src/installer/po/fa.po +++ b/src/installer/po/fa.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" -"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-12 18:37+0000\n" +"Last-Translator: Khalil Delavaran khalil.delavaran@gmail.com\n" "Language-Team: Persian (http://www.transifex.com/projects/p/ipfire/language/fa/)%5Cn" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,85 +18,145 @@ msgstr "" "Language: fa\n" "Plural-Forms: nplurals=1; plural=0;\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr "بله"
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr "نمی خواهم"
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr "من این پروانه را می پذیرم."
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "گوشزد: برپاسازی خودکار تا 10 ثانیه دیگر شروع می شود..." + +#: main.c:403 msgid "Language selection" -msgstr "" +msgstr "گزینش زبان"
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." -msgstr "" +msgstr "گزینش زبان شما برای بکارگیری در برپاسازی." + +#: main.c:418 +msgid "Unattended mode" +msgstr "حالت خودکار"
-#: main.c:323 +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr "<Tab>/<Alt-Tab> میان عنصری | <Space> گزینش | <F12> برای برگه پسین"
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" "\n" "Selecting Cancel on any of the following screens will reboot the computer." -msgstr "" +msgstr "به برنامه برپا سازی %s خوش آمدید.\n\nبرای راه اندازی دوباره کامپیوتر، نمی خواهم را در هر صفحه ای می توانید گزینش کنید."
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr "آغاز برپا سازی"
-#: main.c:339 -msgid "No local source media found. Starting download." -msgstr "هیچ رسانه محلی یافت نشد. دانلود آغاز شد." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "دانلود ایمیج برپاسازی" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:487 main.c:516 +msgid "Retry" +msgstr "دوباره" + +#: main.c:501 +msgid "Downloading installation image..." msgstr "در حال دانلود ایمیج برای برپا سازی..."
-#: main.c:342 -msgid "Download error" -msgstr "ایراد در دانلود" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" +msgstr "" + +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "ایمیج برپاسازی را نمی توان دانلود کرد.\nزیرا: %s\n\n%s"
-#: main.c:376 +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "نمی توان %s را به %s مونت کرد:\n%s\n" + +#: main.c:543 msgid "License Agreement" -msgstr "" +msgstr "موافقنامه"
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr "پروانه پذیرفته نشد!"
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr "هارد دیسک یافت نشد."
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr "گزینش دیسک"
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr "دیسک (های) را برای برپاسازی IPFire گزینش کنید. نخست آنها را پارنیشین بندی کرده، و سپس، سیستم فایلی برای پارتیشن ها برگزینید.\n\nهمه داده های دیسک پاک می شوند."
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr "هیچ دیسکی گزینش نشده است.\n\nخواهشمند است یک دیسک یا بیشتر را برای برپا سازی IPFire گزینش کنید."
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -106,15 +166,15 @@ msgid "" "Do you agree to continue?" msgstr "آماده سازی دیسک سخت برای برپا سازی برنامه :\n\n%s\n\nآیا شما گرایش به ادامه دارید؟"
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr "پیکربندی دیسک"
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr "پاک کردن همه داده ها"
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -125,119 +185,146 @@ msgid "" "Do you agree to continue?" msgstr "پیکربندی RAID بر روی هارد دیسکهای گزینش شده برای برپا سازی برنامه\n\n%s\n%s\n\nآیا شما گرایش به ادامه دارید؟"
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr "پیکربندی RAID"
-#: main.c:466 -msgid "You disk configuration is currently not supported." -msgstr "پیکربندی دیسک شما پشتیبانی نمی شود." +#: main.c:640 +msgid "Your disk configuration is currently not supported." +msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr "هارد دیسک شما بسیار کوچک است."
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." -msgstr "" +msgstr "هارد دیسک شما بسیار کوچک است، ولی می توانید بدون ساخت swap پارتیشن ادامه دهید."
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr "فایل سیستم ext4"
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr "سیستم فایل ext4 بدون روزنامه"
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr "فایل سیستم XFS"
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr "فایل سیستم RaiserFS"
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr "گزینش فایل سیستم"
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr "خواهشمند است فایل سیستم خود را گزینش کنید:"
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr "ساخت RAID..."
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr "ناتوانی در ساخت RAID."
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr "پارتیشن بندی دیسک..."
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr "ناتوانی در پارتیشین بندی دیسک."
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr "ساخت سیستم فایل..."
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr "ناتوانی در ساخت سیستم فایل."
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr "ناتوانی در مونت کردن سیستم فایل."
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr "برپا سازی سیستم..."
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr "ناتوانی در برپاسازی سیستم."
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr "در حال برپا سازی کش زبان..."
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr "ناتوانی در برپا سازی کش زبان."
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr "برپا سازی بوت لودر..."
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." -msgstr "" +msgstr "نمی توان /etc/default/grub را برای ویرایش باز کرد."
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr "ناتوانی در برپا سازی بوت لودر."
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "بله" + +#: main.c:827 +msgid "No" +msgstr "خیر" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" "\n" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." -msgstr "" +msgstr "%s برپا سازی شده است!\n\nخواهشمند است هر برپاسازی میانه ای از سیستم را پاک کنید و دکمه ریبوت را بزنید. پس از یک بار ریستارت سیستم، شما به پرسش های پیکربندی شبکه و گذر واژه سیستم پاسخ دهید. سپس برای پیکربندی پیشخوان وب، باید در مرورگر خود آدرس https://%s:444 (یا هر نامیکه گزینشی شما %s )را بنویسید."
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr "شادباش می گوییم!"
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr "ریبوت"
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." -msgstr "" +msgstr "برپا سازی شکست خورد. برای راه اندازی دوباره بلی را فشار دهید." diff --git a/src/installer/po/fr.po b/src/installer/po/fr.po index a4af363..93ba210 100644 --- a/src/installer/po/fr.po +++ b/src/installer/po/fr.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: French (http://www.transifex.com/projects/p/ipfire/language/fr/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/hr.po b/src/installer/po/hr.po new file mode 100644 index 0000000..3b67c36 --- /dev/null +++ b/src/installer/po/hr.po @@ -0,0 +1,329 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR The IPFire Project (www.ipfire.org) +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: IPFire Project\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" +"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"Language-Team: Croatian (http://www.transifex.com/projects/p/ipfire/language/hr/)%5Cn" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: hr\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 +msgid "OK" +msgstr "OK" + +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 +msgid "Cancel" +msgstr "Otkazati" + +#: main.c:176 +msgid "I accept this license" +msgstr "Prihvaćam ovu licencu" + +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 +msgid "Language selection" +msgstr "Odabir jezika" + +#: main.c:403 +msgid "Select the language you wish to use for the installation." +msgstr "Odaberite jezik koji želite koristiti za instalaciju." + +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 +msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" +msgstr "<Tab>/<Alt-Tab> Između odabira | <Space> Izaberi | <F12> Idući ekran" + +#: main.c:426 +#, c-format +msgid "" +"Welcome to the %s installation program.\n" +"\n" +"Selecting Cancel on any of the following screens will reboot the computer." +msgstr "Dobrodošli u %s instalacijski programa..\n\nOdabirom Otkazati na bilo kojem od sljedećih ekranima će se ponovno pokrenuti računalo." + +#: main.c:428 +msgid "Start installation" +msgstr "Pokrenite instalaciju" + +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" +msgstr "" + +#: main.c:501 +msgid "Downloading installation image..." +msgstr "" + +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" +msgstr "" + +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 +msgid "License Agreement" +msgstr "Ugovor o licenci" + +#: main.c:544 +msgid "License not accepted!" +msgstr "Licenca nije prihvaćena!" + +#: main.c:566 +msgid "No hard disk found." +msgstr "Tvrdi disk nije pronađen." + +#: main.c:587 +msgid "Disk Selection" +msgstr "Izbor diska" + +#: main.c:588 +msgid "" +"Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" +"\n" +"ALL DATA ON THE DISK WILL BE DESTROYED." +msgstr "Odaberite disk(ove) na koje želite instalirati IPFire. Prvo će biti podijeljeni, a zatim particije će se datotečni sustav staviti na njih.\n\nSVI PODACI NA DISKU ĆE BITI UNIŠTENI!" + +#: main.c:599 +msgid "" +"No disk has been selected.\n" +"\n" +"Please select one or more disks you want to install IPFire on." +msgstr "Disk nije izabran. \n\nOdaberite jedan ili više diskova na koje želite instalirati na IPFire." + +#: main.c:617 +#, c-format +msgid "" +"The installation program will now prepare the chosen harddisk:\n" +"\n" +" %s\n" +"\n" +"Do you agree to continue?" +msgstr "Instalacijski program će sada pripremiti odabrani tvrdi disk:\n\n %s\n\nSlažete li da nastavimo?" + +#: main.c:619 +msgid "Disk Setup" +msgstr "Postavke diska" + +#: main.c:620 main.c:630 +msgid "Delete all data" +msgstr "Izbriši sve podatke" + +#: main.c:627 +#, c-format +msgid "" +"The installation program will now set up a RAID configuration on the selected harddisks:\n" +"\n" +" %s\n" +" %s\n" +"\n" +"Do you agree to continue?" +msgstr "Instalacijski program će se sada postaviti RAID konfiguraciju na odabranim tvrdim diskovima:\n\n %s\n %s\n\nSlažete li da nastavimo?" + +#: main.c:629 +msgid "RAID Setup" +msgstr "Postavljanje RAIDa" + +#: main.c:640 +msgid "Your disk configuration is currently not supported." +msgstr "" + +#: main.c:655 +msgid "Your harddisk is too small." +msgstr "Vaš tvrdi disk je premali." + +#: main.c:671 +msgid "" +"Your harddisk is very small, but you can continue without a swap partition." +msgstr "Vaš tvrdi disk je dosta mali, ali možete nastaviti bez swap particije." + +#: main.c:684 +msgid "ext4 Filesystem" +msgstr "ext4 datotečni sustav" + +#: main.c:685 +msgid "ext4 Filesystem without journal" +msgstr "ext4 datotečni sustav bez journal-a" + +#: main.c:686 +msgid "XFS Filesystem" +msgstr "XFS datotečni sustav" + +#: main.c:687 +msgid "ReiserFS Filesystem" +msgstr "ReiserFS datotečni sustav" + +#: main.c:701 +msgid "Filesystem Selection" +msgstr "Izabir datotečnog sustava" + +#: main.c:701 +msgid "Please choose your filesystem:" +msgstr "Molimo odaberite svoj datotečni sustav:" + +#: main.c:712 +msgid "Building RAID..." +msgstr "Izgradnja RAIDa..." + +#: main.c:716 +msgid "Unable to build the RAID." +msgstr "Nije moguće izgraditi RAID." + +#: main.c:728 +msgid "Partitioning disk..." +msgstr "Particioniranje diska ..." + +#: main.c:732 +msgid "Unable to partition the disk." +msgstr "Nije moguće particionirati disk." + +#: main.c:739 +msgid "Creating filesystems..." +msgstr "Izrada datotečnog sustava ..." + +#: main.c:743 +msgid "Unable to create filesystems." +msgstr "Nije moguće stvoriti datotečni sustav." + +#: main.c:749 +msgid "Unable to mount filesystems." +msgstr "Nije moguće montirati datotečni sustav." + +#: main.c:760 +msgid "Installing the system..." +msgstr "Instaliranje sustava..." + +#: main.c:761 +msgid "Unable to install the system." +msgstr "Nije moguće instalirati sustav." + +#: main.c:777 +msgid "Installing the language cache..." +msgstr "Instaliranje cache-a jezika..." + +#: main.c:778 +msgid "Unable to install the language cache." +msgstr "Nije moguće instalirati cache jezika." + +#: main.c:783 +msgid "Installing the bootloader..." +msgstr "Instaliranje bootloadera..." + +#: main.c:790 +msgid "Unable to open /etc/default/grub for writing." +msgstr "Ne mogu otvoriti /etc/default/grub grub za pisanje." + +#: main.c:812 +msgid "Unable to install the bootloader." +msgstr "Nije moguće instalirati bootloader." + +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 +#, c-format +msgid "" +"%s was successfully installed!\n" +"\n" +"Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." +msgstr "%s uspješno je instaliran!\n\nMolimo uklonite sve instalacijske medije iz tog sustava i pritisnite gumb ponovno podizanje sustava. Nakon što je sustav ponovno podigne, od vas će biti zatraženo postavljanje mreže i lozinke sustava. Nakon toga, trebali usmjerite svoj web preglednik nahttps://%s:444 (ili koje god ste nazvali vaš %s) za postavke preko weba." + +#: main.c:882 +msgid "Congratulations!" +msgstr "Čestitamo!" + +#: main.c:882 +msgid "Reboot" +msgstr "Ponovno pokretanje" + +#: main.c:893 +msgid "Setup has failed. Press Ok to reboot." +msgstr "Postavljanje nije uspjelo. Pritisnite OK za ponovno podizanje sustava." diff --git a/src/installer/po/hu.po b/src/installer/po/hu.po index ac25009..7e9e198 100644 --- a/src/installer/po/hu.po +++ b/src/installer/po/hu.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Hungarian (http://www.transifex.com/projects/p/ipfire/language/hu/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: hu\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/id.po b/src/installer/po/id.po index 28d9ae3..e4cc4c1 100644 --- a/src/installer/po/id.po +++ b/src/installer/po/id.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/ipfire/language/id/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: id\n" "Plural-Forms: nplurals=1; plural=0;\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/it.po b/src/installer/po/it.po index 70d0098..d938f37 100644 --- a/src/installer/po/it.po +++ b/src/installer/po/it.po @@ -3,13 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Gabriele, 2014 +# luX lucianocataldo@gmail.com, 2014 msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" -"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-12-06 18:41+0000\n" +"Last-Translator: Gabriele\n" "Language-Team: Italian (http://www.transifex.com/projects/p/ipfire/language/it/)%5Cn" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -17,85 +19,145 @@ msgstr "" "Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" -msgstr "" +msgstr "OK"
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" -msgstr "" +msgstr "Annulla"
-#: main.c:145 +#: main.c:176 msgid "I accept this license" -msgstr "" +msgstr "Accetto questa licenza"
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "Attenzione: L'installazione automatica inizierà tra 10 secondi..." + +#: main.c:403 msgid "Language selection" -msgstr "" +msgstr "Scelta della lingua"
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." -msgstr "" +msgstr "Selezionare la lingua che si desidera utilizzare per l'installazione."
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "Modalità automatico" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" -msgstr "" +msgstr "<Tab>/<Alt-Tab> tra elementi | <Space> seleziona | <F12> schermata successiva"
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" "\n" "Selecting Cancel on any of the following screens will reboot the computer." -msgstr "" +msgstr "Benvenuti nel programma di installazione %s.\n\nSelezionando Annulla su una delle seguenti schermate si riavvia il computer."
-#: main.c:330 +#: main.c:428 msgid "Start installation" -msgstr "" +msgstr "Avvio installazione"
-#: main.c:339 -msgid "No local source media found. Starting download." -msgstr "" +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "Il programma di installazione proverà ora a scaricare l'immagine di installazione."
-#: main.c:340 -msgid "Downloading installation image ..." -msgstr "" +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "Nessuna unità di origine trovata.\n\nPuoi provare a scaricare l'immagine d'installazione richiesta."
-#: main.c:342 -msgid "Download error" -msgstr "" +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "Per piacere assicurati di collegare il tuo computer ad una rete e il programma d'installazione proverà ad acquisire un indirizzo IP." + +#: main.c:460 +msgid "Download installation image" +msgstr "Scaricamento immagine d'installazione" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "Provo ad avviare la rete (DHCP)..." + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "Non è stato possibile avviare la rete, ma è richiesto per continuare l'installazione.\n\nPer piacere collega il tuo computer ad una rete con un server DHCP e riprova." + +#: main.c:487 main.c:516 +msgid "Retry" +msgstr "Riprova" + +#: main.c:501 +msgid "Downloading installation image..." +msgstr "Scaricamento immagine di installazione..." + +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" +msgstr "Checksum MD5 non corrispondente" + +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "Non è stato possibile scaricare l'immagine di installazione.\nMotivo: %s\n\n%s" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "Impossibile montare %s su %s:\n %s\n"
-#: main.c:376 +#: main.c:543 msgid "License Agreement" -msgstr "" +msgstr "Contratto di licenza"
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" -msgstr "" +msgstr "Licenza non accettata!"
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." -msgstr "" +msgstr "Nessun Hard Disk trovato."
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" -msgstr "" +msgstr "Selezione disco"
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." -msgstr "" +msgstr "Selezionare il disco su cui si desidera installare IPFire. In primo luogo verrà partizionato, e quindi le partizioni avranno un filesystem.\n\nTUTTI I DATI SUL DISCO VERRANNO DISTRUTTI."
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." -msgstr "" +msgstr "Non è stato selezionato alcun disco.\n\nSi prega di selezionare uno o più dischi su cui si desidera installare IPFire."
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -103,17 +165,17 @@ msgid "" " %s\n" "\n" "Do you agree to continue?" -msgstr "" +msgstr "Il programma di installazione preparerà l'hard disk prescelto.\n\n%s\n\nSiete d'accordo di continuare?"
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" -msgstr "" +msgstr "Disco di Installazione"
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" -msgstr "" +msgstr "Elimina tutti i dati"
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -122,121 +184,148 @@ msgid "" " %s\n" "\n" "Do you agree to continue?" -msgstr "" +msgstr "Il programma di installazione configurerà il RAID sul hard disk selezionato:\n\n%s\n%s\n\nSiete d'accordo di continuare?"
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" -msgstr "" +msgstr "Installazione RAID"
-#: main.c:466 -msgid "You disk configuration is currently not supported." -msgstr "" +#: main.c:640 +msgid "Your disk configuration is currently not supported." +msgstr "La tua configurazione disco non è attualmente supportata."
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." -msgstr "" +msgstr "Il disco rigido è troppo piccolo."
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." -msgstr "" +msgstr "Il disco rigido è molto piccolo, ma puoi continuare senza una partizione di swap."
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" -msgstr "" +msgstr "Filesystem ext4"
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" -msgstr "" +msgstr "ext4 Filesystem senza journal"
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" -msgstr "" +msgstr "Filesystem XFS"
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" -msgstr "" +msgstr "Filesystem ReiserFS"
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" -msgstr "" +msgstr "Selezione del filesystem"
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" -msgstr "" +msgstr "Scegliere il filesystem:"
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." -msgstr "" +msgstr "Costruzione RAID..."
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." -msgstr "" +msgstr "Impossibile generare il RAID."
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." -msgstr "" +msgstr "Partizionamento del disco..."
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." -msgstr "" +msgstr "Impossibile partizionare il disco."
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." -msgstr "" +msgstr "Creazione filesystem..."
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." -msgstr "" +msgstr "Impossibile creare il filesystem."
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." -msgstr "" +msgstr "Impossibile montare il filesystem."
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." -msgstr "" +msgstr "Installazione del sistema..."
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." -msgstr "" +msgstr "Impossibile installare il sistema."
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." -msgstr "" +msgstr "Installazione della cache della lingua..."
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." -msgstr "" +msgstr "Impossibile installare la cache della lingua."
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." -msgstr "" +msgstr "Installazione del bootloader..."
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." -msgstr "" +msgstr "Impossibile aprire /etc/default/grub per la scrittura."
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." -msgstr "" +msgstr "Impossibile installare il bootloader." + +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "Un file di backup è stato trovato sull'immagine di installazione.\n\nVuoi ripristinare il backup?"
-#: main.c:666 +#: main.c:827 +msgid "Yes" +msgstr "Sì" + +#: main.c:827 +msgid "No" +msgstr "No" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "Si è verificato un errore durante il ripristino del file di backup" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "Esecuzione degli script post-installazione..." + +#: main.c:870 +msgid "Post-install script failed." +msgstr "Script post-installazione fallito." + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" "\n" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." -msgstr "" +msgstr "%s è stato installato con successo!\n\nSi prega di rimuovere eventuali supporti di installazione da questo sistema e premere il pulsante di riavvio. Una volta che il sistema è stato riavviato verrà chiesto di impostare le password di rete e di sistema.\nDopo di che, si dovrebbe puntare il browser web su https://%s:444 (o qualunque altro nome %s) per la console di configurazione web.\n "
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" -msgstr "" +msgstr "Congratulazioni!"
-#: main.c:671 +#: main.c:882 msgid "Reboot" -msgstr "" +msgstr "Riavvio"
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." -msgstr "" +msgstr "Installazione non riuscita. Premere Ok per riavviare." diff --git a/src/installer/po/ja.po b/src/installer/po/ja.po index 6cdadf5..5a14029 100644 --- a/src/installer/po/ja.po +++ b/src/installer/po/ja.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Japanese (http://www.transifex.com/projects/p/ipfire/language/ja/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: ja\n" "Plural-Forms: nplurals=1; plural=0;\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/ja_JP.po b/src/installer/po/ja_JP.po new file mode 100644 index 0000000..1243121 --- /dev/null +++ b/src/installer/po/ja_JP.po @@ -0,0 +1,329 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR The IPFire Project (www.ipfire.org) +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: IPFire Project\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-07-31 09:39+0000\n" +"Last-Translator: FULL NAME EMAIL@ADDRESS\n" +"Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/ipfire/language/ja_JP/)%5Cn" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ja_JP\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 +msgid "OK" +msgstr "" + +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 +msgid "Cancel" +msgstr "" + +#: main.c:176 +msgid "I accept this license" +msgstr "" + +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 +msgid "Language selection" +msgstr "" + +#: main.c:403 +msgid "Select the language you wish to use for the installation." +msgstr "" + +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 +msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" +msgstr "" + +#: main.c:426 +#, c-format +msgid "" +"Welcome to the %s installation program.\n" +"\n" +"Selecting Cancel on any of the following screens will reboot the computer." +msgstr "" + +#: main.c:428 +msgid "Start installation" +msgstr "" + +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" +msgstr "" + +#: main.c:501 +msgid "Downloading installation image..." +msgstr "" + +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" +msgstr "" + +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 +msgid "License Agreement" +msgstr "" + +#: main.c:544 +msgid "License not accepted!" +msgstr "" + +#: main.c:566 +msgid "No hard disk found." +msgstr "" + +#: main.c:587 +msgid "Disk Selection" +msgstr "" + +#: main.c:588 +msgid "" +"Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" +"\n" +"ALL DATA ON THE DISK WILL BE DESTROYED." +msgstr "" + +#: main.c:599 +msgid "" +"No disk has been selected.\n" +"\n" +"Please select one or more disks you want to install IPFire on." +msgstr "" + +#: main.c:617 +#, c-format +msgid "" +"The installation program will now prepare the chosen harddisk:\n" +"\n" +" %s\n" +"\n" +"Do you agree to continue?" +msgstr "" + +#: main.c:619 +msgid "Disk Setup" +msgstr "" + +#: main.c:620 main.c:630 +msgid "Delete all data" +msgstr "" + +#: main.c:627 +#, c-format +msgid "" +"The installation program will now set up a RAID configuration on the selected harddisks:\n" +"\n" +" %s\n" +" %s\n" +"\n" +"Do you agree to continue?" +msgstr "" + +#: main.c:629 +msgid "RAID Setup" +msgstr "" + +#: main.c:640 +msgid "Your disk configuration is currently not supported." +msgstr "" + +#: main.c:655 +msgid "Your harddisk is too small." +msgstr "" + +#: main.c:671 +msgid "" +"Your harddisk is very small, but you can continue without a swap partition." +msgstr "" + +#: main.c:684 +msgid "ext4 Filesystem" +msgstr "" + +#: main.c:685 +msgid "ext4 Filesystem without journal" +msgstr "" + +#: main.c:686 +msgid "XFS Filesystem" +msgstr "" + +#: main.c:687 +msgid "ReiserFS Filesystem" +msgstr "" + +#: main.c:701 +msgid "Filesystem Selection" +msgstr "" + +#: main.c:701 +msgid "Please choose your filesystem:" +msgstr "" + +#: main.c:712 +msgid "Building RAID..." +msgstr "" + +#: main.c:716 +msgid "Unable to build the RAID." +msgstr "" + +#: main.c:728 +msgid "Partitioning disk..." +msgstr "" + +#: main.c:732 +msgid "Unable to partition the disk." +msgstr "" + +#: main.c:739 +msgid "Creating filesystems..." +msgstr "" + +#: main.c:743 +msgid "Unable to create filesystems." +msgstr "" + +#: main.c:749 +msgid "Unable to mount filesystems." +msgstr "" + +#: main.c:760 +msgid "Installing the system..." +msgstr "" + +#: main.c:761 +msgid "Unable to install the system." +msgstr "" + +#: main.c:777 +msgid "Installing the language cache..." +msgstr "" + +#: main.c:778 +msgid "Unable to install the language cache." +msgstr "" + +#: main.c:783 +msgid "Installing the bootloader..." +msgstr "" + +#: main.c:790 +msgid "Unable to open /etc/default/grub for writing." +msgstr "" + +#: main.c:812 +msgid "Unable to install the bootloader." +msgstr "" + +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 +#, c-format +msgid "" +"%s was successfully installed!\n" +"\n" +"Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." +msgstr "" + +#: main.c:882 +msgid "Congratulations!" +msgstr "" + +#: main.c:882 +msgid "Reboot" +msgstr "" + +#: main.c:893 +msgid "Setup has failed. Press Ok to reboot." +msgstr "" diff --git a/src/installer/po/km_KH.po b/src/installer/po/km_KH.po index 0f7f946..b4e5f89 100644 --- a/src/installer/po/km_KH.po +++ b/src/installer/po/km_KH.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Khmer (Cambodia) (http://www.transifex.com/projects/p/ipfire/language/km_KH/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: km_KH\n" "Plural-Forms: nplurals=1; plural=0;\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/nl.po b/src/installer/po/nl.po index 6e2f7ea..41908ac 100644 --- a/src/installer/po/nl.po +++ b/src/installer/po/nl.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Dutch (http://www.transifex.com/projects/p/ipfire/language/nl/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/pl.po b/src/installer/po/pl.po index cfad680..4abe195 100644 --- a/src/installer/po/pl.po +++ b/src/installer/po/pl.po @@ -3,12 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# btelega btelega@gmail.com, 2014 +# Przemysław Karpeta przemyslaw.karpeta@gmail.com, 2014 msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Polish (http://www.transifex.com/projects/p/ipfire/language/pl/)%5Cn" "MIME-Version: 1.0\n" @@ -17,85 +19,145 @@ msgstr "" "Language: pl\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" -msgstr "" +msgstr "OK"
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" -msgstr "" +msgstr "Anuluj"
-#: main.c:145 +#: main.c:176 msgid "I accept this license" +msgstr "Akceptuje licencje" + +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Language selection" -msgstr "" +msgstr "Wybór języka"
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." +msgstr "Wybierz język jaki chcesz użyć do tej instalacji." + +#: main.c:418 +msgid "Unattended mode" msgstr ""
-#: main.c:323 +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" -msgstr "" +msgstr "<Tab>/<Alt-Tab> przełącza między pozycjami | <Space> wybiera | <F12> następny ekran"
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" "\n" "Selecting Cancel on any of the following screens will reboot the computer." -msgstr "" +msgstr "Witaj w instalatorze %s.\n\nWybranie Cancel na dowolnym z następnych ekranów spowoduje restart komputera."
-#: main.c:330 +#: main.c:428 msgid "Start installation" +msgstr "Rozpoczynam instalację" + +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:460 +msgid "Download installation image" msgstr ""
-#: main.c:376 -msgid "License Agreement" +#: main.c:473 +msgid "Trying to start networking (DHCP)..." msgstr ""
-#: main.c:377 -msgid "License not accepted!" +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." msgstr ""
-#: main.c:399 -msgid "No hard disk found." +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:418 -msgid "Disk Selection" +#: main.c:501 +msgid "Downloading installation image..." +msgstr "" + +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" +msgstr "" + +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" msgstr ""
-#: main.c:419 +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 +msgid "License Agreement" +msgstr "Umowa Licencyjna" + +#: main.c:544 +msgid "License not accepted!" +msgstr "Licencja nie została zaakceptowana !" + +#: main.c:566 +msgid "No hard disk found." +msgstr "Nie znaleziono twardego dysku." + +#: main.c:587 +msgid "Disk Selection" +msgstr "Wybór Dysku" + +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." -msgstr "" +msgstr "Wybierz dysk(dyski), na którym ma zostać zainstalowany IPFire. Wybrane urządzenia zostaną podzielone na partycje, a na tych partycjach zostaną utworzone systemy plików. \n\nWSZYSTKIE ISTNIEJĄCE NA DYSKACH DANE ZOSTANĄ ZNISZCZONE."
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." -msgstr "" +msgstr "Nie wybrano żadnego dysku.\n\nWybierz jeden lub więcej dysków, na których chesz zainstalować IPFire."
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -103,17 +165,17 @@ msgid "" " %s\n" "\n" "Do you agree to continue?" -msgstr "" +msgstr "Instalator przygotuje teraz wybrany dysk twardy:\n\n %s\n\nCzy kontynuować ?"
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" -msgstr "" +msgstr "Konfiguracja Dysku"
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" -msgstr "" +msgstr "Usuń wszystkie dane"
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -122,121 +184,148 @@ msgid "" " %s\n" "\n" "Do you agree to continue?" -msgstr "" +msgstr "Instalator skonfiguruje teraz RAID na wybranych dyskach twardych:\n\n %s\n %s\n\nCzy kontynuować ?"
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" -msgstr "" +msgstr "Konfiguracja RAID"
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." -msgstr "" +msgstr "Twój dysk twardy jest za mały"
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." -msgstr "" +msgstr "Dysk twardy jest bardzo mały, ale można kontynuować bez partycji swap."
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" -msgstr "" +msgstr "ext4 Filesystem"
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" -msgstr "" +msgstr "ext4 Filesystem bez dziennika"
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" -msgstr "" +msgstr "XFS Filesystem"
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" -msgstr "" +msgstr "System plików ReiserFS"
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" -msgstr "" +msgstr "System plików został wybrany"
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" -msgstr "" +msgstr "Wybierz system plików:"
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." -msgstr "" +msgstr "Tworzenie RAID ..."
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." -msgstr "" +msgstr "Nie udało się utworzyć RAID."
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." -msgstr "" +msgstr "Partycjonowanie dysku..."
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." -msgstr "" +msgstr "Partycjonowanie dysku niemożliwe."
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." -msgstr "" +msgstr "Tworzenie systemów plików..."
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." -msgstr "" +msgstr "Nie można utworzyć systemów plików."
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." -msgstr "" +msgstr "Nie można zamontować systemów plików."
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." -msgstr "" +msgstr "Instalowanie systemu..."
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." -msgstr "" +msgstr "Nie można zainstalować systemu."
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." -msgstr "" +msgstr "Instalacja pamięci podręcznej języków."
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." -msgstr "" +msgstr "Nie można zainstalować pamięci podręcznej języków."
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." -msgstr "" +msgstr "Instalacja programu rozruchowego..."
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." -msgstr "" +msgstr "Nie można otworzyć /etc/default/grub do zapisu."
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." +msgstr "Nie mogę zainstalować programu rozruchowego." + +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" msgstr ""
-#: main.c:666 +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" "\n" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." -msgstr "" +msgstr "Instalacja %s zakończyła się sukcesem !\n\nProsze usunąć nośnik instalacyjny z systemu i wcisnąć przycisk restartu. Po restarcie systemu pojawi się prośba o skonfigurowanie sieci i ustawienie haseł systemowych. Następnie należy oworzyć w przeglądarce WWW adres https://%s:444 (lub inną nazwę, ktora została nadana %s), aby uzyskać dostęp do internetowej konsoli konfiguracyjnej."
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" -msgstr "" +msgstr "Gratulacje!"
-#: main.c:671 +#: main.c:882 msgid "Reboot" -msgstr "" +msgstr "Uruchom ponownie"
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." -msgstr "" +msgstr "Konfiguracja nieudana. Wciśnij Ok, aby zrestartować." diff --git a/src/installer/po/pt_BR.po b/src/installer/po/pt_BR.po index 0152ede..dba4b65 100644 --- a/src/installer/po/pt_BR.po +++ b/src/installer/po/pt_BR.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/ipfire/language/pt_BR/)%5Cn" "MIME-Version: 1.0\n" @@ -19,31 +19,40 @@ msgstr "" "Language: pt_BR\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr "Ok"
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr "Cancelar"
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr "Eu aceito esta licença"
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr "<Tab>/<Alt-Tab> entre os elementos | <Space> Selecione | <F12> próxima tela"
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -51,53 +60,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr "Iniciar a instalação"
-#: main.c:339 -msgid "No local source media found. Starting download." -msgstr "Nenhuma fonte de mídia local encontrada. Iniciando download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." -msgstr "Baixando imagem de instalação ..." +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr ""
-#: main.c:342 -msgid "Download error" -msgstr "Erro de download" +#: main.c:487 main.c:516 +msgid "Retry" +msgstr ""
-#: main.c:376 +#: main.c:501 +msgid "Downloading installation image..." +msgstr "" + +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" +msgstr "" + +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr "Licença não aceita!"
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr "Nenhum disco rígido foi encontrado."
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr "Seleção de disco"
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr "Selecione o disco(s) que deseja instalar o IPFire. Primeiramente o mesmo será particionado, e então, as partições terão um sistema de arquivos que você escolher. \n\nTODOS OS DADOS NO DISCO SERÃO DESTRUÍDOS."
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr "Nenhum disco foi selecionado.\n\nPor favor seleccione um ou mais discos que você deseja instalar o IPFire."
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -107,15 +167,15 @@ msgid "" "Do you agree to continue?" msgstr "O programa de instalação irá agora preparar o disco rígido escolhido:\n\n%s \n\nVocê concorda em continuar?"
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr "Configuração de Discos"
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr "Apagar todos os dados"
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -126,104 +186,131 @@ msgid "" "Do you agree to continue?" msgstr "O programa de instalação ira agora definir uma configuração de RAID nos discos rígidos selecionados:\n\n%s\n%s\n \nVocê concorda continuar?"
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr "Configuração de RAID"
-#: main.c:466 -msgid "You disk configuration is currently not supported." -msgstr "Sua configuração de disco não é suportada atualmente." +#: main.c:640 +msgid "Your disk configuration is currently not supported." +msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr "Seu disco rígido é muito pequeno."
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr "Sistema de arquivos ext4"
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr "Sistema de arquivos ext4 sem journal"
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr "Sistema de arquivos XFS"
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr "Sistema de arquivos ReiserFS"
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr "Seleção do sistema de arquivos"
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr "Por favor, escolha o seu sistema de arquivos:"
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr "Construindo o RAID..."
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr "Não foi possível construir o RAID."
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr "Particionando o disco..."
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr "Não foi possível particionar o disco."
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr "Criando o sistema de arquivos..."
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr "Não foi possível criar sistemas de arquivos."
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr "Não foi possível montar sistemas de arquivos."
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr "Instalando o sistema..."
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr "Não é possível instalar o sistema."
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr "Instalando o cache de linguagem..."
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr "Não foi possível instalar o cache de linguagem."
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr "Instalando o gerenciador de inicialização..."
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr "Não foi possível instalar o gerenciador de inicialização."
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -231,14 +318,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr "Parabéns!"
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr "Reiniciar"
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/pt_PT.po b/src/installer/po/pt_PT.po index ee41d97..5b70188 100644 --- a/src/installer/po/pt_PT.po +++ b/src/installer/po/pt_PT.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/ipfire/language/pt_PT/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: pt_PT\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/ro_RO.po b/src/installer/po/ro_RO.po index 7fc70c8..6601c0b 100644 --- a/src/installer/po/ro_RO.po +++ b/src/installer/po/ro_RO.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Romanian (Romania) (http://www.transifex.com/projects/p/ipfire/language/ro_RO/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: ro_RO\n" "Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/ru.po b/src/installer/po/ru.po index e3e0a8b..7905236 100644 --- a/src/installer/po/ru.po +++ b/src/installer/po/ru.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Russian (http://www.transifex.com/projects/p/ipfire/language/ru/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: ru\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/rw.po b/src/installer/po/rw.po new file mode 100644 index 0000000..e099182 --- /dev/null +++ b/src/installer/po/rw.po @@ -0,0 +1,329 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR The IPFire Project (www.ipfire.org) +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: IPFire Project\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" +"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"Language-Team: Kinyarwanda (http://www.transifex.com/projects/p/ipfire/language/rw/)%5Cn" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: rw\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 +msgid "OK" +msgstr "" + +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 +msgid "Cancel" +msgstr "" + +#: main.c:176 +msgid "I accept this license" +msgstr "" + +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 +msgid "Language selection" +msgstr "" + +#: main.c:403 +msgid "Select the language you wish to use for the installation." +msgstr "" + +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 +msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" +msgstr "" + +#: main.c:426 +#, c-format +msgid "" +"Welcome to the %s installation program.\n" +"\n" +"Selecting Cancel on any of the following screens will reboot the computer." +msgstr "" + +#: main.c:428 +msgid "Start installation" +msgstr "" + +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" +msgstr "" + +#: main.c:501 +msgid "Downloading installation image..." +msgstr "" + +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" +msgstr "" + +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 +msgid "License Agreement" +msgstr "" + +#: main.c:544 +msgid "License not accepted!" +msgstr "" + +#: main.c:566 +msgid "No hard disk found." +msgstr "" + +#: main.c:587 +msgid "Disk Selection" +msgstr "" + +#: main.c:588 +msgid "" +"Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" +"\n" +"ALL DATA ON THE DISK WILL BE DESTROYED." +msgstr "" + +#: main.c:599 +msgid "" +"No disk has been selected.\n" +"\n" +"Please select one or more disks you want to install IPFire on." +msgstr "" + +#: main.c:617 +#, c-format +msgid "" +"The installation program will now prepare the chosen harddisk:\n" +"\n" +" %s\n" +"\n" +"Do you agree to continue?" +msgstr "" + +#: main.c:619 +msgid "Disk Setup" +msgstr "" + +#: main.c:620 main.c:630 +msgid "Delete all data" +msgstr "" + +#: main.c:627 +#, c-format +msgid "" +"The installation program will now set up a RAID configuration on the selected harddisks:\n" +"\n" +" %s\n" +" %s\n" +"\n" +"Do you agree to continue?" +msgstr "" + +#: main.c:629 +msgid "RAID Setup" +msgstr "" + +#: main.c:640 +msgid "Your disk configuration is currently not supported." +msgstr "" + +#: main.c:655 +msgid "Your harddisk is too small." +msgstr "" + +#: main.c:671 +msgid "" +"Your harddisk is very small, but you can continue without a swap partition." +msgstr "" + +#: main.c:684 +msgid "ext4 Filesystem" +msgstr "" + +#: main.c:685 +msgid "ext4 Filesystem without journal" +msgstr "" + +#: main.c:686 +msgid "XFS Filesystem" +msgstr "" + +#: main.c:687 +msgid "ReiserFS Filesystem" +msgstr "" + +#: main.c:701 +msgid "Filesystem Selection" +msgstr "" + +#: main.c:701 +msgid "Please choose your filesystem:" +msgstr "" + +#: main.c:712 +msgid "Building RAID..." +msgstr "" + +#: main.c:716 +msgid "Unable to build the RAID." +msgstr "" + +#: main.c:728 +msgid "Partitioning disk..." +msgstr "" + +#: main.c:732 +msgid "Unable to partition the disk." +msgstr "" + +#: main.c:739 +msgid "Creating filesystems..." +msgstr "" + +#: main.c:743 +msgid "Unable to create filesystems." +msgstr "" + +#: main.c:749 +msgid "Unable to mount filesystems." +msgstr "" + +#: main.c:760 +msgid "Installing the system..." +msgstr "" + +#: main.c:761 +msgid "Unable to install the system." +msgstr "" + +#: main.c:777 +msgid "Installing the language cache..." +msgstr "" + +#: main.c:778 +msgid "Unable to install the language cache." +msgstr "" + +#: main.c:783 +msgid "Installing the bootloader..." +msgstr "" + +#: main.c:790 +msgid "Unable to open /etc/default/grub for writing." +msgstr "" + +#: main.c:812 +msgid "Unable to install the bootloader." +msgstr "" + +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 +#, c-format +msgid "" +"%s was successfully installed!\n" +"\n" +"Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." +msgstr "" + +#: main.c:882 +msgid "Congratulations!" +msgstr "" + +#: main.c:882 +msgid "Reboot" +msgstr "" + +#: main.c:893 +msgid "Setup has failed. Press Ok to reboot." +msgstr "" diff --git a/src/installer/po/sk.po b/src/installer/po/sk.po index 86d37cd..3766bae 100644 --- a/src/installer/po/sk.po +++ b/src/installer/po/sk.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Slovak (http://www.transifex.com/projects/p/ipfire/language/sk/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: sk\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/sq.po b/src/installer/po/sq.po index 8ac31c1..af653fd 100644 --- a/src/installer/po/sq.po +++ b/src/installer/po/sq.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Albanian (http://www.transifex.com/projects/p/ipfire/language/sq/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: sq\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/sr.po b/src/installer/po/sr.po new file mode 100644 index 0000000..97fad59 --- /dev/null +++ b/src/installer/po/sr.po @@ -0,0 +1,329 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR The IPFire Project (www.ipfire.org) +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: IPFire Project\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-07-31 09:39+0000\n" +"Last-Translator: FULL NAME EMAIL@ADDRESS\n" +"Language-Team: Serbian (http://www.transifex.com/projects/p/ipfire/language/sr/)%5Cn" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sr\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 +msgid "OK" +msgstr "" + +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 +msgid "Cancel" +msgstr "" + +#: main.c:176 +msgid "I accept this license" +msgstr "" + +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 +msgid "Language selection" +msgstr "" + +#: main.c:403 +msgid "Select the language you wish to use for the installation." +msgstr "" + +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 +msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" +msgstr "" + +#: main.c:426 +#, c-format +msgid "" +"Welcome to the %s installation program.\n" +"\n" +"Selecting Cancel on any of the following screens will reboot the computer." +msgstr "" + +#: main.c:428 +msgid "Start installation" +msgstr "" + +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" +msgstr "" + +#: main.c:501 +msgid "Downloading installation image..." +msgstr "" + +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" +msgstr "" + +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 +msgid "License Agreement" +msgstr "" + +#: main.c:544 +msgid "License not accepted!" +msgstr "" + +#: main.c:566 +msgid "No hard disk found." +msgstr "" + +#: main.c:587 +msgid "Disk Selection" +msgstr "" + +#: main.c:588 +msgid "" +"Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" +"\n" +"ALL DATA ON THE DISK WILL BE DESTROYED." +msgstr "" + +#: main.c:599 +msgid "" +"No disk has been selected.\n" +"\n" +"Please select one or more disks you want to install IPFire on." +msgstr "" + +#: main.c:617 +#, c-format +msgid "" +"The installation program will now prepare the chosen harddisk:\n" +"\n" +" %s\n" +"\n" +"Do you agree to continue?" +msgstr "" + +#: main.c:619 +msgid "Disk Setup" +msgstr "" + +#: main.c:620 main.c:630 +msgid "Delete all data" +msgstr "" + +#: main.c:627 +#, c-format +msgid "" +"The installation program will now set up a RAID configuration on the selected harddisks:\n" +"\n" +" %s\n" +" %s\n" +"\n" +"Do you agree to continue?" +msgstr "" + +#: main.c:629 +msgid "RAID Setup" +msgstr "" + +#: main.c:640 +msgid "Your disk configuration is currently not supported." +msgstr "" + +#: main.c:655 +msgid "Your harddisk is too small." +msgstr "" + +#: main.c:671 +msgid "" +"Your harddisk is very small, but you can continue without a swap partition." +msgstr "" + +#: main.c:684 +msgid "ext4 Filesystem" +msgstr "" + +#: main.c:685 +msgid "ext4 Filesystem without journal" +msgstr "" + +#: main.c:686 +msgid "XFS Filesystem" +msgstr "" + +#: main.c:687 +msgid "ReiserFS Filesystem" +msgstr "" + +#: main.c:701 +msgid "Filesystem Selection" +msgstr "" + +#: main.c:701 +msgid "Please choose your filesystem:" +msgstr "" + +#: main.c:712 +msgid "Building RAID..." +msgstr "" + +#: main.c:716 +msgid "Unable to build the RAID." +msgstr "" + +#: main.c:728 +msgid "Partitioning disk..." +msgstr "" + +#: main.c:732 +msgid "Unable to partition the disk." +msgstr "" + +#: main.c:739 +msgid "Creating filesystems..." +msgstr "" + +#: main.c:743 +msgid "Unable to create filesystems." +msgstr "" + +#: main.c:749 +msgid "Unable to mount filesystems." +msgstr "" + +#: main.c:760 +msgid "Installing the system..." +msgstr "" + +#: main.c:761 +msgid "Unable to install the system." +msgstr "" + +#: main.c:777 +msgid "Installing the language cache..." +msgstr "" + +#: main.c:778 +msgid "Unable to install the language cache." +msgstr "" + +#: main.c:783 +msgid "Installing the bootloader..." +msgstr "" + +#: main.c:790 +msgid "Unable to open /etc/default/grub for writing." +msgstr "" + +#: main.c:812 +msgid "Unable to install the bootloader." +msgstr "" + +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 +#, c-format +msgid "" +"%s was successfully installed!\n" +"\n" +"Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." +msgstr "" + +#: main.c:882 +msgid "Congratulations!" +msgstr "" + +#: main.c:882 +msgid "Reboot" +msgstr "" + +#: main.c:893 +msgid "Setup has failed. Press Ok to reboot." +msgstr "" diff --git a/src/installer/po/sv.po b/src/installer/po/sv.po index 25e0ad4..b0e5ae7 100644 --- a/src/installer/po/sv.po +++ b/src/installer/po/sv.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Swedish (http://www.transifex.com/projects/p/ipfire/language/sv/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: sv\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/th.po b/src/installer/po/th.po index 2a88dca..97842e8 100644 --- a/src/installer/po/th.po +++ b/src/installer/po/th.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Thai (http://www.transifex.com/projects/p/ipfire/language/th/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: th\n" "Plural-Forms: nplurals=1; plural=0;\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/tk.po b/src/installer/po/tk.po index e07df58..c753b72 100644 --- a/src/installer/po/tk.po +++ b/src/installer/po/tk.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Turkmen (http://www.transifex.com/projects/p/ipfire/language/tk/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: tk\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/tr.po b/src/installer/po/tr.po index 99a100a..0198445 100644 --- a/src/installer/po/tr.po +++ b/src/installer/po/tr.po @@ -3,13 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Kudret Emre kudretemre@hotmail.com.tr, 2014 +# Kudret Emre kudretemre@hotmail.com.tr, 2014 msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" -"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-12-08 17:24+0000\n" +"Last-Translator: Kudret Emre kudretemre@hotmail.com.tr\n" "Language-Team: Turkish (http://www.transifex.com/projects/p/ipfire/language/tr/)%5Cn" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -17,85 +19,145 @@ msgstr "" "Language: tr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" -msgstr "" +msgstr "Tamam"
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" -msgstr "" +msgstr "İptal"
-#: main.c:145 +#: main.c:176 msgid "I accept this license" -msgstr "" +msgstr "Lisansı kabul ediyorum"
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "Uyarı: Katılımsız kurulum 10 saniye içinde başlayacak..." + +#: main.c:403 msgid "Language selection" -msgstr "" +msgstr "Dil seçimi"
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." -msgstr "" +msgstr "Yükleme için istediğiniz dili seçin."
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "Katılımsız kurulum modu" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" -msgstr "" +msgstr "<Tab>/<Alt-Tab> elementler arası geçiş | <Space> seç | <F12> sonraki ekran"
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" "\n" "Selecting Cancel on any of the following screens will reboot the computer." -msgstr "" +msgstr "%s yükleme programına hoşgeldiniz.\n\nİlerleyen ekranların herhangi birinde İptal'e tıklamanız bilgisayarınızı yeniden başlatır."
-#: main.c:330 +#: main.c:428 msgid "Start installation" -msgstr "" +msgstr "Yüklemeyi başlat"
-#: main.c:339 -msgid "No local source media found. Starting download." -msgstr "" +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "Yükleyici şimdi yükleme dosyasını indirmeyi deneyecek." + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "Hiçbir kaynak sürücüsü bulunamadı.\n\nGerekli yükleme dosyasını indirmeyi deneyebilirsiniz."
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:460 +msgid "Download installation image" +msgstr "Yükleme dosyasını indir" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "Ağa bağlanmaya çalışılıyor (DHCP)..." + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "Yüklemenin devam etmesi için ağ bağlantısı gereklidir fakat başlatılamıyor.\n\nLütfen makinenizi bir DHCP sunucu ile ağa bağlayıp tekrar deneyin." + +#: main.c:487 main.c:516 +msgid "Retry" +msgstr "Tekrar dene" + +#: main.c:501 +msgid "Downloading installation image..." +msgstr "Yükleme dosyası indiriliyor..." + +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" +msgstr "MD5 checksum uyuşmuyor" + +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "Yükleme dosyası indirilemedi.\nSebep: %s\n\n%s" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" msgstr ""
-#: main.c:376 +#: main.c:543 msgid "License Agreement" -msgstr "" +msgstr "Lisans Anlaşması"
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" -msgstr "" +msgstr "Lisans kabul edilmedi!"
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." -msgstr "" +msgstr "Sabit disk bulunamadı."
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" -msgstr "" +msgstr "Disk Seçimi"
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." -msgstr "" +msgstr "IPFire'ı yüklemek istediğiniz disk(ler)i seçin. Diskler önce bölümlenecek, sonra bölümlere dosya sistemi oluşturulacaktır.\n\nDİSKTEKİ TÜM VERİLER SİLİNECEKTİR."
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." -msgstr "" +msgstr "Hiçbir disk seçilmedi.\n\nLütfen IPFire'ı yüklemek için bir veya daha fazla disk seçin."
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -103,17 +165,17 @@ msgid "" " %s\n" "\n" "Do you agree to continue?" -msgstr "" +msgstr "Yükleme programı şimdi seçilen diski hazırlayacak:\n\n%s\n\nDevam etmek istiyor musunuz?"
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" -msgstr "" +msgstr "Disk Kurulumu"
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" -msgstr "" +msgstr "Tüm veriyi sil"
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -122,121 +184,148 @@ msgid "" " %s\n" "\n" "Do you agree to continue?" -msgstr "" +msgstr "Yükleme programı şimdi seçilen sabit disk üzerinde bir RAID yapılandırması kuracak:\n\n%s\n%s\n\nDevam etmek istiyor musunuz?"
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" -msgstr "" +msgstr "RAID Kurulumu"
-#: main.c:466 -msgid "You disk configuration is currently not supported." -msgstr "" +#: main.c:640 +msgid "Your disk configuration is currently not supported." +msgstr "Disk yapılandırmanız desteklenmiyor."
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." -msgstr "" +msgstr "Sabit diskiniz çok küçük."
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." -msgstr "" +msgstr "Sabit diskiniz çok küçük, fakat takas bölümü olmadan devam edebilirsiniz."
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" -msgstr "" +msgstr "ext4 Dosya sistemi"
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" -msgstr "" +msgstr "ext4 Dosya sistemi - günlüksüz"
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" -msgstr "" +msgstr "XFS Dosya sistemi"
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" -msgstr "" +msgstr "ReiserFS Dosya sistemi"
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" -msgstr "" +msgstr "Dosya sistemi Seçimi"
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" -msgstr "" +msgstr "Lütfen dosya sisteminizi seçin:"
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." -msgstr "" +msgstr "RAID oluşturuluyor..."
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." -msgstr "" +msgstr "RAID oluşturulamıyor."
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." -msgstr "" +msgstr "Disk bölümleniyor..."
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." -msgstr "" +msgstr "Disk bölümlendirilemiyor."
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." -msgstr "" +msgstr "Dosya sistemleri oluşturuluyor..."
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." -msgstr "" +msgstr "Dosya sistemleri oluşturulamıyor."
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." -msgstr "" +msgstr "Dosya sistemleri bağlanamıyor."
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." -msgstr "" +msgstr "Sistem yükleniyor..."
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." -msgstr "" +msgstr "Sistem yüklenemiyor."
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." -msgstr "" +msgstr "Dil ön blleği yükleniyor..."
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." -msgstr "" +msgstr "Dil ön belleği yüklenemiyor."
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." -msgstr "" +msgstr "bootloader yükleniyor..."
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." -msgstr "" +msgstr "/etc/default/grub yazma işlemi için açılamıyor."
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." -msgstr "" +msgstr "bootloader yüklenemiyor." + +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "Yükleme dosyasında bir yedekleme dosyası bulundu.\n\nYedeği geri yüklemek ister misiniz?" + +#: main.c:827 +msgid "Yes" +msgstr "Evet"
-#: main.c:666 +#: main.c:827 +msgid "No" +msgstr "Hayır" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "Yedek dosyası geri yüklenirken bir hata oluştu." + +#: main.c:869 +msgid "Running post-install script..." +msgstr "post-install betiği çalıştırılıyor..." + +#: main.c:870 +msgid "Post-install script failed." +msgstr "post-install betiği başarısız oldu." + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" "\n" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." -msgstr "" +msgstr "%s başarıyla yüklendi!\n\nLütfen yükleme ortamlarını bu sistemden çıkarın ve yeniden başlatma butonuna tıklayın. Sistem yeniden başlatıldığında ağ ve sistem şifrenizi ayarlamanız istenecek. Daha sonra web yapılandırma konsoluna gitmek için yarayıcınızdan https://%s:444 (veya %s yerine ne isim verdiyseniz) adresine gidin."
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" -msgstr "" +msgstr "Tebrikler!"
-#: main.c:671 +#: main.c:882 msgid "Reboot" -msgstr "" +msgstr "Yeniden başlat."
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." -msgstr "" +msgstr "Kurulum başarısız oldu. Yeniden başlatmak için Tamam'a basın." diff --git a/src/installer/po/uk.po b/src/installer/po/uk.po index e6c955a..4a2ab67 100644 --- a/src/installer/po/uk.po +++ b/src/installer/po/uk.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Ukrainian (http://www.transifex.com/projects/p/ipfire/language/uk/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: uk\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/uz@Latn.po b/src/installer/po/uz@Latn.po index 2bdb551..8c68800 100644 --- a/src/installer/po/uz@Latn.po +++ b/src/installer/po/uz@Latn.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Uzbek (Latin) (http://www.transifex.com/projects/p/ipfire/language/uz@Latn/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: uz@Latn\n" "Plural-Forms: nplurals=1; plural=0;\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/vi.po b/src/installer/po/vi.po index 197382b..4f5b455 100644 --- a/src/installer/po/vi.po +++ b/src/installer/po/vi.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Vietnamese (http://www.transifex.com/projects/p/ipfire/language/vi/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: vi\n" "Plural-Forms: nplurals=1; plural=0;\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/installer/po/zh.po b/src/installer/po/zh.po index 3148f14..3dbca13 100644 --- a/src/installer/po/zh.po +++ b/src/installer/po/zh.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-08-21 15:09+0000\n" -"PO-Revision-Date: 2014-08-21 15:11+0000\n" +"POT-Creation-Date: 2014-11-05 01:29+0000\n" +"PO-Revision-Date: 2014-11-05 01:33+0000\n" "Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" "Language-Team: Chinese (http://www.transifex.com/projects/p/ipfire/language/zh/)%5Cn" "MIME-Version: 1.0\n" @@ -17,31 +17,40 @@ msgstr "" "Language: zh\n" "Plural-Forms: nplurals=1; plural=0;\n"
-#: main.c:77 main.c:148 main.c:313 main.c:339 main.c:493 main.c:524 main.c:682 +#: main.c:78 main.c:179 main.c:404 main.c:670 main.c:702 main.c:893 msgid "OK" msgstr ""
-#: main.c:78 main.c:446 main.c:456 main.c:493 main.c:524 +#: main.c:79 main.c:460 main.c:487 main.c:516 main.c:620 main.c:630 main.c:670 +#: main.c:702 msgid "Cancel" msgstr ""
-#: main.c:145 +#: main.c:176 msgid "I accept this license" msgstr ""
-#: main.c:312 +#: main.c:384 +msgid "Warning: Unattended installation will start in 10 seconds..." +msgstr "" + +#: main.c:403 msgid "Language selection" msgstr ""
-#: main.c:312 +#: main.c:403 msgid "Select the language you wish to use for the installation." msgstr ""
-#: main.c:323 +#: main.c:418 +msgid "Unattended mode" +msgstr "" + +#: main.c:420 msgid "<Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen" msgstr ""
-#: main.c:328 +#: main.c:426 #, c-format msgid "" "Welcome to the %s installation program.\n" @@ -49,53 +58,104 @@ msgid "" "Selecting Cancel on any of the following screens will reboot the computer." msgstr ""
-#: main.c:330 +#: main.c:428 msgid "Start installation" msgstr ""
-#: main.c:339 -msgid "No local source media found. Starting download." +#: main.c:449 +#, c-format +msgid "The installer will now try downloading the installation image." +msgstr "" + +#: main.c:452 +#, c-format +msgid "" +"No source drive could be found.\n" +"\n" +"You can try downloading the required installation image." +msgstr "" + +#: main.c:456 +msgid "" +"Please make sure to connect your machine to a network and the installer will" +" try connect to acquire an IP address." +msgstr "" + +#: main.c:460 +msgid "Download installation image" +msgstr "" + +#: main.c:473 +msgid "Trying to start networking (DHCP)..." +msgstr "" + +#: main.c:484 +msgid "" +"Networking could not be started but is required to go on with the installation.\n" +"\n" +"Please connect your machine to a network with a DHCP server and retry." +msgstr "" + +#: main.c:487 main.c:516 +msgid "Retry" msgstr ""
-#: main.c:340 -msgid "Downloading installation image ..." +#: main.c:501 +msgid "Downloading installation image..." msgstr ""
-#: main.c:342 -msgid "Download error" +#: main.c:510 +#, c-format +msgid "MD5 checksum mismatch" msgstr ""
-#: main.c:376 +#: main.c:513 +#, c-format +msgid "" +"The installation image could not be downloaded.\n" +" Reason: %s\n" +"\n" +"%s" +msgstr "" + +#: main.c:528 +#, c-format +msgid "" +"Could not mount %s to %s:\n" +" %s\n" +msgstr "" + +#: main.c:543 msgid "License Agreement" msgstr ""
-#: main.c:377 +#: main.c:544 msgid "License not accepted!" msgstr ""
-#: main.c:399 +#: main.c:566 msgid "No hard disk found." msgstr ""
-#: main.c:418 +#: main.c:587 msgid "Disk Selection" msgstr ""
-#: main.c:419 +#: main.c:588 msgid "" "Select the disk(s) you want to install IPFire on. First those will be partitioned, and then the partitions will have a filesystem put on them.\n" "\n" "ALL DATA ON THE DISK WILL BE DESTROYED." msgstr ""
-#: main.c:430 +#: main.c:599 msgid "" "No disk has been selected.\n" "\n" "Please select one or more disks you want to install IPFire on." msgstr ""
-#: main.c:443 +#: main.c:617 #, c-format msgid "" "The installation program will now prepare the chosen harddisk:\n" @@ -105,15 +165,15 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:445 +#: main.c:619 msgid "Disk Setup" msgstr ""
-#: main.c:446 main.c:456 +#: main.c:620 main.c:630 msgid "Delete all data" msgstr ""
-#: main.c:453 +#: main.c:627 #, c-format msgid "" "The installation program will now set up a RAID configuration on the selected harddisks:\n" @@ -124,104 +184,131 @@ msgid "" "Do you agree to continue?" msgstr ""
-#: main.c:455 +#: main.c:629 msgid "RAID Setup" msgstr ""
-#: main.c:466 -msgid "You disk configuration is currently not supported." +#: main.c:640 +msgid "Your disk configuration is currently not supported." msgstr ""
-#: main.c:480 +#: main.c:655 msgid "Your harddisk is too small." msgstr ""
-#: main.c:494 +#: main.c:671 msgid "" "Your harddisk is very small, but you can continue without a swap partition." msgstr ""
-#: main.c:506 +#: main.c:684 msgid "ext4 Filesystem" msgstr ""
-#: main.c:507 +#: main.c:685 msgid "ext4 Filesystem without journal" msgstr ""
-#: main.c:508 +#: main.c:686 msgid "XFS Filesystem" msgstr ""
-#: main.c:509 +#: main.c:687 msgid "ReiserFS Filesystem" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Filesystem Selection" msgstr ""
-#: main.c:523 +#: main.c:701 msgid "Please choose your filesystem:" msgstr ""
-#: main.c:534 +#: main.c:712 msgid "Building RAID..." msgstr ""
-#: main.c:538 +#: main.c:716 msgid "Unable to build the RAID." msgstr ""
-#: main.c:550 +#: main.c:728 msgid "Partitioning disk..." msgstr ""
-#: main.c:554 +#: main.c:732 msgid "Unable to partition the disk." msgstr ""
-#: main.c:561 +#: main.c:739 msgid "Creating filesystems..." msgstr ""
-#: main.c:565 +#: main.c:743 msgid "Unable to create filesystems." msgstr ""
-#: main.c:571 +#: main.c:749 msgid "Unable to mount filesystems." msgstr ""
-#: main.c:582 +#: main.c:760 msgid "Installing the system..." msgstr ""
-#: main.c:583 +#: main.c:761 msgid "Unable to install the system." msgstr ""
-#: main.c:599 +#: main.c:777 msgid "Installing the language cache..." msgstr ""
-#: main.c:600 +#: main.c:778 msgid "Unable to install the language cache." msgstr ""
-#: main.c:605 +#: main.c:783 msgid "Installing the bootloader..." msgstr ""
-#: main.c:612 +#: main.c:790 msgid "Unable to open /etc/default/grub for writing." msgstr ""
-#: main.c:634 +#: main.c:812 msgid "Unable to install the bootloader." msgstr ""
-#: main.c:666 +#: main.c:826 +msgid "" +"A backup file has been found on the installation image.\n" +"\n" +"Do you want to restore the backup?" +msgstr "" + +#: main.c:827 +msgid "Yes" +msgstr "" + +#: main.c:827 +msgid "No" +msgstr "" + +#: main.c:834 +msgid "An error occured when the backup file was restored." +msgstr "" + +#: main.c:869 +msgid "Running post-install script..." +msgstr "" + +#: main.c:870 +msgid "Post-install script failed." +msgstr "" + +#: main.c:877 #, c-format msgid "" "%s was successfully installed!\n" @@ -229,14 +316,14 @@ msgid "" "Please remove any installation mediums from this system and hit the reboot button. Once the system has restarted you will be asked to setup networking and system passwords. After that, you should point your web browser at https://%s:444 (or what ever you name your %s) for the web configuration console." msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Congratulations!" msgstr ""
-#: main.c:671 +#: main.c:882 msgid "Reboot" msgstr ""
-#: main.c:682 +#: main.c:893 msgid "Setup has failed. Press Ok to reboot." msgstr "" diff --git a/src/patches/backports-3.18.1-1-add_usbnet_modules.patch b/src/patches/backports-3.18.1-1-add_usbnet_modules.patch new file mode 100644 index 0000000..11b9638 --- /dev/null +++ b/src/patches/backports-3.18.1-1-add_usbnet_modules.patch @@ -0,0 +1,29383 @@ +diff -Naur backports-3.18.1-1.org/drivers/net/usb/asix_common.c backports-3.18.1-1/drivers/net/usb/asix_common.c +--- backports-3.18.1-1.org/drivers/net/usb/asix_common.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/asix_common.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,582 @@ ++/* ++ * ASIX AX8817X based USB 2.0 Ethernet Devices ++ * Copyright (C) 2003-2006 David Hollis dhollis@davehollis.com ++ * Copyright (C) 2005 Phil Chang pchang23@sbcglobal.net ++ * Copyright (C) 2006 James Painter jamie.painter@iname.com ++ * Copyright (c) 2002-2003 TiVo Inc. ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include "asix.h" ++ ++int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data) ++{ ++ int ret; ++ ret = usbnet_read_cmd(dev, cmd, ++ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ value, index, data, size); ++ ++ if (ret != size && ret >= 0) ++ return -EINVAL; ++ return ret; ++} ++ ++int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data) ++{ ++ return usbnet_write_cmd(dev, cmd, ++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ value, index, data, size); ++} ++ ++void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data) ++{ ++ usbnet_write_cmd_async(dev, cmd, ++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ value, index, data, size); ++} ++ ++int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb, ++ struct asix_rx_fixup_info *rx) ++{ ++ int offset = 0; ++ ++ while (offset + sizeof(u16) <= skb->len) { ++ u16 remaining = 0; ++ unsigned char *data; ++ ++ if (!rx->size) { ++ if ((skb->len - offset == sizeof(u16)) || ++ rx->split_head) { ++ if(!rx->split_head) { ++ rx->header = get_unaligned_le16( ++ skb->data + offset); ++ rx->split_head = true; ++ offset += sizeof(u16); ++ break; ++ } else { ++ rx->header |= (get_unaligned_le16( ++ skb->data + offset) ++ << 16); ++ rx->split_head = false; ++ offset += sizeof(u16); ++ } ++ } else { ++ rx->header = get_unaligned_le32(skb->data + ++ offset); ++ offset += sizeof(u32); ++ } ++ ++ /* get the packet length */ ++ rx->size = (u16) (rx->header & 0x7ff); ++ if (rx->size != ((~rx->header >> 16) & 0x7ff)) { ++ netdev_err(dev->net, "asix_rx_fixup() Bad Header Length 0x%x, offset %d\n", ++ rx->header, offset); ++ rx->size = 0; ++ return 0; ++ } ++ rx->ax_skb = netdev_alloc_skb_ip_align(dev->net, ++ rx->size); ++ if (!rx->ax_skb) ++ return 0; ++ } ++ ++ if (rx->size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) { ++ netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", ++ rx->size); ++ kfree_skb(rx->ax_skb); ++ rx->ax_skb = NULL; ++ rx->size = 0U; ++ ++ return 0; ++ } ++ ++ if (rx->size > skb->len - offset) { ++ remaining = rx->size - (skb->len - offset); ++ rx->size = skb->len - offset; ++ } ++ ++ data = skb_put(rx->ax_skb, rx->size); ++ memcpy(data, skb->data + offset, rx->size); ++ if (!remaining) ++ usbnet_skb_return(dev, rx->ax_skb); ++ ++ offset += (rx->size + 1) & 0xfffe; ++ rx->size = remaining; ++ } ++ ++ if (skb->len != offset) { ++ netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d, %d\n", ++ skb->len, offset); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++int asix_rx_fixup_common(struct usbnet *dev, struct sk_buff *skb) ++{ ++ struct asix_common_private *dp = dev->driver_priv; ++ struct asix_rx_fixup_info *rx = &dp->rx_fixup_info; ++ ++ return asix_rx_fixup_internal(dev, skb, rx); ++} ++ ++struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, ++ gfp_t flags) ++{ ++ int padlen; ++ int headroom = skb_headroom(skb); ++ int tailroom = skb_tailroom(skb); ++ u32 packet_len; ++ u32 padbytes = 0xffff0000; ++ ++ padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4; ++ ++ /* We need to push 4 bytes in front of frame (packet_len) ++ * and maybe add 4 bytes after the end (if padlen is 4) ++ * ++ * Avoid skb_copy_expand() expensive call, using following rules : ++ * - We are allowed to push 4 bytes in headroom if skb_header_cloned() ++ * is false (and if we have 4 bytes of headroom) ++ * - We are allowed to put 4 bytes at tail if skb_cloned() ++ * is false (and if we have 4 bytes of tailroom) ++ * ++ * TCP packets for example are cloned, but skb_header_release() ++ * was called in tcp stack, allowing us to use headroom for our needs. ++ */ ++ if (!skb_header_cloned(skb) && ++ !(padlen && skb_cloned(skb)) && ++ headroom + tailroom >= 4 + padlen) { ++ /* following should not happen, but better be safe */ ++ if (headroom < 4 || ++ tailroom < padlen) { ++ skb->data = memmove(skb->head + 4, skb->data, skb->len); ++ skb_set_tail_pointer(skb, skb->len); ++ } ++ } else { ++ struct sk_buff *skb2; ++ ++ skb2 = skb_copy_expand(skb, 4, padlen, flags); ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ if (!skb) ++ return NULL; ++ } ++ ++ packet_len = ((skb->len ^ 0x0000ffff) << 16) + skb->len; ++ skb_push(skb, 4); ++ cpu_to_le32s(&packet_len); ++ skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); ++ ++ if (padlen) { ++ cpu_to_le32s(&padbytes); ++ memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); ++ skb_put(skb, sizeof(padbytes)); ++ } ++ return skb; ++} ++ ++int asix_set_sw_mii(struct usbnet *dev) ++{ ++ int ret; ++ ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, "Failed to enable software MII access\n"); ++ return ret; ++} ++ ++int asix_set_hw_mii(struct usbnet *dev) ++{ ++ int ret; ++ ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, "Failed to enable hardware MII access\n"); ++ return ret; ++} ++ ++int asix_read_phy_addr(struct usbnet *dev, int internal) ++{ ++ int offset = (internal ? 1 : 0); ++ u8 buf[2]; ++ int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf); ++ ++ netdev_dbg(dev->net, "asix_get_phy_addr()\n"); ++ ++ if (ret < 0) { ++ netdev_err(dev->net, "Error reading PHYID register: %02x\n", ret); ++ goto out; ++ } ++ netdev_dbg(dev->net, "asix_get_phy_addr() returning 0x%04x\n", ++ *((__le16 *)buf)); ++ ret = buf[offset]; ++ ++out: ++ return ret; ++} ++ ++int asix_get_phy_addr(struct usbnet *dev) ++{ ++ /* return the address of the internal phy */ ++ return asix_read_phy_addr(dev, 1); ++} ++ ++ ++int asix_sw_reset(struct usbnet *dev, u8 flags) ++{ ++ int ret; ++ ++ ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, "Failed to send software reset: %02x\n", ret); ++ ++ return ret; ++} ++ ++u16 asix_read_rx_ctl(struct usbnet *dev) ++{ ++ __le16 v; ++ int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v); ++ ++ if (ret < 0) { ++ netdev_err(dev->net, "Error reading RX_CTL register: %02x\n", ret); ++ goto out; ++ } ++ ret = le16_to_cpu(v); ++out: ++ return ret; ++} ++ ++int asix_write_rx_ctl(struct usbnet *dev, u16 mode) ++{ ++ int ret; ++ ++ netdev_dbg(dev->net, "asix_write_rx_ctl() - mode = 0x%04x\n", mode); ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, "Failed to write RX_CTL mode to 0x%04x: %02x\n", ++ mode, ret); ++ ++ return ret; ++} ++ ++u16 asix_read_medium_status(struct usbnet *dev) ++{ ++ __le16 v; ++ int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); ++ ++ if (ret < 0) { ++ netdev_err(dev->net, "Error reading Medium Status register: %02x\n", ++ ret); ++ return ret; /* TODO: callers not checking for error ret */ ++ } ++ ++ return le16_to_cpu(v); ++ ++} ++ ++int asix_write_medium_mode(struct usbnet *dev, u16 mode) ++{ ++ int ret; ++ ++ netdev_dbg(dev->net, "asix_write_medium_mode() - mode = 0x%04x\n", mode); ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, "Failed to write Medium Mode mode to 0x%04x: %02x\n", ++ mode, ret); ++ ++ return ret; ++} ++ ++int asix_write_gpio(struct usbnet *dev, u16 value, int sleep) ++{ ++ int ret; ++ ++ netdev_dbg(dev->net, "asix_write_gpio() - value = 0x%04x\n", value); ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, "Failed to write GPIO value 0x%04x: %02x\n", ++ value, ret); ++ ++ if (sleep) ++ msleep(sleep); ++ ++ return ret; ++} ++ ++/* ++ * AX88772 & AX88178 have a 16-bit RX_CTL value ++ */ ++void asix_set_multicast(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct asix_data *data = (struct asix_data *)&dev->data; ++ u16 rx_ctl = AX_DEFAULT_RX_CTL; ++ ++ if (net->flags & IFF_PROMISC) { ++ rx_ctl |= AX_RX_CTL_PRO; ++ } else if (net->flags & IFF_ALLMULTI || ++ netdev_mc_count(net) > AX_MAX_MCAST) { ++ rx_ctl |= AX_RX_CTL_AMALL; ++ } else if (netdev_mc_empty(net)) { ++ /* just broadcast and directed */ ++ } else { ++ /* We use the 20 byte dev->data ++ * for our 8 byte filter buffer ++ * to avoid allocating memory that ++ * is tricky to free later */ ++ struct netdev_hw_addr *ha; ++ u32 crc_bits; ++ ++ memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); ++ ++ /* Build the multicast hash filter. */ ++ netdev_for_each_mc_addr(ha, net) { ++ crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; ++ data->multi_filter[crc_bits >> 3] |= ++ 1 << (crc_bits & 7); ++ } ++ ++ asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, ++ AX_MCAST_FILTER_SIZE, data->multi_filter); ++ ++ rx_ctl |= AX_RX_CTL_AM; ++ } ++ ++ asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); ++} ++ ++int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ __le16 res; ++ ++ mutex_lock(&dev->phy_mutex); ++ asix_set_sw_mii(dev); ++ asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, ++ (__u16)loc, 2, &res); ++ asix_set_hw_mii(dev); ++ mutex_unlock(&dev->phy_mutex); ++ ++ netdev_dbg(dev->net, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", ++ phy_id, loc, le16_to_cpu(res)); ++ ++ return le16_to_cpu(res); ++} ++ ++void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ __le16 res = cpu_to_le16(val); ++ ++ netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", ++ phy_id, loc, val); ++ mutex_lock(&dev->phy_mutex); ++ asix_set_sw_mii(dev); ++ asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); ++ asix_set_hw_mii(dev); ++ mutex_unlock(&dev->phy_mutex); ++} ++ ++void asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ u8 opt; ++ ++ if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { ++ wolinfo->supported = 0; ++ wolinfo->wolopts = 0; ++ return; ++ } ++ wolinfo->supported = WAKE_PHY | WAKE_MAGIC; ++ wolinfo->wolopts = 0; ++ if (opt & AX_MONITOR_LINK) ++ wolinfo->wolopts |= WAKE_PHY; ++ if (opt & AX_MONITOR_MAGIC) ++ wolinfo->wolopts |= WAKE_MAGIC; ++} ++ ++int asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ u8 opt = 0; ++ ++ if (wolinfo->wolopts & WAKE_PHY) ++ opt |= AX_MONITOR_LINK; ++ if (wolinfo->wolopts & WAKE_MAGIC) ++ opt |= AX_MONITOR_MAGIC; ++ ++ if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, ++ opt, 0, 0, NULL) < 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++int asix_get_eeprom_len(struct net_device *net) ++{ ++ return AX_EEPROM_LEN; ++} ++ ++int asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, ++ u8 *data) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ u16 *eeprom_buff; ++ int first_word, last_word; ++ int i; ++ ++ if (eeprom->len == 0) ++ return -EINVAL; ++ ++ eeprom->magic = AX_EEPROM_MAGIC; ++ ++ first_word = eeprom->offset >> 1; ++ last_word = (eeprom->offset + eeprom->len - 1) >> 1; ++ ++ eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), ++ GFP_KERNEL); ++ if (!eeprom_buff) ++ return -ENOMEM; ++ ++ /* ax8817x returns 2 bytes from eeprom on read */ ++ for (i = first_word; i <= last_word; i++) { ++ if (asix_read_cmd(dev, AX_CMD_READ_EEPROM, i, 0, 2, ++ &(eeprom_buff[i - first_word])) < 0) { ++ kfree(eeprom_buff); ++ return -EIO; ++ } ++ } ++ ++ memcpy(data, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); ++ kfree(eeprom_buff); ++ return 0; ++} ++ ++int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, ++ u8 *data) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ u16 *eeprom_buff; ++ int first_word, last_word; ++ int i; ++ int ret; ++ ++ netdev_dbg(net, "write EEPROM len %d, offset %d, magic 0x%x\n", ++ eeprom->len, eeprom->offset, eeprom->magic); ++ ++ if (eeprom->len == 0) ++ return -EINVAL; ++ ++ if (eeprom->magic != AX_EEPROM_MAGIC) ++ return -EINVAL; ++ ++ first_word = eeprom->offset >> 1; ++ last_word = (eeprom->offset + eeprom->len - 1) >> 1; ++ ++ eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), ++ GFP_KERNEL); ++ if (!eeprom_buff) ++ return -ENOMEM; ++ ++ /* align data to 16 bit boundaries, read the missing data from ++ the EEPROM */ ++ if (eeprom->offset & 1) { ++ ret = asix_read_cmd(dev, AX_CMD_READ_EEPROM, first_word, 0, 2, ++ &(eeprom_buff[0])); ++ if (ret < 0) { ++ netdev_err(net, "Failed to read EEPROM at offset 0x%02x.\n", first_word); ++ goto free; ++ } ++ } ++ ++ if ((eeprom->offset + eeprom->len) & 1) { ++ ret = asix_read_cmd(dev, AX_CMD_READ_EEPROM, last_word, 0, 2, ++ &(eeprom_buff[last_word - first_word])); ++ if (ret < 0) { ++ netdev_err(net, "Failed to read EEPROM at offset 0x%02x.\n", last_word); ++ goto free; ++ } ++ } ++ ++ memcpy((u8 *)eeprom_buff + (eeprom->offset & 1), data, eeprom->len); ++ ++ /* write data to EEPROM */ ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0x0000, 0, 0, NULL); ++ if (ret < 0) { ++ netdev_err(net, "Failed to enable EEPROM write\n"); ++ goto free; ++ } ++ msleep(20); ++ ++ for (i = first_word; i <= last_word; i++) { ++ netdev_dbg(net, "write to EEPROM at offset 0x%02x, data 0x%04x\n", ++ i, eeprom_buff[i - first_word]); ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_EEPROM, i, ++ eeprom_buff[i - first_word], 0, NULL); ++ if (ret < 0) { ++ netdev_err(net, "Failed to write EEPROM at offset 0x%02x.\n", ++ i); ++ goto free; ++ } ++ msleep(20); ++ } ++ ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0x0000, 0, 0, NULL); ++ if (ret < 0) { ++ netdev_err(net, "Failed to disable EEPROM write\n"); ++ goto free; ++ } ++ ++ ret = 0; ++free: ++ kfree(eeprom_buff); ++ return ret; ++} ++ ++void asix_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) ++{ ++ /* Inherit standard device info */ ++ usbnet_get_drvinfo(net, info); ++ strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver)); ++ strlcpy(info->version, DRIVER_VERSION, sizeof(info->version)); ++ info->eedump_len = AX_EEPROM_LEN; ++} ++ ++int asix_set_mac_address(struct net_device *net, void *p) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct asix_data *data = (struct asix_data *)&dev->data; ++ struct sockaddr *addr = p; ++ ++ if (netif_running(net)) ++ return -EBUSY; ++ if (!is_valid_ether_addr(addr->sa_data)) ++ return -EADDRNOTAVAIL; ++ ++ memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); ++ ++ /* We use the 20 byte dev->data ++ * for our 6 byte mac buffer ++ * to avoid allocating memory that ++ * is tricky to free later */ ++ memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); ++ asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, ++ data->mac_addr); ++ ++ return 0; ++} +diff -Naur backports-3.18.1-1.org/drivers/net/usb/asix_devices.c backports-3.18.1-1/drivers/net/usb/asix_devices.c +--- backports-3.18.1-1.org/drivers/net/usb/asix_devices.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/asix_devices.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,1104 @@ ++/* ++ * ASIX AX8817X based USB 2.0 Ethernet Devices ++ * Copyright (C) 2003-2006 David Hollis dhollis@davehollis.com ++ * Copyright (C) 2005 Phil Chang pchang23@sbcglobal.net ++ * Copyright (C) 2006 James Painter jamie.painter@iname.com ++ * Copyright (c) 2002-2003 TiVo Inc. ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include "asix.h" ++ ++#define PHY_MODE_MARVELL 0x0000 ++#define MII_MARVELL_LED_CTRL 0x0018 ++#define MII_MARVELL_STATUS 0x001b ++#define MII_MARVELL_CTRL 0x0014 ++ ++#define MARVELL_LED_MANUAL 0x0019 ++ ++#define MARVELL_STATUS_HWCFG 0x0004 ++ ++#define MARVELL_CTRL_TXDELAY 0x0002 ++#define MARVELL_CTRL_RXDELAY 0x0080 ++ ++#define PHY_MODE_RTL8211CL 0x000C ++ ++struct ax88172_int_data { ++ __le16 res1; ++ u8 link; ++ __le16 res2; ++ u8 status; ++ __le16 res3; ++} __packed; ++ ++static void asix_status(struct usbnet *dev, struct urb *urb) ++{ ++ struct ax88172_int_data *event; ++ int link; ++ ++ if (urb->actual_length < 8) ++ return; ++ ++ event = urb->transfer_buffer; ++ link = event->link & 0x01; ++ if (netif_carrier_ok(dev->net) != link) { ++ usbnet_link_change(dev, link, 1); ++ netdev_dbg(dev->net, "Link Status is: %d\n", link); ++ } ++} ++ ++static void asix_set_netdev_dev_addr(struct usbnet *dev, u8 *addr) ++{ ++ if (is_valid_ether_addr(addr)) { ++ memcpy(dev->net->dev_addr, addr, ETH_ALEN); ++ } else { ++ netdev_info(dev->net, "invalid hw address, using random\n"); ++ eth_hw_addr_random(dev->net); ++ } ++} ++ ++/* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ ++static u32 asix_get_phyid(struct usbnet *dev) ++{ ++ int phy_reg; ++ u32 phy_id; ++ int i; ++ ++ /* Poll for the rare case the FW or phy isn't ready yet. */ ++ for (i = 0; i < 100; i++) { ++ phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1); ++ if (phy_reg != 0 && phy_reg != 0xFFFF) ++ break; ++ mdelay(1); ++ } ++ ++ if (phy_reg <= 0 || phy_reg == 0xFFFF) ++ return 0; ++ ++ phy_id = (phy_reg & 0xffff) << 16; ++ ++ phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID2); ++ if (phy_reg < 0) ++ return 0; ++ ++ phy_id |= (phy_reg & 0xffff); ++ ++ return phy_id; ++} ++ ++static u32 asix_get_link(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ return mii_link_ok(&dev->mii); ++} ++ ++static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); ++} ++ ++/* We need to override some ethtool_ops so we require our ++ own structure so we don't interfere with other usbnet ++ devices that may be connected at the same time. */ ++static const struct ethtool_ops ax88172_ethtool_ops = { ++ .get_drvinfo = asix_get_drvinfo, ++ .get_link = asix_get_link, ++ .get_msglevel = usbnet_get_msglevel, ++ .set_msglevel = usbnet_set_msglevel, ++ .get_wol = asix_get_wol, ++ .set_wol = asix_set_wol, ++ .get_eeprom_len = asix_get_eeprom_len, ++ .get_eeprom = asix_get_eeprom, ++ .set_eeprom = asix_set_eeprom, ++ .get_settings = usbnet_get_settings, ++ .set_settings = usbnet_set_settings, ++ .nway_reset = usbnet_nway_reset, ++}; ++ ++static void ax88172_set_multicast(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct asix_data *data = (struct asix_data *)&dev->data; ++ u8 rx_ctl = 0x8c; ++ ++ if (net->flags & IFF_PROMISC) { ++ rx_ctl |= 0x01; ++ } else if (net->flags & IFF_ALLMULTI || ++ netdev_mc_count(net) > AX_MAX_MCAST) { ++ rx_ctl |= 0x02; ++ } else if (netdev_mc_empty(net)) { ++ /* just broadcast and directed */ ++ } else { ++ /* We use the 20 byte dev->data ++ * for our 8 byte filter buffer ++ * to avoid allocating memory that ++ * is tricky to free later */ ++ struct netdev_hw_addr *ha; ++ u32 crc_bits; ++ ++ memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); ++ ++ /* Build the multicast hash filter. */ ++ netdev_for_each_mc_addr(ha, net) { ++ crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; ++ data->multi_filter[crc_bits >> 3] |= ++ 1 << (crc_bits & 7); ++ } ++ ++ asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, ++ AX_MCAST_FILTER_SIZE, data->multi_filter); ++ ++ rx_ctl |= 0x10; ++ } ++ ++ asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); ++} ++ ++static int ax88172_link_reset(struct usbnet *dev) ++{ ++ u8 mode; ++ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; ++ ++ mii_check_media(&dev->mii, 1, 1); ++ mii_ethtool_gset(&dev->mii, &ecmd); ++ mode = AX88172_MEDIUM_DEFAULT; ++ ++ if (ecmd.duplex != DUPLEX_FULL) ++ mode |= ~AX88172_MEDIUM_FD; ++ ++ netdev_dbg(dev->net, "ax88172_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n", ++ ethtool_cmd_speed(&ecmd), ecmd.duplex, mode); ++ ++ asix_write_medium_mode(dev, mode); ++ ++ return 0; ++} ++ ++static const struct net_device_ops ax88172_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = usbnet_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = asix_ioctl, ++ .ndo_set_rx_mode = ax88172_set_multicast, ++}; ++ ++static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int ret = 0; ++ u8 buf[ETH_ALEN]; ++ int i; ++ unsigned long gpio_bits = dev->driver_info->data; ++ ++ usbnet_get_endpoints(dev,intf); ++ ++ /* Toggle the GPIOs in a manufacturer/model specific way */ ++ for (i = 2; i >= 0; i--) { ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, ++ (gpio_bits >> (i * 8)) & 0xff, 0, 0, NULL); ++ if (ret < 0) ++ goto out; ++ msleep(5); ++ } ++ ++ ret = asix_write_rx_ctl(dev, 0x80); ++ if (ret < 0) ++ goto out; ++ ++ /* Get the MAC address */ ++ ret = asix_read_cmd(dev, AX88172_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf); ++ if (ret < 0) { ++ netdev_dbg(dev->net, "read AX_CMD_READ_NODE_ID failed: %d\n", ++ ret); ++ goto out; ++ } ++ ++ asix_set_netdev_dev_addr(dev, buf); ++ ++ /* Initialize MII structure */ ++ dev->mii.dev = dev->net; ++ dev->mii.mdio_read = asix_mdio_read; ++ dev->mii.mdio_write = asix_mdio_write; ++ dev->mii.phy_id_mask = 0x3f; ++ dev->mii.reg_num_mask = 0x1f; ++ dev->mii.phy_id = asix_get_phy_addr(dev); ++ ++ dev->net->netdev_ops = &ax88172_netdev_ops; ++ dev->net->ethtool_ops = &ax88172_ethtool_ops; ++ dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */ ++ dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */ ++ ++ asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); ++ asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ++ ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); ++ mii_nway_restart(&dev->mii); ++ ++ return 0; ++ ++out: ++ return ret; ++} ++ ++static const struct ethtool_ops ax88772_ethtool_ops = { ++ .get_drvinfo = asix_get_drvinfo, ++ .get_link = asix_get_link, ++ .get_msglevel = usbnet_get_msglevel, ++ .set_msglevel = usbnet_set_msglevel, ++ .get_wol = asix_get_wol, ++ .set_wol = asix_set_wol, ++ .get_eeprom_len = asix_get_eeprom_len, ++ .get_eeprom = asix_get_eeprom, ++ .set_eeprom = asix_set_eeprom, ++ .get_settings = usbnet_get_settings, ++ .set_settings = usbnet_set_settings, ++ .nway_reset = usbnet_nway_reset, ++}; ++ ++static int ax88772_link_reset(struct usbnet *dev) ++{ ++ u16 mode; ++ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; ++ ++ mii_check_media(&dev->mii, 1, 1); ++ mii_ethtool_gset(&dev->mii, &ecmd); ++ mode = AX88772_MEDIUM_DEFAULT; ++ ++ if (ethtool_cmd_speed(&ecmd) != SPEED_100) ++ mode &= ~AX_MEDIUM_PS; ++ ++ if (ecmd.duplex != DUPLEX_FULL) ++ mode &= ~AX_MEDIUM_FD; ++ ++ netdev_dbg(dev->net, "ax88772_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n", ++ ethtool_cmd_speed(&ecmd), ecmd.duplex, mode); ++ ++ asix_write_medium_mode(dev, mode); ++ ++ return 0; ++} ++ ++static int ax88772_reset(struct usbnet *dev) ++{ ++ struct asix_data *data = (struct asix_data *)&dev->data; ++ int ret, embd_phy; ++ u16 rx_ctl; ++ ++ ret = asix_write_gpio(dev, ++ AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5); ++ if (ret < 0) ++ goto out; ++ ++ embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); ++ ++ ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); ++ if (ret < 0) { ++ netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); ++ goto out; ++ } ++ ++ ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL); ++ if (ret < 0) ++ goto out; ++ ++ msleep(150); ++ ++ ret = asix_sw_reset(dev, AX_SWRESET_CLEAR); ++ if (ret < 0) ++ goto out; ++ ++ msleep(150); ++ ++ if (embd_phy) { ++ ret = asix_sw_reset(dev, AX_SWRESET_IPRL); ++ if (ret < 0) ++ goto out; ++ } else { ++ ret = asix_sw_reset(dev, AX_SWRESET_PRTE); ++ if (ret < 0) ++ goto out; ++ } ++ ++ msleep(150); ++ rx_ctl = asix_read_rx_ctl(dev); ++ netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); ++ ret = asix_write_rx_ctl(dev, 0x0000); ++ if (ret < 0) ++ goto out; ++ ++ rx_ctl = asix_read_rx_ctl(dev); ++ netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); ++ ++ ret = asix_sw_reset(dev, AX_SWRESET_PRL); ++ if (ret < 0) ++ goto out; ++ ++ msleep(150); ++ ++ ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL); ++ if (ret < 0) ++ goto out; ++ ++ msleep(150); ++ ++ asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); ++ asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ++ ADVERTISE_ALL | ADVERTISE_CSMA); ++ mii_nway_restart(&dev->mii); ++ ++ ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT); ++ if (ret < 0) ++ goto out; ++ ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, ++ AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, ++ AX88772_IPG2_DEFAULT, 0, NULL); ++ if (ret < 0) { ++ netdev_dbg(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); ++ goto out; ++ } ++ ++ /* Rewrite MAC address */ ++ memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, ++ data->mac_addr); ++ if (ret < 0) ++ goto out; ++ ++ /* Set RX_CTL to default values with 2k buffer, and enable cactus */ ++ ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); ++ if (ret < 0) ++ goto out; ++ ++ rx_ctl = asix_read_rx_ctl(dev); ++ netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", ++ rx_ctl); ++ ++ rx_ctl = asix_read_medium_status(dev); ++ netdev_dbg(dev->net, ++ "Medium Status is 0x%04x after all initializations\n", ++ rx_ctl); ++ ++ return 0; ++ ++out: ++ return ret; ++ ++} ++ ++static const struct net_device_ops ax88772_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = usbnet_change_mtu, ++ .ndo_set_mac_address = asix_set_mac_address, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = asix_ioctl, ++ .ndo_set_rx_mode = asix_set_multicast, ++}; ++ ++static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int ret, embd_phy, i; ++ u8 buf[ETH_ALEN]; ++ u32 phyid; ++ ++ usbnet_get_endpoints(dev,intf); ++ ++ /* Get the MAC address */ ++ if (dev->driver_info->data & FLAG_EEPROM_MAC) { ++ for (i = 0; i < (ETH_ALEN >> 1); i++) { ++ ret = asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x04 + i, ++ 0, 2, buf + i * 2); ++ if (ret < 0) ++ break; ++ } ++ } else { ++ ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, ++ 0, 0, ETH_ALEN, buf); ++ } ++ ++ if (ret < 0) { ++ netdev_dbg(dev->net, "Failed to read MAC address: %d\n", ret); ++ return ret; ++ } ++ ++ asix_set_netdev_dev_addr(dev, buf); ++ ++ /* Initialize MII structure */ ++ dev->mii.dev = dev->net; ++ dev->mii.mdio_read = asix_mdio_read; ++ dev->mii.mdio_write = asix_mdio_write; ++ dev->mii.phy_id_mask = 0x1f; ++ dev->mii.reg_num_mask = 0x1f; ++ dev->mii.phy_id = asix_get_phy_addr(dev); ++ ++ dev->net->netdev_ops = &ax88772_netdev_ops; ++ dev->net->ethtool_ops = &ax88772_ethtool_ops; ++ dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */ ++ dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */ ++ ++ embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); ++ ++ /* Reset the PHY to normal operation mode */ ++ ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); ++ if (ret < 0) { ++ netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); ++ return ret; ++ } ++ ++ ax88772_reset(dev); ++ ++ /* Read PHYID register *AFTER* the PHY was reset properly */ ++ phyid = asix_get_phyid(dev); ++ netdev_dbg(dev->net, "PHYID=0x%08x\n", phyid); ++ ++ /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ ++ if (dev->driver_info->flags & FLAG_FRAMING_AX) { ++ /* hard_mtu is still the default - the device does not support ++ jumbo eth frames */ ++ dev->rx_urb_size = 2048; ++ } ++ ++ dev->driver_priv = kzalloc(sizeof(struct asix_common_private), GFP_KERNEL); ++ if (!dev->driver_priv) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ if (dev->driver_priv) ++ kfree(dev->driver_priv); ++} ++ ++static const struct ethtool_ops ax88178_ethtool_ops = { ++ .get_drvinfo = asix_get_drvinfo, ++ .get_link = asix_get_link, ++ .get_msglevel = usbnet_get_msglevel, ++ .set_msglevel = usbnet_set_msglevel, ++ .get_wol = asix_get_wol, ++ .set_wol = asix_set_wol, ++ .get_eeprom_len = asix_get_eeprom_len, ++ .get_eeprom = asix_get_eeprom, ++ .set_eeprom = asix_set_eeprom, ++ .get_settings = usbnet_get_settings, ++ .set_settings = usbnet_set_settings, ++ .nway_reset = usbnet_nway_reset, ++}; ++ ++static int marvell_phy_init(struct usbnet *dev) ++{ ++ struct asix_data *data = (struct asix_data *)&dev->data; ++ u16 reg; ++ ++ netdev_dbg(dev->net, "marvell_phy_init()\n"); ++ ++ reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_MARVELL_STATUS); ++ netdev_dbg(dev->net, "MII_MARVELL_STATUS = 0x%04x\n", reg); ++ ++ asix_mdio_write(dev->net, dev->mii.phy_id, MII_MARVELL_CTRL, ++ MARVELL_CTRL_RXDELAY | MARVELL_CTRL_TXDELAY); ++ ++ if (data->ledmode) { ++ reg = asix_mdio_read(dev->net, dev->mii.phy_id, ++ MII_MARVELL_LED_CTRL); ++ netdev_dbg(dev->net, "MII_MARVELL_LED_CTRL (1) = 0x%04x\n", reg); ++ ++ reg &= 0xf8ff; ++ reg |= (1 + 0x0100); ++ asix_mdio_write(dev->net, dev->mii.phy_id, ++ MII_MARVELL_LED_CTRL, reg); ++ ++ reg = asix_mdio_read(dev->net, dev->mii.phy_id, ++ MII_MARVELL_LED_CTRL); ++ netdev_dbg(dev->net, "MII_MARVELL_LED_CTRL (2) = 0x%04x\n", reg); ++ reg &= 0xfc0f; ++ } ++ ++ return 0; ++} ++ ++static int rtl8211cl_phy_init(struct usbnet *dev) ++{ ++ struct asix_data *data = (struct asix_data *)&dev->data; ++ ++ netdev_dbg(dev->net, "rtl8211cl_phy_init()\n"); ++ ++ asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0x0005); ++ asix_mdio_write (dev->net, dev->mii.phy_id, 0x0c, 0); ++ asix_mdio_write (dev->net, dev->mii.phy_id, 0x01, ++ asix_mdio_read (dev->net, dev->mii.phy_id, 0x01) | 0x0080); ++ asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0); ++ ++ if (data->ledmode == 12) { ++ asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0x0002); ++ asix_mdio_write (dev->net, dev->mii.phy_id, 0x1a, 0x00cb); ++ asix_mdio_write (dev->net, dev->mii.phy_id, 0x1f, 0); ++ } ++ ++ return 0; ++} ++ ++static int marvell_led_status(struct usbnet *dev, u16 speed) ++{ ++ u16 reg = asix_mdio_read(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL); ++ ++ netdev_dbg(dev->net, "marvell_led_status() read 0x%04x\n", reg); ++ ++ /* Clear out the center LED bits - 0x03F0 */ ++ reg &= 0xfc0f; ++ ++ switch (speed) { ++ case SPEED_1000: ++ reg |= 0x03e0; ++ break; ++ case SPEED_100: ++ reg |= 0x03b0; ++ break; ++ default: ++ reg |= 0x02f0; ++ } ++ ++ netdev_dbg(dev->net, "marvell_led_status() writing 0x%04x\n", reg); ++ asix_mdio_write(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL, reg); ++ ++ return 0; ++} ++ ++static int ax88178_reset(struct usbnet *dev) ++{ ++ struct asix_data *data = (struct asix_data *)&dev->data; ++ int ret; ++ __le16 eeprom; ++ u8 status; ++ int gpio0 = 0; ++ u32 phyid; ++ ++ asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status); ++ netdev_dbg(dev->net, "GPIO Status: 0x%04x\n", status); ++ ++ asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL); ++ asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom); ++ asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL); ++ ++ netdev_dbg(dev->net, "EEPROM index 0x17 is 0x%04x\n", eeprom); ++ ++ if (eeprom == cpu_to_le16(0xffff)) { ++ data->phymode = PHY_MODE_MARVELL; ++ data->ledmode = 0; ++ gpio0 = 1; ++ } else { ++ data->phymode = le16_to_cpu(eeprom) & 0x7F; ++ data->ledmode = le16_to_cpu(eeprom) >> 8; ++ gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1; ++ } ++ netdev_dbg(dev->net, "GPIO0: %d, PhyMode: %d\n", gpio0, data->phymode); ++ ++ /* Power up external GigaPHY through AX88178 GPIO pin */ ++ asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40); ++ if ((le16_to_cpu(eeprom) >> 8) != 1) { ++ asix_write_gpio(dev, 0x003c, 30); ++ asix_write_gpio(dev, 0x001c, 300); ++ asix_write_gpio(dev, 0x003c, 30); ++ } else { ++ netdev_dbg(dev->net, "gpio phymode == 1 path\n"); ++ asix_write_gpio(dev, AX_GPIO_GPO1EN, 30); ++ asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30); ++ } ++ ++ /* Read PHYID register *AFTER* powering up PHY */ ++ phyid = asix_get_phyid(dev); ++ netdev_dbg(dev->net, "PHYID=0x%08x\n", phyid); ++ ++ /* Set AX88178 to enable MII/GMII/RGMII interface for external PHY */ ++ asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0, 0, 0, NULL); ++ ++ asix_sw_reset(dev, 0); ++ msleep(150); ++ ++ asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD); ++ msleep(150); ++ ++ asix_write_rx_ctl(dev, 0); ++ ++ if (data->phymode == PHY_MODE_MARVELL) { ++ marvell_phy_init(dev); ++ msleep(60); ++ } else if (data->phymode == PHY_MODE_RTL8211CL) ++ rtl8211cl_phy_init(dev); ++ ++ asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, ++ BMCR_RESET | BMCR_ANENABLE); ++ asix_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ++ ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); ++ asix_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000, ++ ADVERTISE_1000FULL); ++ ++ mii_nway_restart(&dev->mii); ++ ++ ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT); ++ if (ret < 0) ++ return ret; ++ ++ /* Rewrite MAC address */ ++ memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, ++ data->mac_addr); ++ if (ret < 0) ++ return ret; ++ ++ ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static int ax88178_link_reset(struct usbnet *dev) ++{ ++ u16 mode; ++ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; ++ struct asix_data *data = (struct asix_data *)&dev->data; ++ u32 speed; ++ ++ netdev_dbg(dev->net, "ax88178_link_reset()\n"); ++ ++ mii_check_media(&dev->mii, 1, 1); ++ mii_ethtool_gset(&dev->mii, &ecmd); ++ mode = AX88178_MEDIUM_DEFAULT; ++ speed = ethtool_cmd_speed(&ecmd); ++ ++ if (speed == SPEED_1000) ++ mode |= AX_MEDIUM_GM; ++ else if (speed == SPEED_100) ++ mode |= AX_MEDIUM_PS; ++ else ++ mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM); ++ ++ mode |= AX_MEDIUM_ENCK; ++ ++ if (ecmd.duplex == DUPLEX_FULL) ++ mode |= AX_MEDIUM_FD; ++ else ++ mode &= ~AX_MEDIUM_FD; ++ ++ netdev_dbg(dev->net, "ax88178_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n", ++ speed, ecmd.duplex, mode); ++ ++ asix_write_medium_mode(dev, mode); ++ ++ if (data->phymode == PHY_MODE_MARVELL && data->ledmode) ++ marvell_led_status(dev, speed); ++ ++ return 0; ++} ++ ++static void ax88178_set_mfb(struct usbnet *dev) ++{ ++ u16 mfb = AX_RX_CTL_MFB_16384; ++ u16 rxctl; ++ u16 medium; ++ int old_rx_urb_size = dev->rx_urb_size; ++ ++ if (dev->hard_mtu < 2048) { ++ dev->rx_urb_size = 2048; ++ mfb = AX_RX_CTL_MFB_2048; ++ } else if (dev->hard_mtu < 4096) { ++ dev->rx_urb_size = 4096; ++ mfb = AX_RX_CTL_MFB_4096; ++ } else if (dev->hard_mtu < 8192) { ++ dev->rx_urb_size = 8192; ++ mfb = AX_RX_CTL_MFB_8192; ++ } else if (dev->hard_mtu < 16384) { ++ dev->rx_urb_size = 16384; ++ mfb = AX_RX_CTL_MFB_16384; ++ } ++ ++ rxctl = asix_read_rx_ctl(dev); ++ asix_write_rx_ctl(dev, (rxctl & ~AX_RX_CTL_MFB_16384) | mfb); ++ ++ medium = asix_read_medium_status(dev); ++ if (dev->net->mtu > 1500) ++ medium |= AX_MEDIUM_JFE; ++ else ++ medium &= ~AX_MEDIUM_JFE; ++ asix_write_medium_mode(dev, medium); ++ ++ if (dev->rx_urb_size > old_rx_urb_size) ++ usbnet_unlink_rx_urbs(dev); ++} ++ ++static int ax88178_change_mtu(struct net_device *net, int new_mtu) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ int ll_mtu = new_mtu + net->hard_header_len + 4; ++ ++ netdev_dbg(dev->net, "ax88178_change_mtu() new_mtu=%d\n", new_mtu); ++ ++ if (new_mtu <= 0 || ll_mtu > 16384) ++ return -EINVAL; ++ ++ if ((ll_mtu % dev->maxpacket) == 0) ++ return -EDOM; ++ ++ net->mtu = new_mtu; ++ dev->hard_mtu = net->mtu + net->hard_header_len; ++ ax88178_set_mfb(dev); ++ ++ /* max qlen depend on hard_mtu and rx_urb_size */ ++ usbnet_update_max_qlen(dev); ++ ++ return 0; ++} ++ ++static const struct net_device_ops ax88178_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_set_mac_address = asix_set_mac_address, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_set_rx_mode = asix_set_multicast, ++ .ndo_do_ioctl = asix_ioctl, ++ .ndo_change_mtu = ax88178_change_mtu, ++}; ++ ++static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int ret; ++ u8 buf[ETH_ALEN]; ++ ++ usbnet_get_endpoints(dev,intf); ++ ++ /* Get the MAC address */ ++ ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf); ++ if (ret < 0) { ++ netdev_dbg(dev->net, "Failed to read MAC address: %d\n", ret); ++ return ret; ++ } ++ ++ asix_set_netdev_dev_addr(dev, buf); ++ ++ /* Initialize MII structure */ ++ dev->mii.dev = dev->net; ++ dev->mii.mdio_read = asix_mdio_read; ++ dev->mii.mdio_write = asix_mdio_write; ++ dev->mii.phy_id_mask = 0x1f; ++ dev->mii.reg_num_mask = 0xff; ++ dev->mii.supports_gmii = 1; ++ dev->mii.phy_id = asix_get_phy_addr(dev); ++ ++ dev->net->netdev_ops = &ax88178_netdev_ops; ++ dev->net->ethtool_ops = &ax88178_ethtool_ops; ++ ++ /* Blink LEDS so users know driver saw dongle */ ++ asix_sw_reset(dev, 0); ++ msleep(150); ++ ++ asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD); ++ msleep(150); ++ ++ /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ ++ if (dev->driver_info->flags & FLAG_FRAMING_AX) { ++ /* hard_mtu is still the default - the device does not support ++ jumbo eth frames */ ++ dev->rx_urb_size = 2048; ++ } ++ ++ dev->driver_priv = kzalloc(sizeof(struct asix_common_private), GFP_KERNEL); ++ if (!dev->driver_priv) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++static const struct driver_info ax8817x_info = { ++ .description = "ASIX AX8817x USB 2.0 Ethernet", ++ .bind = ax88172_bind, ++ .status = asix_status, ++ .link_reset = ax88172_link_reset, ++ .reset = ax88172_link_reset, ++ .flags = FLAG_ETHER | FLAG_LINK_INTR, ++ .data = 0x00130103, ++}; ++ ++static const struct driver_info dlink_dub_e100_info = { ++ .description = "DLink DUB-E100 USB Ethernet", ++ .bind = ax88172_bind, ++ .status = asix_status, ++ .link_reset = ax88172_link_reset, ++ .reset = ax88172_link_reset, ++ .flags = FLAG_ETHER | FLAG_LINK_INTR, ++ .data = 0x009f9d9f, ++}; ++ ++static const struct driver_info netgear_fa120_info = { ++ .description = "Netgear FA-120 USB Ethernet", ++ .bind = ax88172_bind, ++ .status = asix_status, ++ .link_reset = ax88172_link_reset, ++ .reset = ax88172_link_reset, ++ .flags = FLAG_ETHER | FLAG_LINK_INTR, ++ .data = 0x00130103, ++}; ++ ++static const struct driver_info hawking_uf200_info = { ++ .description = "Hawking UF200 USB Ethernet", ++ .bind = ax88172_bind, ++ .status = asix_status, ++ .link_reset = ax88172_link_reset, ++ .reset = ax88172_link_reset, ++ .flags = FLAG_ETHER | FLAG_LINK_INTR, ++ .data = 0x001f1d1f, ++}; ++ ++static const struct driver_info ax88772_info = { ++ .description = "ASIX AX88772 USB 2.0 Ethernet", ++ .bind = ax88772_bind, ++ .unbind = ax88772_unbind, ++ .status = asix_status, ++ .link_reset = ax88772_link_reset, ++ .reset = ax88772_link_reset, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET, ++ .rx_fixup = asix_rx_fixup_common, ++ .tx_fixup = asix_tx_fixup, ++}; ++ ++static const struct driver_info ax88772b_info = { ++ .description = "ASIX AX88772B USB 2.0 Ethernet", ++ .bind = ax88772_bind, ++ .unbind = ax88772_unbind, ++ .status = asix_status, ++ .link_reset = ax88772_link_reset, ++ .reset = ax88772_reset, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | ++ FLAG_MULTI_PACKET, ++ .rx_fixup = asix_rx_fixup_common, ++ .tx_fixup = asix_tx_fixup, ++ .data = FLAG_EEPROM_MAC, ++}; ++ ++static const struct driver_info ax88178_info = { ++ .description = "ASIX AX88178 USB 2.0 Ethernet", ++ .bind = ax88178_bind, ++ .unbind = ax88772_unbind, ++ .status = asix_status, ++ .link_reset = ax88178_link_reset, ++ .reset = ax88178_reset, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | ++ FLAG_MULTI_PACKET, ++ .rx_fixup = asix_rx_fixup_common, ++ .tx_fixup = asix_tx_fixup, ++}; ++ ++/* ++ * USBLINK 20F9 "USB 2.0 LAN" USB ethernet adapter, typically found in ++ * no-name packaging. ++ * USB device strings are: ++ * 1: Manufacturer: USBLINK ++ * 2: Product: HG20F9 USB2.0 ++ * 3: Serial: 000003 ++ * Appears to be compatible with Asix 88772B. ++ */ ++static const struct driver_info hg20f9_info = { ++ .description = "HG20F9 USB 2.0 Ethernet", ++ .bind = ax88772_bind, ++ .unbind = ax88772_unbind, ++ .status = asix_status, ++ .link_reset = ax88772_link_reset, ++ .reset = ax88772_reset, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | ++ FLAG_MULTI_PACKET, ++ .rx_fixup = asix_rx_fixup_common, ++ .tx_fixup = asix_tx_fixup, ++ .data = FLAG_EEPROM_MAC, ++}; ++ ++static const struct usb_device_id products [] = { ++{ ++ // Linksys USB200M ++ USB_DEVICE (0x077b, 0x2226), ++ .driver_info = (unsigned long) &ax8817x_info, ++}, { ++ // Netgear FA120 ++ USB_DEVICE (0x0846, 0x1040), ++ .driver_info = (unsigned long) &netgear_fa120_info, ++}, { ++ // DLink DUB-E100 ++ USB_DEVICE (0x2001, 0x1a00), ++ .driver_info = (unsigned long) &dlink_dub_e100_info, ++}, { ++ // Intellinet, ST Lab USB Ethernet ++ USB_DEVICE (0x0b95, 0x1720), ++ .driver_info = (unsigned long) &ax8817x_info, ++}, { ++ // Hawking UF200, TrendNet TU2-ET100 ++ USB_DEVICE (0x07b8, 0x420a), ++ .driver_info = (unsigned long) &hawking_uf200_info, ++}, { ++ // Billionton Systems, USB2AR ++ USB_DEVICE (0x08dd, 0x90ff), ++ .driver_info = (unsigned long) &ax8817x_info, ++}, { ++ // ATEN UC210T ++ USB_DEVICE (0x0557, 0x2009), ++ .driver_info = (unsigned long) &ax8817x_info, ++}, { ++ // Buffalo LUA-U2-KTX ++ USB_DEVICE (0x0411, 0x003d), ++ .driver_info = (unsigned long) &ax8817x_info, ++}, { ++ // Buffalo LUA-U2-GT 10/100/1000 ++ USB_DEVICE (0x0411, 0x006e), ++ .driver_info = (unsigned long) &ax88178_info, ++}, { ++ // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" ++ USB_DEVICE (0x6189, 0x182d), ++ .driver_info = (unsigned long) &ax8817x_info, ++}, { ++ // Sitecom LN-031 "USB 2.0 10/100/1000 Ethernet adapter" ++ USB_DEVICE (0x0df6, 0x0056), ++ .driver_info = (unsigned long) &ax88178_info, ++}, { ++ // corega FEther USB2-TX ++ USB_DEVICE (0x07aa, 0x0017), ++ .driver_info = (unsigned long) &ax8817x_info, ++}, { ++ // Surecom EP-1427X-2 ++ USB_DEVICE (0x1189, 0x0893), ++ .driver_info = (unsigned long) &ax8817x_info, ++}, { ++ // goodway corp usb gwusb2e ++ USB_DEVICE (0x1631, 0x6200), ++ .driver_info = (unsigned long) &ax8817x_info, ++}, { ++ // JVC MP-PRX1 Port Replicator ++ USB_DEVICE (0x04f1, 0x3008), ++ .driver_info = (unsigned long) &ax8817x_info, ++}, { ++ // Lenovo U2L100P 10/100 ++ USB_DEVICE (0x17ef, 0x7203), ++ .driver_info = (unsigned long) &ax88772_info, ++}, { ++ // ASIX AX88772B 10/100 ++ USB_DEVICE (0x0b95, 0x772b), ++ .driver_info = (unsigned long) &ax88772b_info, ++}, { ++ // ASIX AX88772 10/100 ++ USB_DEVICE (0x0b95, 0x7720), ++ .driver_info = (unsigned long) &ax88772_info, ++}, { ++ // ASIX AX88178 10/100/1000 ++ USB_DEVICE (0x0b95, 0x1780), ++ .driver_info = (unsigned long) &ax88178_info, ++}, { ++ // Logitec LAN-GTJ/U2A ++ USB_DEVICE (0x0789, 0x0160), ++ .driver_info = (unsigned long) &ax88178_info, ++}, { ++ // Linksys USB200M Rev 2 ++ USB_DEVICE (0x13b1, 0x0018), ++ .driver_info = (unsigned long) &ax88772_info, ++}, { ++ // 0Q0 cable ethernet ++ USB_DEVICE (0x1557, 0x7720), ++ .driver_info = (unsigned long) &ax88772_info, ++}, { ++ // DLink DUB-E100 H/W Ver B1 ++ USB_DEVICE (0x07d1, 0x3c05), ++ .driver_info = (unsigned long) &ax88772_info, ++}, { ++ // DLink DUB-E100 H/W Ver B1 Alternate ++ USB_DEVICE (0x2001, 0x3c05), ++ .driver_info = (unsigned long) &ax88772_info, ++}, { ++ // DLink DUB-E100 H/W Ver C1 ++ USB_DEVICE (0x2001, 0x1a02), ++ .driver_info = (unsigned long) &ax88772_info, ++}, { ++ // Linksys USB1000 ++ USB_DEVICE (0x1737, 0x0039), ++ .driver_info = (unsigned long) &ax88178_info, ++}, { ++ // IO-DATA ETG-US2 ++ USB_DEVICE (0x04bb, 0x0930), ++ .driver_info = (unsigned long) &ax88178_info, ++}, { ++ // Belkin F5D5055 ++ USB_DEVICE(0x050d, 0x5055), ++ .driver_info = (unsigned long) &ax88178_info, ++}, { ++ // Apple USB Ethernet Adapter ++ USB_DEVICE(0x05ac, 0x1402), ++ .driver_info = (unsigned long) &ax88772_info, ++}, { ++ // Cables-to-Go USB Ethernet Adapter ++ USB_DEVICE(0x0b95, 0x772a), ++ .driver_info = (unsigned long) &ax88772_info, ++}, { ++ // ABOCOM for pci ++ USB_DEVICE(0x14ea, 0xab11), ++ .driver_info = (unsigned long) &ax88178_info, ++}, { ++ // ASIX 88772a ++ USB_DEVICE(0x0db0, 0xa877), ++ .driver_info = (unsigned long) &ax88772_info, ++}, { ++ // Asus USB Ethernet Adapter ++ USB_DEVICE (0x0b95, 0x7e2b), ++ .driver_info = (unsigned long) &ax88772_info, ++}, { ++ /* ASIX 88172a demo board */ ++ USB_DEVICE(0x0b95, 0x172a), ++ .driver_info = (unsigned long) &ax88172a_info, ++}, { ++ /* ++ * USBLINK HG20F9 "USB 2.0 LAN" ++ * Appears to have gazumped Linksys's manufacturer ID but ++ * doesn't (yet) conflict with any known Linksys product. ++ */ ++ USB_DEVICE(0x066b, 0x20f9), ++ .driver_info = (unsigned long) &hg20f9_info, ++}, ++ { }, // END ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver asix_driver = { ++ .name = DRIVER_NAME, ++ .id_table = products, ++ .probe = usbnet_probe, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disconnect = usbnet_disconnect, ++ .supports_autosuspend = 1, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(asix_driver); ++ ++MODULE_AUTHOR("David Hollis"); ++MODULE_VERSION(DRIVER_VERSION); ++MODULE_DESCRIPTION("ASIX AX8817X based USB 2.0 Ethernet Devices"); ++MODULE_LICENSE("GPL"); ++ +diff -Naur backports-3.18.1-1.org/drivers/net/usb/asix.h backports-3.18.1-1/drivers/net/usb/asix.h +--- backports-3.18.1-1.org/drivers/net/usb/asix.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/asix.h 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,234 @@ ++/* ++ * ASIX AX8817X based USB 2.0 Ethernet Devices ++ * Copyright (C) 2003-2006 David Hollis dhollis@davehollis.com ++ * Copyright (C) 2005 Phil Chang pchang23@sbcglobal.net ++ * Copyright (C) 2006 James Painter jamie.painter@iname.com ++ * Copyright (c) 2002-2003 TiVo Inc. ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#ifndef _ASIX_H ++#define _ASIX_H ++ ++// #define DEBUG // error path messages, extra info ++// #define VERBOSE // more; success messages ++ ++#include <linux/module.h> ++#include <linux/kmod.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/crc32.h> ++#include <linux/usb/usbnet.h> ++#include <linux/slab.h> ++#include <linux/if_vlan.h> ++ ++#define DRIVER_VERSION "22-Dec-2011" ++#define DRIVER_NAME "asix" ++ ++/* ASIX AX8817X based USB 2.0 Ethernet Devices */ ++ ++#define AX_CMD_SET_SW_MII 0x06 ++#define AX_CMD_READ_MII_REG 0x07 ++#define AX_CMD_WRITE_MII_REG 0x08 ++#define AX_CMD_SET_HW_MII 0x0a ++#define AX_CMD_READ_EEPROM 0x0b ++#define AX_CMD_WRITE_EEPROM 0x0c ++#define AX_CMD_WRITE_ENABLE 0x0d ++#define AX_CMD_WRITE_DISABLE 0x0e ++#define AX_CMD_READ_RX_CTL 0x0f ++#define AX_CMD_WRITE_RX_CTL 0x10 ++#define AX_CMD_READ_IPG012 0x11 ++#define AX_CMD_WRITE_IPG0 0x12 ++#define AX_CMD_WRITE_IPG1 0x13 ++#define AX_CMD_READ_NODE_ID 0x13 ++#define AX_CMD_WRITE_NODE_ID 0x14 ++#define AX_CMD_WRITE_IPG2 0x14 ++#define AX_CMD_WRITE_MULTI_FILTER 0x16 ++#define AX88172_CMD_READ_NODE_ID 0x17 ++#define AX_CMD_READ_PHY_ID 0x19 ++#define AX_CMD_READ_MEDIUM_STATUS 0x1a ++#define AX_CMD_WRITE_MEDIUM_MODE 0x1b ++#define AX_CMD_READ_MONITOR_MODE 0x1c ++#define AX_CMD_WRITE_MONITOR_MODE 0x1d ++#define AX_CMD_READ_GPIOS 0x1e ++#define AX_CMD_WRITE_GPIOS 0x1f ++#define AX_CMD_SW_RESET 0x20 ++#define AX_CMD_SW_PHY_STATUS 0x21 ++#define AX_CMD_SW_PHY_SELECT 0x22 ++ ++#define AX_PHY_SELECT_MASK (BIT(3) | BIT(2)) ++#define AX_PHY_SELECT_INTERNAL 0 ++#define AX_PHY_SELECT_EXTERNAL BIT(2) ++ ++#define AX_MONITOR_MODE 0x01 ++#define AX_MONITOR_LINK 0x02 ++#define AX_MONITOR_MAGIC 0x04 ++#define AX_MONITOR_HSFS 0x10 ++ ++/* AX88172 Medium Status Register values */ ++#define AX88172_MEDIUM_FD 0x02 ++#define AX88172_MEDIUM_TX 0x04 ++#define AX88172_MEDIUM_FC 0x10 ++#define AX88172_MEDIUM_DEFAULT \ ++ ( AX88172_MEDIUM_FD | AX88172_MEDIUM_TX | AX88172_MEDIUM_FC ) ++ ++#define AX_MCAST_FILTER_SIZE 8 ++#define AX_MAX_MCAST 64 ++ ++#define AX_SWRESET_CLEAR 0x00 ++#define AX_SWRESET_RR 0x01 ++#define AX_SWRESET_RT 0x02 ++#define AX_SWRESET_PRTE 0x04 ++#define AX_SWRESET_PRL 0x08 ++#define AX_SWRESET_BZ 0x10 ++#define AX_SWRESET_IPRL 0x20 ++#define AX_SWRESET_IPPD 0x40 ++ ++#define AX88772_IPG0_DEFAULT 0x15 ++#define AX88772_IPG1_DEFAULT 0x0c ++#define AX88772_IPG2_DEFAULT 0x12 ++ ++/* AX88772 & AX88178 Medium Mode Register */ ++#define AX_MEDIUM_PF 0x0080 ++#define AX_MEDIUM_JFE 0x0040 ++#define AX_MEDIUM_TFC 0x0020 ++#define AX_MEDIUM_RFC 0x0010 ++#define AX_MEDIUM_ENCK 0x0008 ++#define AX_MEDIUM_AC 0x0004 ++#define AX_MEDIUM_FD 0x0002 ++#define AX_MEDIUM_GM 0x0001 ++#define AX_MEDIUM_SM 0x1000 ++#define AX_MEDIUM_SBP 0x0800 ++#define AX_MEDIUM_PS 0x0200 ++#define AX_MEDIUM_RE 0x0100 ++ ++#define AX88178_MEDIUM_DEFAULT \ ++ (AX_MEDIUM_PS | AX_MEDIUM_FD | AX_MEDIUM_AC | \ ++ AX_MEDIUM_RFC | AX_MEDIUM_TFC | AX_MEDIUM_JFE | \ ++ AX_MEDIUM_RE) ++ ++#define AX88772_MEDIUM_DEFAULT \ ++ (AX_MEDIUM_FD | AX_MEDIUM_RFC | \ ++ AX_MEDIUM_TFC | AX_MEDIUM_PS | \ ++ AX_MEDIUM_AC | AX_MEDIUM_RE) ++ ++/* AX88772 & AX88178 RX_CTL values */ ++#define AX_RX_CTL_SO 0x0080 ++#define AX_RX_CTL_AP 0x0020 ++#define AX_RX_CTL_AM 0x0010 ++#define AX_RX_CTL_AB 0x0008 ++#define AX_RX_CTL_SEP 0x0004 ++#define AX_RX_CTL_AMALL 0x0002 ++#define AX_RX_CTL_PRO 0x0001 ++#define AX_RX_CTL_MFB_2048 0x0000 ++#define AX_RX_CTL_MFB_4096 0x0100 ++#define AX_RX_CTL_MFB_8192 0x0200 ++#define AX_RX_CTL_MFB_16384 0x0300 ++ ++#define AX_DEFAULT_RX_CTL (AX_RX_CTL_SO | AX_RX_CTL_AB) ++ ++/* GPIO 0 .. 2 toggles */ ++#define AX_GPIO_GPO0EN 0x01 /* GPIO0 Output enable */ ++#define AX_GPIO_GPO_0 0x02 /* GPIO0 Output value */ ++#define AX_GPIO_GPO1EN 0x04 /* GPIO1 Output enable */ ++#define AX_GPIO_GPO_1 0x08 /* GPIO1 Output value */ ++#define AX_GPIO_GPO2EN 0x10 /* GPIO2 Output enable */ ++#define AX_GPIO_GPO_2 0x20 /* GPIO2 Output value */ ++#define AX_GPIO_RESERVED 0x40 /* Reserved */ ++#define AX_GPIO_RSE 0x80 /* Reload serial EEPROM */ ++ ++#define AX_EEPROM_MAGIC 0xdeadbeef ++#define AX_EEPROM_LEN 0x200 ++ ++/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ ++struct asix_data { ++ u8 multi_filter[AX_MCAST_FILTER_SIZE]; ++ u8 mac_addr[ETH_ALEN]; ++ u8 phymode; ++ u8 ledmode; ++ u8 res; ++}; ++ ++struct asix_rx_fixup_info { ++ struct sk_buff *ax_skb; ++ u32 header; ++ u16 size; ++ bool split_head; ++}; ++ ++struct asix_common_private { ++ struct asix_rx_fixup_info rx_fixup_info; ++}; ++ ++extern const struct driver_info ax88172a_info; ++ ++/* ASIX specific flags */ ++#define FLAG_EEPROM_MAC (1UL << 0) /* init device MAC from eeprom */ ++ ++int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data); ++ ++int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data); ++ ++void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, ++ u16 index, u16 size, void *data); ++ ++int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb, ++ struct asix_rx_fixup_info *rx); ++int asix_rx_fixup_common(struct usbnet *dev, struct sk_buff *skb); ++ ++struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, ++ gfp_t flags); ++ ++int asix_set_sw_mii(struct usbnet *dev); ++int asix_set_hw_mii(struct usbnet *dev); ++ ++int asix_read_phy_addr(struct usbnet *dev, int internal); ++int asix_get_phy_addr(struct usbnet *dev); ++ ++int asix_sw_reset(struct usbnet *dev, u8 flags); ++ ++u16 asix_read_rx_ctl(struct usbnet *dev); ++int asix_write_rx_ctl(struct usbnet *dev, u16 mode); ++ ++u16 asix_read_medium_status(struct usbnet *dev); ++int asix_write_medium_mode(struct usbnet *dev, u16 mode); ++ ++int asix_write_gpio(struct usbnet *dev, u16 value, int sleep); ++ ++void asix_set_multicast(struct net_device *net); ++ ++int asix_mdio_read(struct net_device *netdev, int phy_id, int loc); ++void asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val); ++ ++void asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo); ++int asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo); ++ ++int asix_get_eeprom_len(struct net_device *net); ++int asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, ++ u8 *data); ++int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, ++ u8 *data); ++ ++void asix_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info); ++ ++int asix_set_mac_address(struct net_device *net, void *p); ++ ++#endif /* _ASIX_H */ +diff -Naur backports-3.18.1-1.org/drivers/net/usb/ax88172a.c backports-3.18.1-1/drivers/net/usb/ax88172a.c +--- backports-3.18.1-1.org/drivers/net/usb/ax88172a.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/ax88172a.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,422 @@ ++/* ++ * ASIX AX88172A based USB 2.0 Ethernet Devices ++ * Copyright (C) 2012 OMICRON electronics GmbH ++ * ++ * Supports external PHYs via phylib. Based on the driver for the ++ * AX88772. Original copyrights follow: ++ * ++ * Copyright (C) 2003-2006 David Hollis dhollis@davehollis.com ++ * Copyright (C) 2005 Phil Chang pchang23@sbcglobal.net ++ * Copyright (C) 2006 James Painter jamie.painter@iname.com ++ * Copyright (c) 2002-2003 TiVo Inc. ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include "asix.h" ++#include <linux/phy.h> ++ ++struct ax88172a_private { ++ struct mii_bus *mdio; ++ struct phy_device *phydev; ++ char phy_name[20]; ++ u16 phy_addr; ++ u16 oldmode; ++ int use_embdphy; ++ struct asix_rx_fixup_info rx_fixup_info; ++}; ++ ++/* MDIO read and write wrappers for phylib */ ++static int asix_mdio_bus_read(struct mii_bus *bus, int phy_id, int regnum) ++{ ++ return asix_mdio_read(((struct usbnet *)bus->priv)->net, phy_id, ++ regnum); ++} ++ ++static int asix_mdio_bus_write(struct mii_bus *bus, int phy_id, int regnum, ++ u16 val) ++{ ++ asix_mdio_write(((struct usbnet *)bus->priv)->net, phy_id, regnum, val); ++ return 0; ++} ++ ++static int ax88172a_ioctl(struct net_device *net, struct ifreq *rq, int cmd) ++{ ++ if (!netif_running(net)) ++ return -EINVAL; ++ ++ if (!net->phydev) ++ return -ENODEV; ++ ++ return phy_mii_ioctl(net->phydev, rq, cmd); ++} ++ ++/* set MAC link settings according to information from phylib */ ++static void ax88172a_adjust_link(struct net_device *netdev) ++{ ++ struct phy_device *phydev = netdev->phydev; ++ struct usbnet *dev = netdev_priv(netdev); ++ struct ax88172a_private *priv = dev->driver_priv; ++ u16 mode = 0; ++ ++ if (phydev->link) { ++ mode = AX88772_MEDIUM_DEFAULT; ++ ++ if (phydev->duplex == DUPLEX_HALF) ++ mode &= ~AX_MEDIUM_FD; ++ ++ if (phydev->speed != SPEED_100) ++ mode &= ~AX_MEDIUM_PS; ++ } ++ ++ if (mode != priv->oldmode) { ++ asix_write_medium_mode(dev, mode); ++ priv->oldmode = mode; ++ netdev_dbg(netdev, "speed %u duplex %d, setting mode to 0x%04x\n", ++ phydev->speed, phydev->duplex, mode); ++ phy_print_status(phydev); ++ } ++} ++ ++static void ax88172a_status(struct usbnet *dev, struct urb *urb) ++{ ++ /* link changes are detected by polling the phy */ ++} ++ ++/* use phylib infrastructure */ ++static int ax88172a_init_mdio(struct usbnet *dev) ++{ ++ struct ax88172a_private *priv = dev->driver_priv; ++ int ret, i; ++ ++ priv->mdio = mdiobus_alloc(); ++ if (!priv->mdio) { ++ netdev_err(dev->net, "Could not allocate MDIO bus\n"); ++ return -ENOMEM; ++ } ++ ++ priv->mdio->priv = (void *)dev; ++ priv->mdio->read = &asix_mdio_bus_read; ++ priv->mdio->write = &asix_mdio_bus_write; ++ priv->mdio->name = "Asix MDIO Bus"; ++ /* mii bus name is usb-<usb bus number>-<usb device number> */ ++ snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "usb-%03d:%03d", ++ dev->udev->bus->busnum, dev->udev->devnum); ++ ++ priv->mdio->irq = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); ++ if (!priv->mdio->irq) { ++ ret = -ENOMEM; ++ goto mfree; ++ } ++ for (i = 0; i < PHY_MAX_ADDR; i++) ++ priv->mdio->irq[i] = PHY_POLL; ++ ++ ret = mdiobus_register(priv->mdio); ++ if (ret) { ++ netdev_err(dev->net, "Could not register MDIO bus\n"); ++ goto ifree; ++ } ++ ++ netdev_info(dev->net, "registered mdio bus %s\n", priv->mdio->id); ++ return 0; ++ ++ifree: ++ kfree(priv->mdio->irq); ++mfree: ++ mdiobus_free(priv->mdio); ++ return ret; ++} ++ ++static void ax88172a_remove_mdio(struct usbnet *dev) ++{ ++ struct ax88172a_private *priv = dev->driver_priv; ++ ++ netdev_info(dev->net, "deregistering mdio bus %s\n", priv->mdio->id); ++ mdiobus_unregister(priv->mdio); ++ kfree(priv->mdio->irq); ++ mdiobus_free(priv->mdio); ++} ++ ++static const struct net_device_ops ax88172a_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = usbnet_change_mtu, ++ .ndo_set_mac_address = asix_set_mac_address, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = ax88172a_ioctl, ++ .ndo_set_rx_mode = asix_set_multicast, ++}; ++ ++static int ax88172a_get_settings(struct net_device *net, ++ struct ethtool_cmd *cmd) ++{ ++ if (!net->phydev) ++ return -ENODEV; ++ ++ return phy_ethtool_gset(net->phydev, cmd); ++} ++ ++static int ax88172a_set_settings(struct net_device *net, ++ struct ethtool_cmd *cmd) ++{ ++ if (!net->phydev) ++ return -ENODEV; ++ ++ return phy_ethtool_sset(net->phydev, cmd); ++} ++ ++static int ax88172a_nway_reset(struct net_device *net) ++{ ++ if (!net->phydev) ++ return -ENODEV; ++ ++ return phy_start_aneg(net->phydev); ++} ++ ++static const struct ethtool_ops ax88172a_ethtool_ops = { ++ .get_drvinfo = asix_get_drvinfo, ++ .get_link = usbnet_get_link, ++ .get_msglevel = usbnet_get_msglevel, ++ .set_msglevel = usbnet_set_msglevel, ++ .get_wol = asix_get_wol, ++ .set_wol = asix_set_wol, ++ .get_eeprom_len = asix_get_eeprom_len, ++ .get_eeprom = asix_get_eeprom, ++ .set_eeprom = asix_set_eeprom, ++ .get_settings = ax88172a_get_settings, ++ .set_settings = ax88172a_set_settings, ++ .nway_reset = ax88172a_nway_reset, ++}; ++ ++static int ax88172a_reset_phy(struct usbnet *dev, int embd_phy) ++{ ++ int ret; ++ ++ ret = asix_sw_reset(dev, AX_SWRESET_IPPD); ++ if (ret < 0) ++ goto err; ++ ++ msleep(150); ++ ret = asix_sw_reset(dev, AX_SWRESET_CLEAR); ++ if (ret < 0) ++ goto err; ++ ++ msleep(150); ++ ++ ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_IPPD); ++ if (ret < 0) ++ goto err; ++ ++ return 0; ++ ++err: ++ return ret; ++} ++ ++ ++static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int ret; ++ u8 buf[ETH_ALEN]; ++ struct ax88172a_private *priv; ++ ++ usbnet_get_endpoints(dev, intf); ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ dev->driver_priv = priv; ++ ++ /* Get the MAC address */ ++ ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf); ++ if (ret < 0) { ++ netdev_err(dev->net, "Failed to read MAC address: %d\n", ret); ++ goto free; ++ } ++ memcpy(dev->net->dev_addr, buf, ETH_ALEN); ++ ++ dev->net->netdev_ops = &ax88172a_netdev_ops; ++ dev->net->ethtool_ops = &ax88172a_ethtool_ops; ++ ++ /* are we using the internal or the external phy? */ ++ ret = asix_read_cmd(dev, AX_CMD_SW_PHY_STATUS, 0, 0, 1, buf); ++ if (ret < 0) { ++ netdev_err(dev->net, "Failed to read software interface selection register: %d\n", ++ ret); ++ goto free; ++ } ++ ++ netdev_dbg(dev->net, "AX_CMD_SW_PHY_STATUS = 0x%02x\n", buf[0]); ++ switch (buf[0] & AX_PHY_SELECT_MASK) { ++ case AX_PHY_SELECT_INTERNAL: ++ netdev_dbg(dev->net, "use internal phy\n"); ++ priv->use_embdphy = 1; ++ break; ++ case AX_PHY_SELECT_EXTERNAL: ++ netdev_dbg(dev->net, "use external phy\n"); ++ priv->use_embdphy = 0; ++ break; ++ default: ++ netdev_err(dev->net, "Interface mode not supported by driver\n"); ++ ret = -ENOTSUPP; ++ goto free; ++ } ++ ++ priv->phy_addr = asix_read_phy_addr(dev, priv->use_embdphy); ++ ax88172a_reset_phy(dev, priv->use_embdphy); ++ ++ /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ ++ if (dev->driver_info->flags & FLAG_FRAMING_AX) { ++ /* hard_mtu is still the default - the device does not support ++ jumbo eth frames */ ++ dev->rx_urb_size = 2048; ++ } ++ ++ /* init MDIO bus */ ++ ret = ax88172a_init_mdio(dev); ++ if (ret) ++ goto free; ++ ++ return 0; ++ ++free: ++ kfree(priv); ++ return ret; ++} ++ ++static int ax88172a_stop(struct usbnet *dev) ++{ ++ struct ax88172a_private *priv = dev->driver_priv; ++ ++ netdev_dbg(dev->net, "Stopping interface\n"); ++ ++ if (priv->phydev) { ++ netdev_info(dev->net, "Disconnecting from phy %s\n", ++ priv->phy_name); ++ phy_stop(priv->phydev); ++ phy_disconnect(priv->phydev); ++ } ++ ++ return 0; ++} ++ ++static void ax88172a_unbind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ struct ax88172a_private *priv = dev->driver_priv; ++ ++ ax88172a_remove_mdio(dev); ++ kfree(priv); ++} ++ ++static int ax88172a_reset(struct usbnet *dev) ++{ ++ struct asix_data *data = (struct asix_data *)&dev->data; ++ struct ax88172a_private *priv = dev->driver_priv; ++ int ret; ++ u16 rx_ctl; ++ ++ ax88172a_reset_phy(dev, priv->use_embdphy); ++ ++ msleep(150); ++ rx_ctl = asix_read_rx_ctl(dev); ++ netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); ++ ret = asix_write_rx_ctl(dev, 0x0000); ++ if (ret < 0) ++ goto out; ++ ++ rx_ctl = asix_read_rx_ctl(dev); ++ netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); ++ ++ msleep(150); ++ ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, ++ AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, ++ AX88772_IPG2_DEFAULT, 0, NULL); ++ if (ret < 0) { ++ netdev_err(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); ++ goto out; ++ } ++ ++ /* Rewrite MAC address */ ++ memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); ++ ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, ++ data->mac_addr); ++ if (ret < 0) ++ goto out; ++ ++ /* Set RX_CTL to default values with 2k buffer, and enable cactus */ ++ ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); ++ if (ret < 0) ++ goto out; ++ ++ rx_ctl = asix_read_rx_ctl(dev); ++ netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", ++ rx_ctl); ++ ++ rx_ctl = asix_read_medium_status(dev); ++ netdev_dbg(dev->net, "Medium Status is 0x%04x after all initializations\n", ++ rx_ctl); ++ ++ /* Connect to PHY */ ++ snprintf(priv->phy_name, 20, PHY_ID_FMT, ++ priv->mdio->id, priv->phy_addr); ++ ++ priv->phydev = phy_connect(dev->net, priv->phy_name, ++ &ax88172a_adjust_link, ++ PHY_INTERFACE_MODE_MII); ++ if (IS_ERR(priv->phydev)) { ++ netdev_err(dev->net, "Could not connect to PHY device %s\n", ++ priv->phy_name); ++ ret = PTR_ERR(priv->phydev); ++ goto out; ++ } ++ ++ netdev_info(dev->net, "Connected to phy %s\n", priv->phy_name); ++ ++ /* During power-up, the AX88172A set the power down (BMCR_PDOWN) ++ * bit of the PHY. Bring the PHY up again. ++ */ ++ genphy_resume(priv->phydev); ++ phy_start(priv->phydev); ++ ++ return 0; ++ ++out: ++ return ret; ++ ++} ++ ++static int ax88172a_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ struct ax88172a_private *dp = dev->driver_priv; ++ struct asix_rx_fixup_info *rx = &dp->rx_fixup_info; ++ ++ return asix_rx_fixup_internal(dev, skb, rx); ++} ++ ++const struct driver_info ax88172a_info = { ++ .description = "ASIX AX88172A USB 2.0 Ethernet", ++ .bind = ax88172a_bind, ++ .reset = ax88172a_reset, ++ .stop = ax88172a_stop, ++ .unbind = ax88172a_unbind, ++ .status = ax88172a_status, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | ++ FLAG_MULTI_PACKET, ++ .rx_fixup = ax88172a_rx_fixup, ++ .tx_fixup = asix_tx_fixup, ++}; +diff -Naur backports-3.18.1-1.org/drivers/net/usb/ax88179_178a.c backports-3.18.1-1/drivers/net/usb/ax88179_178a.c +--- backports-3.18.1-1.org/drivers/net/usb/ax88179_178a.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/ax88179_178a.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,1756 @@ ++/* ++ * ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet Devices ++ * ++ * Copyright (C) 2011-2013 ASIX ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include <linux/module.h> ++#include <linux/etherdevice.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/crc32.h> ++#include <linux/usb/usbnet.h> ++#include <uapi/linux/mdio.h> ++#include <linux/mdio.h> ++ ++#define AX88179_PHY_ID 0x03 ++#define AX_EEPROM_LEN 0x100 ++#define AX88179_EEPROM_MAGIC 0x17900b95 ++#define AX_MCAST_FLTSIZE 8 ++#define AX_MAX_MCAST 64 ++#define AX_INT_PPLS_LINK ((u32)BIT(16)) ++#define AX_RXHDR_L4_TYPE_MASK 0x1c ++#define AX_RXHDR_L4_TYPE_UDP 4 ++#define AX_RXHDR_L4_TYPE_TCP 16 ++#define AX_RXHDR_L3CSUM_ERR 2 ++#define AX_RXHDR_L4CSUM_ERR 1 ++#define AX_RXHDR_CRC_ERR ((u32)BIT(29)) ++#define AX_RXHDR_DROP_ERR ((u32)BIT(31)) ++#define AX_ACCESS_MAC 0x01 ++#define AX_ACCESS_PHY 0x02 ++#define AX_ACCESS_EEPROM 0x04 ++#define AX_ACCESS_EFUS 0x05 ++#define AX_PAUSE_WATERLVL_HIGH 0x54 ++#define AX_PAUSE_WATERLVL_LOW 0x55 ++ ++#define PHYSICAL_LINK_STATUS 0x02 ++ #define AX_USB_SS 0x04 ++ #define AX_USB_HS 0x02 ++ ++#define GENERAL_STATUS 0x03 ++/* Check AX88179 version. UA1:Bit2 = 0, UA2:Bit2 = 1 */ ++ #define AX_SECLD 0x04 ++ ++#define AX_SROM_ADDR 0x07 ++#define AX_SROM_CMD 0x0a ++ #define EEP_RD 0x04 ++ #define EEP_BUSY 0x10 ++ ++#define AX_SROM_DATA_LOW 0x08 ++#define AX_SROM_DATA_HIGH 0x09 ++ ++#define AX_RX_CTL 0x0b ++ #define AX_RX_CTL_DROPCRCERR 0x0100 ++ #define AX_RX_CTL_IPE 0x0200 ++ #define AX_RX_CTL_START 0x0080 ++ #define AX_RX_CTL_AP 0x0020 ++ #define AX_RX_CTL_AM 0x0010 ++ #define AX_RX_CTL_AB 0x0008 ++ #define AX_RX_CTL_AMALL 0x0002 ++ #define AX_RX_CTL_PRO 0x0001 ++ #define AX_RX_CTL_STOP 0x0000 ++ ++#define AX_NODE_ID 0x10 ++#define AX_MULFLTARY 0x16 ++ ++#define AX_MEDIUM_STATUS_MODE 0x22 ++ #define AX_MEDIUM_GIGAMODE 0x01 ++ #define AX_MEDIUM_FULL_DUPLEX 0x02 ++ #define AX_MEDIUM_EN_125MHZ 0x08 ++ #define AX_MEDIUM_RXFLOW_CTRLEN 0x10 ++ #define AX_MEDIUM_TXFLOW_CTRLEN 0x20 ++ #define AX_MEDIUM_RECEIVE_EN 0x100 ++ #define AX_MEDIUM_PS 0x200 ++ #define AX_MEDIUM_JUMBO_EN 0x8040 ++ ++#define AX_MONITOR_MOD 0x24 ++ #define AX_MONITOR_MODE_RWLC 0x02 ++ #define AX_MONITOR_MODE_RWMP 0x04 ++ #define AX_MONITOR_MODE_PMEPOL 0x20 ++ #define AX_MONITOR_MODE_PMETYPE 0x40 ++ ++#define AX_GPIO_CTRL 0x25 ++ #define AX_GPIO_CTRL_GPIO3EN 0x80 ++ #define AX_GPIO_CTRL_GPIO2EN 0x40 ++ #define AX_GPIO_CTRL_GPIO1EN 0x20 ++ ++#define AX_PHYPWR_RSTCTL 0x26 ++ #define AX_PHYPWR_RSTCTL_BZ 0x0010 ++ #define AX_PHYPWR_RSTCTL_IPRL 0x0020 ++ #define AX_PHYPWR_RSTCTL_AT 0x1000 ++ ++#define AX_RX_BULKIN_QCTRL 0x2e ++#define AX_CLK_SELECT 0x33 ++ #define AX_CLK_SELECT_BCS 0x01 ++ #define AX_CLK_SELECT_ACS 0x02 ++ #define AX_CLK_SELECT_ULR 0x08 ++ ++#define AX_RXCOE_CTL 0x34 ++ #define AX_RXCOE_IP 0x01 ++ #define AX_RXCOE_TCP 0x02 ++ #define AX_RXCOE_UDP 0x04 ++ #define AX_RXCOE_TCPV6 0x20 ++ #define AX_RXCOE_UDPV6 0x40 ++ ++#define AX_TXCOE_CTL 0x35 ++ #define AX_TXCOE_IP 0x01 ++ #define AX_TXCOE_TCP 0x02 ++ #define AX_TXCOE_UDP 0x04 ++ #define AX_TXCOE_TCPV6 0x20 ++ #define AX_TXCOE_UDPV6 0x40 ++ ++#define AX_LEDCTRL 0x73 ++ ++#define GMII_PHY_PHYSR 0x11 ++ #define GMII_PHY_PHYSR_SMASK 0xc000 ++ #define GMII_PHY_PHYSR_GIGA 0x8000 ++ #define GMII_PHY_PHYSR_100 0x4000 ++ #define GMII_PHY_PHYSR_FULL 0x2000 ++ #define GMII_PHY_PHYSR_LINK 0x400 ++ ++#define GMII_LED_ACT 0x1a ++ #define GMII_LED_ACTIVE_MASK 0xff8f ++ #define GMII_LED0_ACTIVE BIT(4) ++ #define GMII_LED1_ACTIVE BIT(5) ++ #define GMII_LED2_ACTIVE BIT(6) ++ ++#define GMII_LED_LINK 0x1c ++ #define GMII_LED_LINK_MASK 0xf888 ++ #define GMII_LED0_LINK_10 BIT(0) ++ #define GMII_LED0_LINK_100 BIT(1) ++ #define GMII_LED0_LINK_1000 BIT(2) ++ #define GMII_LED1_LINK_10 BIT(4) ++ #define GMII_LED1_LINK_100 BIT(5) ++ #define GMII_LED1_LINK_1000 BIT(6) ++ #define GMII_LED2_LINK_10 BIT(8) ++ #define GMII_LED2_LINK_100 BIT(9) ++ #define GMII_LED2_LINK_1000 BIT(10) ++ #define LED0_ACTIVE BIT(0) ++ #define LED0_LINK_10 BIT(1) ++ #define LED0_LINK_100 BIT(2) ++ #define LED0_LINK_1000 BIT(3) ++ #define LED0_FD BIT(4) ++ #define LED0_USB3_MASK 0x001f ++ #define LED1_ACTIVE BIT(5) ++ #define LED1_LINK_10 BIT(6) ++ #define LED1_LINK_100 BIT(7) ++ #define LED1_LINK_1000 BIT(8) ++ #define LED1_FD BIT(9) ++ #define LED1_USB3_MASK 0x03e0 ++ #define LED2_ACTIVE BIT(10) ++ #define LED2_LINK_1000 BIT(13) ++ #define LED2_LINK_100 BIT(12) ++ #define LED2_LINK_10 BIT(11) ++ #define LED2_FD BIT(14) ++ #define LED_VALID BIT(15) ++ #define LED2_USB3_MASK 0x7c00 ++ ++#define GMII_PHYPAGE 0x1e ++#define GMII_PHY_PAGE_SELECT 0x1f ++ #define GMII_PHY_PGSEL_EXT 0x0007 ++ #define GMII_PHY_PGSEL_PAGE0 0x0000 ++ #define GMII_PHY_PGSEL_PAGE3 0x0003 ++ #define GMII_PHY_PGSEL_PAGE5 0x0005 ++ ++struct ax88179_data { ++ u8 eee_enabled; ++ u8 eee_active; ++ u16 rxctl; ++ u16 reserved; ++}; ++ ++struct ax88179_int_data { ++ __le32 intdata1; ++ __le32 intdata2; ++}; ++ ++static const struct { ++ unsigned char ctrl, timer_l, timer_h, size, ifg; ++} AX88179_BULKIN_SIZE[] = { ++ {7, 0x4f, 0, 0x12, 0xff}, ++ {7, 0x20, 3, 0x16, 0xff}, ++ {7, 0xae, 7, 0x18, 0xff}, ++ {7, 0xcc, 0x4c, 0x18, 8}, ++}; ++ ++static int __ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data, int in_pm) ++{ ++ int ret; ++ int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16); ++ ++ BUG_ON(!dev); ++ ++ if (!in_pm) ++ fn = usbnet_read_cmd; ++ else ++ fn = usbnet_read_cmd_nopm; ++ ++ ret = fn(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ value, index, data, size); ++ ++ if (unlikely(ret < 0)) ++ netdev_warn(dev->net, "Failed to read reg index 0x%04x: %d\n", ++ index, ret); ++ ++ return ret; ++} ++ ++static int __ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data, int in_pm) ++{ ++ int ret; ++ int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16); ++ ++ BUG_ON(!dev); ++ ++ if (!in_pm) ++ fn = usbnet_write_cmd; ++ else ++ fn = usbnet_write_cmd_nopm; ++ ++ ret = fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ value, index, data, size); ++ ++ if (unlikely(ret < 0)) ++ netdev_warn(dev->net, "Failed to write reg index 0x%04x: %d\n", ++ index, ret); ++ ++ return ret; ++} ++ ++static void ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, ++ u16 index, u16 size, void *data) ++{ ++ u16 buf; ++ ++ if (2 == size) { ++ buf = *((u16 *)data); ++ cpu_to_le16s(&buf); ++ usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | ++ USB_RECIP_DEVICE, value, index, &buf, ++ size); ++ } else { ++ usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | ++ USB_RECIP_DEVICE, value, index, data, ++ size); ++ } ++} ++ ++static int ax88179_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value, ++ u16 index, u16 size, void *data) ++{ ++ int ret; ++ ++ if (2 == size) { ++ u16 buf; ++ ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1); ++ le16_to_cpus(&buf); ++ *((u16 *)data) = buf; ++ } else if (4 == size) { ++ u32 buf; ++ ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1); ++ le32_to_cpus(&buf); ++ *((u32 *)data) = buf; ++ } else { ++ ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 1); ++ } ++ ++ return ret; ++} ++ ++static int ax88179_write_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value, ++ u16 index, u16 size, void *data) ++{ ++ int ret; ++ ++ if (2 == size) { ++ u16 buf; ++ buf = *((u16 *)data); ++ cpu_to_le16s(&buf); ++ ret = __ax88179_write_cmd(dev, cmd, value, index, ++ size, &buf, 1); ++ } else { ++ ret = __ax88179_write_cmd(dev, cmd, value, index, ++ size, data, 1); ++ } ++ ++ return ret; ++} ++ ++static int ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data) ++{ ++ int ret; ++ ++ if (2 == size) { ++ u16 buf; ++ ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0); ++ le16_to_cpus(&buf); ++ *((u16 *)data) = buf; ++ } else if (4 == size) { ++ u32 buf; ++ ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0); ++ le32_to_cpus(&buf); ++ *((u32 *)data) = buf; ++ } else { ++ ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 0); ++ } ++ ++ return ret; ++} ++ ++static int ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data) ++{ ++ int ret; ++ ++ if (2 == size) { ++ u16 buf; ++ buf = *((u16 *)data); ++ cpu_to_le16s(&buf); ++ ret = __ax88179_write_cmd(dev, cmd, value, index, ++ size, &buf, 0); ++ } else { ++ ret = __ax88179_write_cmd(dev, cmd, value, index, ++ size, data, 0); ++ } ++ ++ return ret; ++} ++ ++static void ax88179_status(struct usbnet *dev, struct urb *urb) ++{ ++ struct ax88179_int_data *event; ++ u32 link; ++ ++ if (urb->actual_length < 8) ++ return; ++ ++ event = urb->transfer_buffer; ++ le32_to_cpus((void *)&event->intdata1); ++ ++ link = (((__force u32)event->intdata1) & AX_INT_PPLS_LINK) >> 16; ++ ++ if (netif_carrier_ok(dev->net) != link) { ++ usbnet_link_change(dev, link, 1); ++ netdev_info(dev->net, "ax88179 - Link status is: %d\n", link); ++ } ++} ++ ++static int ax88179_mdio_read(struct net_device *netdev, int phy_id, int loc) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ u16 res; ++ ++ ax88179_read_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res); ++ return res; ++} ++ ++static void ax88179_mdio_write(struct net_device *netdev, int phy_id, int loc, ++ int val) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ u16 res = (u16) val; ++ ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res); ++} ++ ++static inline int ax88179_phy_mmd_indirect(struct usbnet *dev, u16 prtad, ++ u16 devad) ++{ ++ u16 tmp16; ++ int ret; ++ ++ tmp16 = devad; ++ ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ MII_MMD_CTRL, 2, &tmp16); ++ ++ tmp16 = prtad; ++ ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ MII_MMD_DATA, 2, &tmp16); ++ ++ tmp16 = devad | MII_MMD_CTRL_NOINCR; ++ ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ MII_MMD_CTRL, 2, &tmp16); ++ ++ return ret; ++} ++ ++static int ++ax88179_phy_read_mmd_indirect(struct usbnet *dev, u16 prtad, u16 devad) ++{ ++ int ret; ++ u16 tmp16; ++ ++ ax88179_phy_mmd_indirect(dev, prtad, devad); ++ ++ ret = ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ MII_MMD_DATA, 2, &tmp16); ++ if (ret < 0) ++ return ret; ++ ++ return tmp16; ++} ++ ++static int ++ax88179_phy_write_mmd_indirect(struct usbnet *dev, u16 prtad, u16 devad, ++ u16 data) ++{ ++ int ret; ++ ++ ax88179_phy_mmd_indirect(dev, prtad, devad); ++ ++ ret = ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ MII_MMD_DATA, 2, &data); ++ ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static int ax88179_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ u16 tmp16; ++ u8 tmp8; ++ ++ usbnet_suspend(intf, message); ++ ++ /* Disable RX path */ ++ ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, &tmp16); ++ tmp16 &= ~AX_MEDIUM_RECEIVE_EN; ++ ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, &tmp16); ++ ++ /* Force bulk-in zero length */ ++ ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, ++ 2, 2, &tmp16); ++ ++ tmp16 |= AX_PHYPWR_RSTCTL_BZ | AX_PHYPWR_RSTCTL_IPRL; ++ ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, ++ 2, 2, &tmp16); ++ ++ /* change clock */ ++ tmp8 = 0; ++ ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); ++ ++ /* Configure RX control register => stop operation */ ++ tmp16 = AX_RX_CTL_STOP; ++ ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16); ++ ++ return 0; ++} ++ ++/* This function is used to enable the autodetach function. */ ++/* This function is determined by offset 0x43 of EEPROM */ ++static int ax88179_auto_detach(struct usbnet *dev, int in_pm) ++{ ++ u16 tmp16; ++ u8 tmp8; ++ int (*fnr)(struct usbnet *, u8, u16, u16, u16, void *); ++ int (*fnw)(struct usbnet *, u8, u16, u16, u16, void *); ++ ++ if (!in_pm) { ++ fnr = ax88179_read_cmd; ++ fnw = ax88179_write_cmd; ++ } else { ++ fnr = ax88179_read_cmd_nopm; ++ fnw = ax88179_write_cmd_nopm; ++ } ++ ++ if (fnr(dev, AX_ACCESS_EEPROM, 0x43, 1, 2, &tmp16) < 0) ++ return 0; ++ ++ if ((tmp16 == 0xFFFF) || (!(tmp16 & 0x0100))) ++ return 0; ++ ++ /* Enable Auto Detach bit */ ++ tmp8 = 0; ++ fnr(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); ++ tmp8 |= AX_CLK_SELECT_ULR; ++ fnw(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); ++ ++ fnr(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16); ++ tmp16 |= AX_PHYPWR_RSTCTL_AT; ++ fnw(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16); ++ ++ return 0; ++} ++ ++static int ax88179_resume(struct usb_interface *intf) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ u16 tmp16; ++ u8 tmp8; ++ ++ usbnet_link_change(dev, 0, 0); ++ ++ /* Power up ethernet PHY */ ++ tmp16 = 0; ++ ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, ++ 2, 2, &tmp16); ++ udelay(1000); ++ ++ tmp16 = AX_PHYPWR_RSTCTL_IPRL; ++ ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, ++ 2, 2, &tmp16); ++ msleep(200); ++ ++ /* Ethernet PHY Auto Detach*/ ++ ax88179_auto_detach(dev, 1); ++ ++ /* Enable clock */ ++ ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); ++ tmp8 |= AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; ++ ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); ++ msleep(100); ++ ++ /* Configure RX control register => start operation */ ++ tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START | ++ AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; ++ ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16); ++ ++ return usbnet_resume(intf); ++} ++ ++static void ++ax88179_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ u8 opt; ++ ++ if (ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, ++ 1, 1, &opt) < 0) { ++ wolinfo->supported = 0; ++ wolinfo->wolopts = 0; ++ return; ++ } ++ ++ wolinfo->supported = WAKE_PHY | WAKE_MAGIC; ++ wolinfo->wolopts = 0; ++ if (opt & AX_MONITOR_MODE_RWLC) ++ wolinfo->wolopts |= WAKE_PHY; ++ if (opt & AX_MONITOR_MODE_RWMP) ++ wolinfo->wolopts |= WAKE_MAGIC; ++} ++ ++static int ++ax88179_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ u8 opt = 0; ++ ++ if (wolinfo->wolopts & WAKE_PHY) ++ opt |= AX_MONITOR_MODE_RWLC; ++ if (wolinfo->wolopts & WAKE_MAGIC) ++ opt |= AX_MONITOR_MODE_RWMP; ++ ++ if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, ++ 1, 1, &opt) < 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int ax88179_get_eeprom_len(struct net_device *net) ++{ ++ return AX_EEPROM_LEN; ++} ++ ++static int ++ax88179_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, ++ u8 *data) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ u16 *eeprom_buff; ++ int first_word, last_word; ++ int i, ret; ++ ++ if (eeprom->len == 0) ++ return -EINVAL; ++ ++ eeprom->magic = AX88179_EEPROM_MAGIC; ++ ++ first_word = eeprom->offset >> 1; ++ last_word = (eeprom->offset + eeprom->len - 1) >> 1; ++ eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), ++ GFP_KERNEL); ++ if (!eeprom_buff) ++ return -ENOMEM; ++ ++ /* ax88179/178A returns 2 bytes from eeprom on read */ ++ for (i = first_word; i <= last_word; i++) { ++ ret = __ax88179_read_cmd(dev, AX_ACCESS_EEPROM, i, 1, 2, ++ &eeprom_buff[i - first_word], ++ 0); ++ if (ret < 0) { ++ kfree(eeprom_buff); ++ return -EIO; ++ } ++ } ++ ++ memcpy(data, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); ++ kfree(eeprom_buff); ++ return 0; ++} ++ ++static int ax88179_get_settings(struct net_device *net, struct ethtool_cmd *cmd) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ return mii_ethtool_gset(&dev->mii, cmd); ++} ++ ++static int ax88179_set_settings(struct net_device *net, struct ethtool_cmd *cmd) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ return mii_ethtool_sset(&dev->mii, cmd); ++} ++ ++static int ++ax88179_ethtool_get_eee(struct usbnet *dev, struct ethtool_eee *data) ++{ ++ int val; ++ ++ /* Get Supported EEE */ ++ val = ax88179_phy_read_mmd_indirect(dev, MDIO_PCS_EEE_ABLE, ++ MDIO_MMD_PCS); ++ if (val < 0) ++ return val; ++ data->supported = mmd_eee_cap_to_ethtool_sup_t(val); ++ ++ /* Get advertisement EEE */ ++ val = ax88179_phy_read_mmd_indirect(dev, MDIO_AN_EEE_ADV, ++ MDIO_MMD_AN); ++ if (val < 0) ++ return val; ++ data->advertised = mmd_eee_adv_to_ethtool_adv_t(val); ++ ++ /* Get LP advertisement EEE */ ++ val = ax88179_phy_read_mmd_indirect(dev, MDIO_AN_EEE_LPABLE, ++ MDIO_MMD_AN); ++ if (val < 0) ++ return val; ++ data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val); ++ ++ return 0; ++} ++ ++static int ++ax88179_ethtool_set_eee(struct usbnet *dev, struct ethtool_eee *data) ++{ ++ u16 tmp16 = ethtool_adv_to_mmd_eee_adv_t(data->advertised); ++ ++ return ax88179_phy_write_mmd_indirect(dev, MDIO_AN_EEE_ADV, ++ MDIO_MMD_AN, tmp16); ++} ++ ++static int ax88179_chk_eee(struct usbnet *dev) ++{ ++ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; ++ struct ax88179_data *priv = (struct ax88179_data *)dev->data; ++ ++ mii_ethtool_gset(&dev->mii, &ecmd); ++ ++ if (ecmd.duplex & DUPLEX_FULL) { ++ int eee_lp, eee_cap, eee_adv; ++ u32 lp, cap, adv, supported = 0; ++ ++ eee_cap = ax88179_phy_read_mmd_indirect(dev, ++ MDIO_PCS_EEE_ABLE, ++ MDIO_MMD_PCS); ++ if (eee_cap < 0) { ++ priv->eee_active = 0; ++ return false; ++ } ++ ++ cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap); ++ if (!cap) { ++ priv->eee_active = 0; ++ return false; ++ } ++ ++ eee_lp = ax88179_phy_read_mmd_indirect(dev, ++ MDIO_AN_EEE_LPABLE, ++ MDIO_MMD_AN); ++ if (eee_lp < 0) { ++ priv->eee_active = 0; ++ return false; ++ } ++ ++ eee_adv = ax88179_phy_read_mmd_indirect(dev, ++ MDIO_AN_EEE_ADV, ++ MDIO_MMD_AN); ++ ++ if (eee_adv < 0) { ++ priv->eee_active = 0; ++ return false; ++ } ++ ++ adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv); ++ lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp); ++ supported = (ecmd.speed == SPEED_1000) ? ++ SUPPORTED_1000baseT_Full : ++ SUPPORTED_100baseT_Full; ++ ++ if (!(lp & adv & supported)) { ++ priv->eee_active = 0; ++ return false; ++ } ++ ++ priv->eee_active = 1; ++ return true; ++ } ++ ++ priv->eee_active = 0; ++ return false; ++} ++ ++static void ax88179_disable_eee(struct usbnet *dev) ++{ ++ u16 tmp16; ++ ++ tmp16 = GMII_PHY_PGSEL_PAGE3; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_PHY_PAGE_SELECT, 2, &tmp16); ++ ++ tmp16 = 0x3246; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ MII_PHYADDR, 2, &tmp16); ++ ++ tmp16 = GMII_PHY_PGSEL_PAGE0; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_PHY_PAGE_SELECT, 2, &tmp16); ++} ++ ++static void ax88179_enable_eee(struct usbnet *dev) ++{ ++ u16 tmp16; ++ ++ tmp16 = GMII_PHY_PGSEL_PAGE3; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_PHY_PAGE_SELECT, 2, &tmp16); ++ ++ tmp16 = 0x3247; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ MII_PHYADDR, 2, &tmp16); ++ ++ tmp16 = GMII_PHY_PGSEL_PAGE5; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_PHY_PAGE_SELECT, 2, &tmp16); ++ ++ tmp16 = 0x0680; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ MII_BMSR, 2, &tmp16); ++ ++ tmp16 = GMII_PHY_PGSEL_PAGE0; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_PHY_PAGE_SELECT, 2, &tmp16); ++} ++ ++static int ax88179_get_eee(struct net_device *net, struct ethtool_eee *edata) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct ax88179_data *priv = (struct ax88179_data *)dev->data; ++ ++ edata->eee_enabled = priv->eee_enabled; ++ edata->eee_active = priv->eee_active; ++ ++ return ax88179_ethtool_get_eee(dev, edata); ++} ++ ++static int ax88179_set_eee(struct net_device *net, struct ethtool_eee *edata) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct ax88179_data *priv = (struct ax88179_data *)dev->data; ++ int ret = -EOPNOTSUPP; ++ ++ priv->eee_enabled = edata->eee_enabled; ++ if (!priv->eee_enabled) { ++ ax88179_disable_eee(dev); ++ } else { ++ priv->eee_enabled = ax88179_chk_eee(dev); ++ if (!priv->eee_enabled) ++ return -EOPNOTSUPP; ++ ++ ax88179_enable_eee(dev); ++ } ++ ++ ret = ax88179_ethtool_set_eee(dev, edata); ++ if (ret) ++ return ret; ++ ++ mii_nway_restart(&dev->mii); ++ ++ usbnet_link_change(dev, 0, 0); ++ ++ return ret; ++} ++ ++static int ax88179_ioctl(struct net_device *net, struct ifreq *rq, int cmd) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); ++} ++ ++static const struct ethtool_ops ax88179_ethtool_ops = { ++ .get_link = ethtool_op_get_link, ++ .get_msglevel = usbnet_get_msglevel, ++ .set_msglevel = usbnet_set_msglevel, ++ .get_wol = ax88179_get_wol, ++ .set_wol = ax88179_set_wol, ++ .get_eeprom_len = ax88179_get_eeprom_len, ++ .get_eeprom = ax88179_get_eeprom, ++ .get_settings = ax88179_get_settings, ++ .set_settings = ax88179_set_settings, ++ .get_eee = ax88179_get_eee, ++ .set_eee = ax88179_set_eee, ++ .nway_reset = usbnet_nway_reset, ++}; ++ ++static void ax88179_set_multicast(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct ax88179_data *data = (struct ax88179_data *)dev->data; ++ u8 *m_filter = ((u8 *)dev->data) + 12; ++ ++ data->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_IPE); ++ ++ if (net->flags & IFF_PROMISC) { ++ data->rxctl |= AX_RX_CTL_PRO; ++ } else if (net->flags & IFF_ALLMULTI || ++ netdev_mc_count(net) > AX_MAX_MCAST) { ++ data->rxctl |= AX_RX_CTL_AMALL; ++ } else if (netdev_mc_empty(net)) { ++ /* just broadcast and directed */ ++ } else { ++ /* We use the 20 byte dev->data for our 8 byte filter buffer ++ * to avoid allocating memory that is tricky to free later ++ */ ++ u32 crc_bits; ++ struct netdev_hw_addr *ha; ++ ++ memset(m_filter, 0, AX_MCAST_FLTSIZE); ++ ++ netdev_for_each_mc_addr(ha, net) { ++ crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; ++ *(m_filter + (crc_bits >> 3)) |= (1 << (crc_bits & 7)); ++ } ++ ++ ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_MULFLTARY, ++ AX_MCAST_FLTSIZE, AX_MCAST_FLTSIZE, ++ m_filter); ++ ++ data->rxctl |= AX_RX_CTL_AM; ++ } ++ ++ ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_RX_CTL, ++ 2, 2, &data->rxctl); ++} ++ ++static int ++ax88179_set_features(struct net_device *net, netdev_features_t features) ++{ ++ u8 tmp; ++ struct usbnet *dev = netdev_priv(net); ++ netdev_features_t changed = net->features ^ features; ++ ++ if (changed & NETIF_F_IP_CSUM) { ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); ++ tmp ^= AX_TXCOE_TCP | AX_TXCOE_UDP; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); ++ } ++ ++ if (changed & NETIF_F_IPV6_CSUM) { ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); ++ tmp ^= AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); ++ } ++ ++ if (changed & NETIF_F_RXCSUM) { ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp); ++ tmp ^= AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | ++ AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp); ++ } ++ ++ return 0; ++} ++ ++static int ax88179_change_mtu(struct net_device *net, int new_mtu) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ u16 tmp16; ++ ++ if (new_mtu <= 0 || new_mtu > 4088) ++ return -EINVAL; ++ ++ net->mtu = new_mtu; ++ dev->hard_mtu = net->mtu + net->hard_header_len; ++ ++ if (net->mtu > 1500) { ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, &tmp16); ++ tmp16 |= AX_MEDIUM_JUMBO_EN; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, &tmp16); ++ } else { ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, &tmp16); ++ tmp16 &= ~AX_MEDIUM_JUMBO_EN; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, &tmp16); ++ } ++ ++ /* max qlen depend on hard_mtu and rx_urb_size */ ++ usbnet_update_max_qlen(dev); ++ ++ return 0; ++} ++ ++static int ax88179_set_mac_addr(struct net_device *net, void *p) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct sockaddr *addr = p; ++ int ret; ++ ++ if (netif_running(net)) ++ return -EBUSY; ++ if (!is_valid_ether_addr(addr->sa_data)) ++ return -EADDRNOTAVAIL; ++ ++ memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); ++ ++ /* Set the MAC address */ ++ ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ++ ETH_ALEN, net->dev_addr); ++ if (ret < 0) ++ return ret; ++ ++ return 0; ++} ++ ++static const struct net_device_ops ax88179_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = ax88179_change_mtu, ++ .ndo_set_mac_address = ax88179_set_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = ax88179_ioctl, ++ .ndo_set_rx_mode = ax88179_set_multicast, ++ .ndo_set_features = ax88179_set_features, ++}; ++ ++static int ax88179_check_eeprom(struct usbnet *dev) ++{ ++ u8 i, buf, eeprom[20]; ++ u16 csum, delay = HZ / 10; ++ unsigned long jtimeout; ++ ++ /* Read EEPROM content */ ++ for (i = 0; i < 6; i++) { ++ buf = i; ++ if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR, ++ 1, 1, &buf) < 0) ++ return -EINVAL; ++ ++ buf = EEP_RD; ++ if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, ++ 1, 1, &buf) < 0) ++ return -EINVAL; ++ ++ jtimeout = jiffies + delay; ++ do { ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, ++ 1, 1, &buf); ++ ++ if (time_after(jiffies, jtimeout)) ++ return -EINVAL; ++ ++ } while (buf & EEP_BUSY); ++ ++ __ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW, ++ 2, 2, &eeprom[i * 2], 0); ++ ++ if ((i == 0) && (eeprom[0] == 0xFF)) ++ return -EINVAL; ++ } ++ ++ csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9]; ++ csum = (csum >> 8) + (csum & 0xff); ++ if ((csum + eeprom[10]) != 0xff) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int ax88179_check_efuse(struct usbnet *dev, u16 *ledmode) ++{ ++ u8 i; ++ u8 efuse[64]; ++ u16 csum = 0; ++ ++ if (ax88179_read_cmd(dev, AX_ACCESS_EFUS, 0, 64, 64, efuse) < 0) ++ return -EINVAL; ++ ++ if (*efuse == 0xFF) ++ return -EINVAL; ++ ++ for (i = 0; i < 64; i++) ++ csum = csum + efuse[i]; ++ ++ while (csum > 255) ++ csum = (csum & 0x00FF) + ((csum >> 8) & 0x00FF); ++ ++ if (csum != 0xFF) ++ return -EINVAL; ++ ++ *ledmode = (efuse[51] << 8) | efuse[52]; ++ ++ return 0; ++} ++ ++static int ax88179_convert_old_led(struct usbnet *dev, u16 *ledvalue) ++{ ++ u16 led; ++ ++ /* Loaded the old eFuse LED Mode */ ++ if (ax88179_read_cmd(dev, AX_ACCESS_EEPROM, 0x3C, 1, 2, &led) < 0) ++ return -EINVAL; ++ ++ led >>= 8; ++ switch (led) { ++ case 0xFF: ++ led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 | ++ LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 | ++ LED2_LINK_100 | LED2_LINK_1000 | LED_VALID; ++ break; ++ case 0xFE: ++ led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 | LED_VALID; ++ break; ++ case 0xFD: ++ led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 | ++ LED2_LINK_10 | LED_VALID; ++ break; ++ case 0xFC: ++ led = LED0_ACTIVE | LED1_ACTIVE | LED1_LINK_1000 | LED2_ACTIVE | ++ LED2_LINK_100 | LED2_LINK_10 | LED_VALID; ++ break; ++ default: ++ led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 | ++ LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 | ++ LED2_LINK_100 | LED2_LINK_1000 | LED_VALID; ++ break; ++ } ++ ++ *ledvalue = led; ++ ++ return 0; ++} ++ ++static int ax88179_led_setting(struct usbnet *dev) ++{ ++ u8 ledfd, value = 0; ++ u16 tmp, ledact, ledlink, ledvalue = 0, delay = HZ / 10; ++ unsigned long jtimeout; ++ ++ /* Check AX88179 version. UA1 or UA2*/ ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, GENERAL_STATUS, 1, 1, &value); ++ ++ if (!(value & AX_SECLD)) { /* UA1 */ ++ value = AX_GPIO_CTRL_GPIO3EN | AX_GPIO_CTRL_GPIO2EN | ++ AX_GPIO_CTRL_GPIO1EN; ++ if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_GPIO_CTRL, ++ 1, 1, &value) < 0) ++ return -EINVAL; ++ } ++ ++ /* Check EEPROM */ ++ if (!ax88179_check_eeprom(dev)) { ++ value = 0x42; ++ if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR, ++ 1, 1, &value) < 0) ++ return -EINVAL; ++ ++ value = EEP_RD; ++ if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, ++ 1, 1, &value) < 0) ++ return -EINVAL; ++ ++ jtimeout = jiffies + delay; ++ do { ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, ++ 1, 1, &value); ++ ++ if (time_after(jiffies, jtimeout)) ++ return -EINVAL; ++ ++ } while (value & EEP_BUSY); ++ ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_HIGH, ++ 1, 1, &value); ++ ledvalue = (value << 8); ++ ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW, ++ 1, 1, &value); ++ ledvalue |= value; ++ ++ /* load internal ROM for defaule setting */ ++ if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0)) ++ ax88179_convert_old_led(dev, &ledvalue); ++ ++ } else if (!ax88179_check_efuse(dev, &ledvalue)) { ++ if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0)) ++ ax88179_convert_old_led(dev, &ledvalue); ++ } else { ++ ax88179_convert_old_led(dev, &ledvalue); ++ } ++ ++ tmp = GMII_PHY_PGSEL_EXT; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_PHY_PAGE_SELECT, 2, &tmp); ++ ++ tmp = 0x2c; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_PHYPAGE, 2, &tmp); ++ ++ ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_LED_ACT, 2, &ledact); ++ ++ ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_LED_LINK, 2, &ledlink); ++ ++ ledact &= GMII_LED_ACTIVE_MASK; ++ ledlink &= GMII_LED_LINK_MASK; ++ ++ if (ledvalue & LED0_ACTIVE) ++ ledact |= GMII_LED0_ACTIVE; ++ ++ if (ledvalue & LED1_ACTIVE) ++ ledact |= GMII_LED1_ACTIVE; ++ ++ if (ledvalue & LED2_ACTIVE) ++ ledact |= GMII_LED2_ACTIVE; ++ ++ if (ledvalue & LED0_LINK_10) ++ ledlink |= GMII_LED0_LINK_10; ++ ++ if (ledvalue & LED1_LINK_10) ++ ledlink |= GMII_LED1_LINK_10; ++ ++ if (ledvalue & LED2_LINK_10) ++ ledlink |= GMII_LED2_LINK_10; ++ ++ if (ledvalue & LED0_LINK_100) ++ ledlink |= GMII_LED0_LINK_100; ++ ++ if (ledvalue & LED1_LINK_100) ++ ledlink |= GMII_LED1_LINK_100; ++ ++ if (ledvalue & LED2_LINK_100) ++ ledlink |= GMII_LED2_LINK_100; ++ ++ if (ledvalue & LED0_LINK_1000) ++ ledlink |= GMII_LED0_LINK_1000; ++ ++ if (ledvalue & LED1_LINK_1000) ++ ledlink |= GMII_LED1_LINK_1000; ++ ++ if (ledvalue & LED2_LINK_1000) ++ ledlink |= GMII_LED2_LINK_1000; ++ ++ tmp = ledact; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_LED_ACT, 2, &tmp); ++ ++ tmp = ledlink; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_LED_LINK, 2, &tmp); ++ ++ tmp = GMII_PHY_PGSEL_PAGE0; ++ ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_PHY_PAGE_SELECT, 2, &tmp); ++ ++ /* LED full duplex setting */ ++ ledfd = 0; ++ if (ledvalue & LED0_FD) ++ ledfd |= 0x01; ++ else if ((ledvalue & LED0_USB3_MASK) == 0) ++ ledfd |= 0x02; ++ ++ if (ledvalue & LED1_FD) ++ ledfd |= 0x04; ++ else if ((ledvalue & LED1_USB3_MASK) == 0) ++ ledfd |= 0x08; ++ ++ if (ledvalue & LED2_FD) ++ ledfd |= 0x10; ++ else if ((ledvalue & LED2_USB3_MASK) == 0) ++ ledfd |= 0x20; ++ ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_LEDCTRL, 1, 1, &ledfd); ++ ++ return 0; ++} ++ ++static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ u8 buf[5]; ++ u16 *tmp16; ++ u8 *tmp; ++ struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data; ++ struct ethtool_eee eee_data; ++ ++ usbnet_get_endpoints(dev, intf); ++ ++ tmp16 = (u16 *)buf; ++ tmp = (u8 *)buf; ++ ++ memset(ax179_data, 0, sizeof(*ax179_data)); ++ ++ /* Power up ethernet PHY */ ++ *tmp16 = 0; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); ++ *tmp16 = AX_PHYPWR_RSTCTL_IPRL; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); ++ msleep(200); ++ ++ *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp); ++ msleep(100); ++ ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ++ ETH_ALEN, dev->net->dev_addr); ++ memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN); ++ ++ /* RX bulk configuration */ ++ memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); ++ ++ dev->rx_urb_size = 1024 * 20; ++ ++ *tmp = 0x34; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); ++ ++ *tmp = 0x52; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, ++ 1, 1, tmp); ++ ++ dev->net->netdev_ops = &ax88179_netdev_ops; ++ dev->net->ethtool_ops = &ax88179_ethtool_ops; ++ dev->net->needed_headroom = 8; ++ ++ /* Initialize MII structure */ ++ dev->mii.dev = dev->net; ++ dev->mii.mdio_read = ax88179_mdio_read; ++ dev->mii.mdio_write = ax88179_mdio_write; ++ dev->mii.phy_id_mask = 0xff; ++ dev->mii.reg_num_mask = 0xff; ++ dev->mii.phy_id = 0x03; ++ dev->mii.supports_gmii = 1; ++ ++ dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | ++ NETIF_F_RXCSUM; ++ ++ dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | ++ NETIF_F_RXCSUM; ++ ++ /* Enable checksum offload */ ++ *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | ++ AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp); ++ ++ *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP | ++ AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp); ++ ++ /* Configure RX control register => start operation */ ++ *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START | ++ AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16); ++ ++ *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL | ++ AX_MONITOR_MODE_RWMP; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp); ++ ++ /* Configure default medium type => giga */ ++ *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | ++ AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX | ++ AX_MEDIUM_GIGAMODE; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, tmp16); ++ ++ ax88179_led_setting(dev); ++ ++ ax179_data->eee_enabled = 0; ++ ax179_data->eee_active = 0; ++ ++ ax88179_disable_eee(dev); ++ ++ ax88179_ethtool_get_eee(dev, &eee_data); ++ eee_data.advertised = 0; ++ ax88179_ethtool_set_eee(dev, &eee_data); ++ ++ /* Restart autoneg */ ++ mii_nway_restart(&dev->mii); ++ ++ usbnet_link_change(dev, 0, 0); ++ ++ return 0; ++} ++ ++static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ u16 tmp16; ++ ++ /* Configure RX control register => stop operation */ ++ tmp16 = AX_RX_CTL_STOP; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16); ++ ++ tmp16 = 0; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp16); ++ ++ /* Power down ethernet PHY */ ++ tmp16 = 0; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16); ++} ++ ++static void ++ax88179_rx_checksum(struct sk_buff *skb, u32 *pkt_hdr) ++{ ++ skb->ip_summed = CHECKSUM_NONE; ++ ++ /* checksum error bit is set */ ++ if ((*pkt_hdr & AX_RXHDR_L3CSUM_ERR) || ++ (*pkt_hdr & AX_RXHDR_L4CSUM_ERR)) ++ return; ++ ++ /* It must be a TCP or UDP packet with a valid checksum */ ++ if (((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_TCP) || ++ ((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_UDP)) ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++} ++ ++static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ struct sk_buff *ax_skb; ++ int pkt_cnt; ++ u32 rx_hdr; ++ u16 hdr_off; ++ u32 *pkt_hdr; ++ ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ ++ skb_trim(skb, skb->len - 4); ++ memcpy(&rx_hdr, skb_tail_pointer(skb), 4); ++ le32_to_cpus(&rx_hdr); ++ ++ pkt_cnt = (u16)rx_hdr; ++ hdr_off = (u16)(rx_hdr >> 16); ++ pkt_hdr = (u32 *)(skb->data + hdr_off); ++ ++ while (pkt_cnt--) { ++ u16 pkt_len; ++ ++ le32_to_cpus(pkt_hdr); ++ pkt_len = (*pkt_hdr >> 16) & 0x1fff; ++ ++ /* Check CRC or runt packet */ ++ if ((*pkt_hdr & AX_RXHDR_CRC_ERR) || ++ (*pkt_hdr & AX_RXHDR_DROP_ERR)) { ++ skb_pull(skb, (pkt_len + 7) & 0xFFF8); ++ pkt_hdr++; ++ continue; ++ } ++ ++ if (pkt_cnt == 0) { ++ /* Skip IP alignment psudo header */ ++ skb_pull(skb, 2); ++ skb->len = pkt_len; ++ skb_set_tail_pointer(skb, pkt_len); ++ skb->truesize = pkt_len + sizeof(struct sk_buff); ++ ax88179_rx_checksum(skb, pkt_hdr); ++ return 1; ++ } ++ ++ ax_skb = skb_clone(skb, GFP_ATOMIC); ++ if (ax_skb) { ++ ax_skb->len = pkt_len; ++ ax_skb->data = skb->data + 2; ++ skb_set_tail_pointer(ax_skb, pkt_len); ++ ax_skb->truesize = pkt_len + sizeof(struct sk_buff); ++ ax88179_rx_checksum(ax_skb, pkt_hdr); ++ usbnet_skb_return(dev, ax_skb); ++ } else { ++ return 0; ++ } ++ ++ skb_pull(skb, (pkt_len + 7) & 0xFFF8); ++ pkt_hdr++; ++ } ++ return 1; ++} ++ ++static struct sk_buff * ++ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) ++{ ++ u32 tx_hdr1, tx_hdr2; ++ int frame_size = dev->maxpacket; ++ int mss = skb_shinfo(skb)->gso_size; ++ int headroom; ++ ++ tx_hdr1 = skb->len; ++ tx_hdr2 = mss; ++ if (((skb->len + 8) % frame_size) == 0) ++ tx_hdr2 |= 0x80008000; /* Enable padding */ ++ ++ headroom = skb_headroom(skb) - 8; ++ ++ if ((skb_header_cloned(skb) || headroom < 0) && ++ pskb_expand_head(skb, headroom < 0 ? 8 : 0, 0, GFP_ATOMIC)) { ++ dev_kfree_skb_any(skb); ++ return NULL; ++ } ++ ++ skb_push(skb, 4); ++ cpu_to_le32s(&tx_hdr2); ++ skb_copy_to_linear_data(skb, &tx_hdr2, 4); ++ ++ skb_push(skb, 4); ++ cpu_to_le32s(&tx_hdr1); ++ skb_copy_to_linear_data(skb, &tx_hdr1, 4); ++ ++ return skb; ++} ++ ++static int ax88179_link_reset(struct usbnet *dev) ++{ ++ struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data; ++ u8 tmp[5], link_sts; ++ u16 mode, tmp16, delay = HZ / 10; ++ u32 tmp32 = 0x40000000; ++ unsigned long jtimeout; ++ ++ jtimeout = jiffies + delay; ++ while (tmp32 & 0x40000000) { ++ mode = 0; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &mode); ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, ++ &ax179_data->rxctl); ++ ++ /*link up, check the usb device control TX FIFO full or empty*/ ++ ax88179_read_cmd(dev, 0x81, 0x8c, 0, 4, &tmp32); ++ ++ if (time_after(jiffies, jtimeout)) ++ return 0; ++ } ++ ++ mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | ++ AX_MEDIUM_RXFLOW_CTRLEN; ++ ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS, ++ 1, 1, &link_sts); ++ ++ ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, ++ GMII_PHY_PHYSR, 2, &tmp16); ++ ++ if (!(tmp16 & GMII_PHY_PHYSR_LINK)) { ++ return 0; ++ } else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) { ++ mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ; ++ if (dev->net->mtu > 1500) ++ mode |= AX_MEDIUM_JUMBO_EN; ++ ++ if (link_sts & AX_USB_SS) ++ memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); ++ else if (link_sts & AX_USB_HS) ++ memcpy(tmp, &AX88179_BULKIN_SIZE[1], 5); ++ else ++ memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5); ++ } else if (GMII_PHY_PHYSR_100 == (tmp16 & GMII_PHY_PHYSR_SMASK)) { ++ mode |= AX_MEDIUM_PS; ++ ++ if (link_sts & (AX_USB_SS | AX_USB_HS)) ++ memcpy(tmp, &AX88179_BULKIN_SIZE[2], 5); ++ else ++ memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5); ++ } else { ++ memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5); ++ } ++ ++ /* RX bulk configuration */ ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); ++ ++ dev->rx_urb_size = (1024 * (tmp[3] + 2)); ++ ++ if (tmp16 & GMII_PHY_PHYSR_FULL) ++ mode |= AX_MEDIUM_FULL_DUPLEX; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, &mode); ++ ++ ax179_data->eee_enabled = ax88179_chk_eee(dev); ++ ++ netif_carrier_on(dev->net); ++ ++ return 0; ++} ++ ++static int ax88179_reset(struct usbnet *dev) ++{ ++ u8 buf[5]; ++ u16 *tmp16; ++ u8 *tmp; ++ struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data; ++ struct ethtool_eee eee_data; ++ ++ tmp16 = (u16 *)buf; ++ tmp = (u8 *)buf; ++ ++ /* Power up ethernet PHY */ ++ *tmp16 = 0; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); ++ ++ *tmp16 = AX_PHYPWR_RSTCTL_IPRL; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); ++ msleep(200); ++ ++ *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp); ++ msleep(100); ++ ++ /* Ethernet PHY Auto Detach*/ ++ ax88179_auto_detach(dev, 0); ++ ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN, ++ dev->net->dev_addr); ++ memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN); ++ ++ /* RX bulk configuration */ ++ memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); ++ ++ dev->rx_urb_size = 1024 * 20; ++ ++ *tmp = 0x34; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); ++ ++ *tmp = 0x52; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, ++ 1, 1, tmp); ++ ++ dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | ++ NETIF_F_RXCSUM; ++ ++ dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | ++ NETIF_F_RXCSUM; ++ ++ /* Enable checksum offload */ ++ *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | ++ AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp); ++ ++ *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP | ++ AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp); ++ ++ /* Configure RX control register => start operation */ ++ *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START | ++ AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16); ++ ++ *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL | ++ AX_MONITOR_MODE_RWMP; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp); ++ ++ /* Configure default medium type => giga */ ++ *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | ++ AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX | ++ AX_MEDIUM_GIGAMODE; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, tmp16); ++ ++ ax88179_led_setting(dev); ++ ++ ax179_data->eee_enabled = 0; ++ ax179_data->eee_active = 0; ++ ++ ax88179_disable_eee(dev); ++ ++ ax88179_ethtool_get_eee(dev, &eee_data); ++ eee_data.advertised = 0; ++ ax88179_ethtool_set_eee(dev, &eee_data); ++ ++ /* Restart autoneg */ ++ mii_nway_restart(&dev->mii); ++ ++ usbnet_link_change(dev, 0, 0); ++ ++ return 0; ++} ++ ++static int ax88179_stop(struct usbnet *dev) ++{ ++ u16 tmp16; ++ ++ ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, &tmp16); ++ tmp16 &= ~AX_MEDIUM_RECEIVE_EN; ++ ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, ++ 2, 2, &tmp16); ++ ++ return 0; ++} ++ ++static const struct driver_info ax88179_info = { ++ .description = "ASIX AX88179 USB 3.0 Gigabit Ethernet", ++ .bind = ax88179_bind, ++ .unbind = ax88179_unbind, ++ .status = ax88179_status, ++ .link_reset = ax88179_link_reset, ++ .reset = ax88179_reset, ++ .stop = ax88179_stop, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX, ++ .rx_fixup = ax88179_rx_fixup, ++ .tx_fixup = ax88179_tx_fixup, ++}; ++ ++static const struct driver_info ax88178a_info = { ++ .description = "ASIX AX88178A USB 2.0 Gigabit Ethernet", ++ .bind = ax88179_bind, ++ .unbind = ax88179_unbind, ++ .status = ax88179_status, ++ .link_reset = ax88179_link_reset, ++ .reset = ax88179_reset, ++ .stop = ax88179_stop, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX, ++ .rx_fixup = ax88179_rx_fixup, ++ .tx_fixup = ax88179_tx_fixup, ++}; ++ ++static const struct driver_info dlink_dub1312_info = { ++ .description = "D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter", ++ .bind = ax88179_bind, ++ .unbind = ax88179_unbind, ++ .status = ax88179_status, ++ .link_reset = ax88179_link_reset, ++ .reset = ax88179_reset, ++ .stop = ax88179_stop, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX, ++ .rx_fixup = ax88179_rx_fixup, ++ .tx_fixup = ax88179_tx_fixup, ++}; ++ ++static const struct driver_info sitecom_info = { ++ .description = "Sitecom USB 3.0 to Gigabit Adapter", ++ .bind = ax88179_bind, ++ .unbind = ax88179_unbind, ++ .status = ax88179_status, ++ .link_reset = ax88179_link_reset, ++ .reset = ax88179_reset, ++ .stop = ax88179_stop, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX, ++ .rx_fixup = ax88179_rx_fixup, ++ .tx_fixup = ax88179_tx_fixup, ++}; ++ ++static const struct driver_info samsung_info = { ++ .description = "Samsung USB Ethernet Adapter", ++ .bind = ax88179_bind, ++ .unbind = ax88179_unbind, ++ .status = ax88179_status, ++ .link_reset = ax88179_link_reset, ++ .reset = ax88179_reset, ++ .stop = ax88179_stop, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX, ++ .rx_fixup = ax88179_rx_fixup, ++ .tx_fixup = ax88179_tx_fixup, ++}; ++ ++static const struct driver_info lenovo_info = { ++ .description = "Lenovo OneLinkDock Gigabit LAN", ++ .bind = ax88179_bind, ++ .unbind = ax88179_unbind, ++ .status = ax88179_status, ++ .link_reset = ax88179_link_reset, ++ .reset = ax88179_reset, ++ .stop = ax88179_stop, ++ .flags = FLAG_ETHER | FLAG_FRAMING_AX, ++ .rx_fixup = ax88179_rx_fixup, ++ .tx_fixup = ax88179_tx_fixup, ++}; ++ ++static const struct usb_device_id products[] = { ++{ ++ /* ASIX AX88179 10/100/1000 */ ++ USB_DEVICE(0x0b95, 0x1790), ++ .driver_info = (unsigned long)&ax88179_info, ++}, { ++ /* ASIX AX88178A 10/100/1000 */ ++ USB_DEVICE(0x0b95, 0x178a), ++ .driver_info = (unsigned long)&ax88178a_info, ++}, { ++ /* D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter */ ++ USB_DEVICE(0x2001, 0x4a00), ++ .driver_info = (unsigned long)&dlink_dub1312_info, ++}, { ++ /* Sitecom USB 3.0 to Gigabit Adapter */ ++ USB_DEVICE(0x0df6, 0x0072), ++ .driver_info = (unsigned long)&sitecom_info, ++}, { ++ /* Samsung USB Ethernet Adapter */ ++ USB_DEVICE(0x04e8, 0xa100), ++ .driver_info = (unsigned long)&samsung_info, ++}, { ++ /* Lenovo OneLinkDock Gigabit LAN */ ++ USB_DEVICE(0x17ef, 0x304b), ++ .driver_info = (unsigned long)&lenovo_info, ++}, ++ { }, ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver ax88179_178a_driver = { ++ .name = "ax88179_178a", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .suspend = ax88179_suspend, ++ .resume = ax88179_resume, ++ .reset_resume = ax88179_resume, ++ .disconnect = usbnet_disconnect, ++ .supports_autosuspend = 1, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(ax88179_178a_driver); ++ ++MODULE_DESCRIPTION("ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/catc.c backports-3.18.1-1/drivers/net/usb/catc.c +--- backports-3.18.1-1.org/drivers/net/usb/catc.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/catc.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,965 @@ ++/* ++ * Copyright (c) 2001 Vojtech Pavlik ++ * ++ * CATC EL1210A NetMate USB Ethernet driver ++ * ++ * Sponsored by SuSE ++ * ++ * Based on the work of ++ * Donald Becker ++ * ++ * Old chipset support added by Simon Evans spse@secret.org.uk 2002 ++ * - adds support for Belkin F5U011 ++ */ ++ ++/* ++ * 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 http://www.gnu.org/licenses/. ++ * ++ * Should you need to contact me, the author, you can do so either by ++ * e-mail - mail your message to vojtech@suse.cz, or by paper mail: ++ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/string.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/skbuff.h> ++#include <linux/spinlock.h> ++#include <linux/ethtool.h> ++#include <linux/crc32.h> ++#include <linux/bitops.h> ++#include <linux/gfp.h> ++#include <asm/uaccess.h> ++ ++#undef DEBUG ++ ++#include <linux/usb.h> ++ ++/* ++ * Version information. ++ */ ++ ++#define DRIVER_VERSION "v2.8" ++#define DRIVER_AUTHOR "Vojtech Pavlik vojtech@suse.cz" ++#define DRIVER_DESC "CATC EL1210A NetMate USB Ethernet driver" ++#define SHORT_DRIVER_DESC "EL1210A NetMate USB Ethernet" ++ ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE("GPL"); ++ ++static const char driver_name[] = "catc"; ++ ++/* ++ * Some defines. ++ */ ++ ++#define STATS_UPDATE (HZ) /* Time between stats updates */ ++#define TX_TIMEOUT (5*HZ) /* Max time the queue can be stopped */ ++#define PKT_SZ 1536 /* Max Ethernet packet size */ ++#define RX_MAX_BURST 15 /* Max packets per rx buffer (> 0, < 16) */ ++#define TX_MAX_BURST 15 /* Max full sized packets per tx buffer (> 0) */ ++#define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */ ++#define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */ ++ ++/* ++ * Control requests. ++ */ ++ ++enum control_requests { ++ ReadMem = 0xf1, ++ GetMac = 0xf2, ++ Reset = 0xf4, ++ SetMac = 0xf5, ++ SetRxMode = 0xf5, /* F5U011 only */ ++ WriteROM = 0xf8, ++ SetReg = 0xfa, ++ GetReg = 0xfb, ++ WriteMem = 0xfc, ++ ReadROM = 0xfd, ++}; ++ ++/* ++ * Registers. ++ */ ++ ++enum register_offsets { ++ TxBufCount = 0x20, ++ RxBufCount = 0x21, ++ OpModes = 0x22, ++ TxQed = 0x23, ++ RxQed = 0x24, ++ MaxBurst = 0x25, ++ RxUnit = 0x60, ++ EthStatus = 0x61, ++ StationAddr0 = 0x67, ++ EthStats = 0x69, ++ LEDCtrl = 0x81, ++}; ++ ++enum eth_stats { ++ TxSingleColl = 0x00, ++ TxMultiColl = 0x02, ++ TxExcessColl = 0x04, ++ RxFramErr = 0x06, ++}; ++ ++enum op_mode_bits { ++ Op3MemWaits = 0x03, ++ OpLenInclude = 0x08, ++ OpRxMerge = 0x10, ++ OpTxMerge = 0x20, ++ OpWin95bugfix = 0x40, ++ OpLoopback = 0x80, ++}; ++ ++enum rx_filter_bits { ++ RxEnable = 0x01, ++ RxPolarity = 0x02, ++ RxForceOK = 0x04, ++ RxMultiCast = 0x08, ++ RxPromisc = 0x10, ++ AltRxPromisc = 0x20, /* F5U011 uses different bit */ ++}; ++ ++enum led_values { ++ LEDFast = 0x01, ++ LEDSlow = 0x02, ++ LEDFlash = 0x03, ++ LEDPulse = 0x04, ++ LEDLink = 0x08, ++}; ++ ++enum link_status { ++ LinkNoChange = 0, ++ LinkGood = 1, ++ LinkBad = 2 ++}; ++ ++/* ++ * The catc struct. ++ */ ++ ++#define CTRL_RUNNING 0 ++#define RX_RUNNING 1 ++#define TX_RUNNING 2 ++ ++struct catc { ++ struct net_device *netdev; ++ struct usb_device *usbdev; ++ ++ unsigned long flags; ++ ++ unsigned int tx_ptr, tx_idx; ++ unsigned int ctrl_head, ctrl_tail; ++ spinlock_t tx_lock, ctrl_lock; ++ ++ u8 tx_buf[2][TX_MAX_BURST * (PKT_SZ + 2)]; ++ u8 rx_buf[RX_MAX_BURST * (PKT_SZ + 2)]; ++ u8 irq_buf[2]; ++ u8 ctrl_buf[64]; ++ struct usb_ctrlrequest ctrl_dr; ++ ++ struct timer_list timer; ++ u8 stats_buf[8]; ++ u16 stats_vals[4]; ++ unsigned long last_stats; ++ ++ u8 multicast[64]; ++ ++ struct ctrl_queue { ++ u8 dir; ++ u8 request; ++ u16 value; ++ u16 index; ++ void *buf; ++ int len; ++ void (*callback)(struct catc *catc, struct ctrl_queue *q); ++ } ctrl_queue[CTRL_QUEUE]; ++ ++ struct urb *tx_urb, *rx_urb, *irq_urb, *ctrl_urb; ++ ++ u8 is_f5u011; /* Set if device is an F5U011 */ ++ u8 rxmode[2]; /* Used for F5U011 */ ++ atomic_t recq_sz; /* Used for F5U011 - counter of waiting rx packets */ ++}; ++ ++/* ++ * Useful macros. ++ */ ++ ++#define catc_get_mac(catc, mac) catc_ctrl_msg(catc, USB_DIR_IN, GetMac, 0, 0, mac, 6) ++#define catc_reset(catc) catc_ctrl_msg(catc, USB_DIR_OUT, Reset, 0, 0, NULL, 0) ++#define catc_set_reg(catc, reg, val) catc_ctrl_msg(catc, USB_DIR_OUT, SetReg, val, reg, NULL, 0) ++#define catc_get_reg(catc, reg, buf) catc_ctrl_msg(catc, USB_DIR_IN, GetReg, 0, reg, buf, 1) ++#define catc_write_mem(catc, addr, buf, size) catc_ctrl_msg(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size) ++#define catc_read_mem(catc, addr, buf, size) catc_ctrl_msg(catc, USB_DIR_IN, ReadMem, 0, addr, buf, size) ++ ++#define f5u011_rxmode(catc, rxmode) catc_ctrl_msg(catc, USB_DIR_OUT, SetRxMode, 0, 1, rxmode, 2) ++#define f5u011_rxmode_async(catc, rxmode) catc_ctrl_async(catc, USB_DIR_OUT, SetRxMode, 0, 1, &rxmode, 2, NULL) ++#define f5u011_mchash_async(catc, hash) catc_ctrl_async(catc, USB_DIR_OUT, SetRxMode, 0, 2, &hash, 8, NULL) ++ ++#define catc_set_reg_async(catc, reg, val) catc_ctrl_async(catc, USB_DIR_OUT, SetReg, val, reg, NULL, 0, NULL) ++#define catc_get_reg_async(catc, reg, cb) catc_ctrl_async(catc, USB_DIR_IN, GetReg, 0, reg, NULL, 1, cb) ++#define catc_write_mem_async(catc, addr, buf, size) catc_ctrl_async(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size, NULL) ++ ++/* ++ * Receive routines. ++ */ ++ ++static void catc_rx_done(struct urb *urb) ++{ ++ struct catc *catc = urb->context; ++ u8 *pkt_start = urb->transfer_buffer; ++ struct sk_buff *skb; ++ int pkt_len, pkt_offset = 0; ++ int status = urb->status; ++ ++ if (!catc->is_f5u011) { ++ clear_bit(RX_RUNNING, &catc->flags); ++ pkt_offset = 2; ++ } ++ ++ if (status) { ++ dev_dbg(&urb->dev->dev, "rx_done, status %d, length %d\n", ++ status, urb->actual_length); ++ return; ++ } ++ ++ do { ++ if(!catc->is_f5u011) { ++ pkt_len = le16_to_cpup((__le16*)pkt_start); ++ if (pkt_len > urb->actual_length) { ++ catc->netdev->stats.rx_length_errors++; ++ catc->netdev->stats.rx_errors++; ++ break; ++ } ++ } else { ++ pkt_len = urb->actual_length; ++ } ++ ++ if (!(skb = dev_alloc_skb(pkt_len))) ++ return; ++ ++ skb_copy_to_linear_data(skb, pkt_start + pkt_offset, pkt_len); ++ skb_put(skb, pkt_len); ++ ++ skb->protocol = eth_type_trans(skb, catc->netdev); ++ netif_rx(skb); ++ ++ catc->netdev->stats.rx_packets++; ++ catc->netdev->stats.rx_bytes += pkt_len; ++ ++ /* F5U011 only does one packet per RX */ ++ if (catc->is_f5u011) ++ break; ++ pkt_start += (((pkt_len + 1) >> 6) + 1) << 6; ++ ++ } while (pkt_start - (u8 *) urb->transfer_buffer < urb->actual_length); ++ ++ if (catc->is_f5u011) { ++ if (atomic_read(&catc->recq_sz)) { ++ int state; ++ atomic_dec(&catc->recq_sz); ++ netdev_dbg(catc->netdev, "getting extra packet\n"); ++ urb->dev = catc->usbdev; ++ if ((state = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { ++ netdev_dbg(catc->netdev, ++ "submit(rx_urb) status %d\n", state); ++ } ++ } else { ++ clear_bit(RX_RUNNING, &catc->flags); ++ } ++ } ++} ++ ++static void catc_irq_done(struct urb *urb) ++{ ++ struct catc *catc = urb->context; ++ u8 *data = urb->transfer_buffer; ++ int status = urb->status; ++ unsigned int hasdata = 0, linksts = LinkNoChange; ++ int res; ++ ++ if (!catc->is_f5u011) { ++ hasdata = data[1] & 0x80; ++ if (data[1] & 0x40) ++ linksts = LinkGood; ++ else if (data[1] & 0x20) ++ linksts = LinkBad; ++ } else { ++ hasdata = (unsigned int)(be16_to_cpup((__be16*)data) & 0x0fff); ++ if (data[0] == 0x90) ++ linksts = LinkGood; ++ else if (data[0] == 0xA0) ++ linksts = LinkBad; ++ } ++ ++ switch (status) { ++ case 0: /* success */ ++ break; ++ case -ECONNRESET: /* unlink */ ++ case -ENOENT: ++ case -ESHUTDOWN: ++ return; ++ /* -EPIPE: should clear the halt */ ++ default: /* error */ ++ dev_dbg(&urb->dev->dev, ++ "irq_done, status %d, data %02x %02x.\n", ++ status, data[0], data[1]); ++ goto resubmit; ++ } ++ ++ if (linksts == LinkGood) { ++ netif_carrier_on(catc->netdev); ++ netdev_dbg(catc->netdev, "link ok\n"); ++ } ++ ++ if (linksts == LinkBad) { ++ netif_carrier_off(catc->netdev); ++ netdev_dbg(catc->netdev, "link bad\n"); ++ } ++ ++ if (hasdata) { ++ if (test_and_set_bit(RX_RUNNING, &catc->flags)) { ++ if (catc->is_f5u011) ++ atomic_inc(&catc->recq_sz); ++ } else { ++ catc->rx_urb->dev = catc->usbdev; ++ if ((res = usb_submit_urb(catc->rx_urb, GFP_ATOMIC)) < 0) { ++ dev_err(&catc->usbdev->dev, ++ "submit(rx_urb) status %d\n", res); ++ } ++ } ++ } ++resubmit: ++ res = usb_submit_urb (urb, GFP_ATOMIC); ++ if (res) ++ dev_err(&catc->usbdev->dev, ++ "can't resubmit intr, %s-%s, status %d\n", ++ catc->usbdev->bus->bus_name, ++ catc->usbdev->devpath, res); ++} ++ ++/* ++ * Transmit routines. ++ */ ++ ++static int catc_tx_run(struct catc *catc) ++{ ++ int status; ++ ++ if (catc->is_f5u011) ++ catc->tx_ptr = (catc->tx_ptr + 63) & ~63; ++ ++ catc->tx_urb->transfer_buffer_length = catc->tx_ptr; ++ catc->tx_urb->transfer_buffer = catc->tx_buf[catc->tx_idx]; ++ catc->tx_urb->dev = catc->usbdev; ++ ++ if ((status = usb_submit_urb(catc->tx_urb, GFP_ATOMIC)) < 0) ++ dev_err(&catc->usbdev->dev, "submit(tx_urb), status %d\n", ++ status); ++ ++ catc->tx_idx = !catc->tx_idx; ++ catc->tx_ptr = 0; ++ ++ catc->netdev->trans_start = jiffies; ++ return status; ++} ++ ++static void catc_tx_done(struct urb *urb) ++{ ++ struct catc *catc = urb->context; ++ unsigned long flags; ++ int r, status = urb->status; ++ ++ if (status == -ECONNRESET) { ++ dev_dbg(&urb->dev->dev, "Tx Reset.\n"); ++ urb->status = 0; ++ catc->netdev->trans_start = jiffies; ++ catc->netdev->stats.tx_errors++; ++ clear_bit(TX_RUNNING, &catc->flags); ++ netif_wake_queue(catc->netdev); ++ return; ++ } ++ ++ if (status) { ++ dev_dbg(&urb->dev->dev, "tx_done, status %d, length %d\n", ++ status, urb->actual_length); ++ return; ++ } ++ ++ spin_lock_irqsave(&catc->tx_lock, flags); ++ ++ if (catc->tx_ptr) { ++ r = catc_tx_run(catc); ++ if (unlikely(r < 0)) ++ clear_bit(TX_RUNNING, &catc->flags); ++ } else { ++ clear_bit(TX_RUNNING, &catc->flags); ++ } ++ ++ netif_wake_queue(catc->netdev); ++ ++ spin_unlock_irqrestore(&catc->tx_lock, flags); ++} ++ ++static netdev_tx_t catc_start_xmit(struct sk_buff *skb, ++ struct net_device *netdev) ++{ ++ struct catc *catc = netdev_priv(netdev); ++ unsigned long flags; ++ int r = 0; ++ char *tx_buf; ++ ++ spin_lock_irqsave(&catc->tx_lock, flags); ++ ++ catc->tx_ptr = (((catc->tx_ptr - 1) >> 6) + 1) << 6; ++ tx_buf = catc->tx_buf[catc->tx_idx] + catc->tx_ptr; ++ if (catc->is_f5u011) ++ *(__be16 *)tx_buf = cpu_to_be16(skb->len); ++ else ++ *(__le16 *)tx_buf = cpu_to_le16(skb->len); ++ skb_copy_from_linear_data(skb, tx_buf + 2, skb->len); ++ catc->tx_ptr += skb->len + 2; ++ ++ if (!test_and_set_bit(TX_RUNNING, &catc->flags)) { ++ r = catc_tx_run(catc); ++ if (r < 0) ++ clear_bit(TX_RUNNING, &catc->flags); ++ } ++ ++ if ((catc->is_f5u011 && catc->tx_ptr) || ++ (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2)))) ++ netif_stop_queue(netdev); ++ ++ spin_unlock_irqrestore(&catc->tx_lock, flags); ++ ++ if (r >= 0) { ++ catc->netdev->stats.tx_bytes += skb->len; ++ catc->netdev->stats.tx_packets++; ++ } ++ ++ dev_kfree_skb(skb); ++ ++ return NETDEV_TX_OK; ++} ++ ++static void catc_tx_timeout(struct net_device *netdev) ++{ ++ struct catc *catc = netdev_priv(netdev); ++ ++ dev_warn(&netdev->dev, "Transmit timed out.\n"); ++ usb_unlink_urb(catc->tx_urb); ++} ++ ++/* ++ * Control messages. ++ */ ++ ++static int catc_ctrl_msg(struct catc *catc, u8 dir, u8 request, u16 value, u16 index, void *buf, int len) ++{ ++ int retval = usb_control_msg(catc->usbdev, ++ dir ? usb_rcvctrlpipe(catc->usbdev, 0) : usb_sndctrlpipe(catc->usbdev, 0), ++ request, 0x40 | dir, value, index, buf, len, 1000); ++ return retval < 0 ? retval : 0; ++} ++ ++static void catc_ctrl_run(struct catc *catc) ++{ ++ struct ctrl_queue *q = catc->ctrl_queue + catc->ctrl_tail; ++ struct usb_device *usbdev = catc->usbdev; ++ struct urb *urb = catc->ctrl_urb; ++ struct usb_ctrlrequest *dr = &catc->ctrl_dr; ++ int status; ++ ++ dr->bRequest = q->request; ++ dr->bRequestType = 0x40 | q->dir; ++ dr->wValue = cpu_to_le16(q->value); ++ dr->wIndex = cpu_to_le16(q->index); ++ dr->wLength = cpu_to_le16(q->len); ++ ++ urb->pipe = q->dir ? usb_rcvctrlpipe(usbdev, 0) : usb_sndctrlpipe(usbdev, 0); ++ urb->transfer_buffer_length = q->len; ++ urb->transfer_buffer = catc->ctrl_buf; ++ urb->setup_packet = (void *) dr; ++ urb->dev = usbdev; ++ ++ if (!q->dir && q->buf && q->len) ++ memcpy(catc->ctrl_buf, q->buf, q->len); ++ ++ if ((status = usb_submit_urb(catc->ctrl_urb, GFP_ATOMIC))) ++ dev_err(&catc->usbdev->dev, "submit(ctrl_urb) status %d\n", ++ status); ++} ++ ++static void catc_ctrl_done(struct urb *urb) ++{ ++ struct catc *catc = urb->context; ++ struct ctrl_queue *q; ++ unsigned long flags; ++ int status = urb->status; ++ ++ if (status) ++ dev_dbg(&urb->dev->dev, "ctrl_done, status %d, len %d.\n", ++ status, urb->actual_length); ++ ++ spin_lock_irqsave(&catc->ctrl_lock, flags); ++ ++ q = catc->ctrl_queue + catc->ctrl_tail; ++ ++ if (q->dir) { ++ if (q->buf && q->len) ++ memcpy(q->buf, catc->ctrl_buf, q->len); ++ else ++ q->buf = catc->ctrl_buf; ++ } ++ ++ if (q->callback) ++ q->callback(catc, q); ++ ++ catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1); ++ ++ if (catc->ctrl_head != catc->ctrl_tail) ++ catc_ctrl_run(catc); ++ else ++ clear_bit(CTRL_RUNNING, &catc->flags); ++ ++ spin_unlock_irqrestore(&catc->ctrl_lock, flags); ++} ++ ++static int catc_ctrl_async(struct catc *catc, u8 dir, u8 request, u16 value, ++ u16 index, void *buf, int len, void (*callback)(struct catc *catc, struct ctrl_queue *q)) ++{ ++ struct ctrl_queue *q; ++ int retval = 0; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&catc->ctrl_lock, flags); ++ ++ q = catc->ctrl_queue + catc->ctrl_head; ++ ++ q->dir = dir; ++ q->request = request; ++ q->value = value; ++ q->index = index; ++ q->buf = buf; ++ q->len = len; ++ q->callback = callback; ++ ++ catc->ctrl_head = (catc->ctrl_head + 1) & (CTRL_QUEUE - 1); ++ ++ if (catc->ctrl_head == catc->ctrl_tail) { ++ dev_err(&catc->usbdev->dev, "ctrl queue full\n"); ++ catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1); ++ retval = -1; ++ } ++ ++ if (!test_and_set_bit(CTRL_RUNNING, &catc->flags)) ++ catc_ctrl_run(catc); ++ ++ spin_unlock_irqrestore(&catc->ctrl_lock, flags); ++ ++ return retval; ++} ++ ++/* ++ * Statistics. ++ */ ++ ++static void catc_stats_done(struct catc *catc, struct ctrl_queue *q) ++{ ++ int index = q->index - EthStats; ++ u16 data, last; ++ ++ catc->stats_buf[index] = *((char *)q->buf); ++ ++ if (index & 1) ++ return; ++ ++ data = ((u16)catc->stats_buf[index] << 8) | catc->stats_buf[index + 1]; ++ last = catc->stats_vals[index >> 1]; ++ ++ switch (index) { ++ case TxSingleColl: ++ case TxMultiColl: ++ catc->netdev->stats.collisions += data - last; ++ break; ++ case TxExcessColl: ++ catc->netdev->stats.tx_aborted_errors += data - last; ++ catc->netdev->stats.tx_errors += data - last; ++ break; ++ case RxFramErr: ++ catc->netdev->stats.rx_frame_errors += data - last; ++ catc->netdev->stats.rx_errors += data - last; ++ break; ++ } ++ ++ catc->stats_vals[index >> 1] = data; ++} ++ ++static void catc_stats_timer(unsigned long data) ++{ ++ struct catc *catc = (void *) data; ++ int i; ++ ++ for (i = 0; i < 8; i++) ++ catc_get_reg_async(catc, EthStats + 7 - i, catc_stats_done); ++ ++ mod_timer(&catc->timer, jiffies + STATS_UPDATE); ++} ++ ++/* ++ * Receive modes. Broadcast, Multicast, Promisc. ++ */ ++ ++static void catc_multicast(unsigned char *addr, u8 *multicast) ++{ ++ u32 crc; ++ ++ crc = ether_crc_le(6, addr); ++ multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7); ++} ++ ++static void catc_set_multicast_list(struct net_device *netdev) ++{ ++ struct catc *catc = netdev_priv(netdev); ++ struct netdev_hw_addr *ha; ++ u8 broadcast[ETH_ALEN]; ++ u8 rx = RxEnable | RxPolarity | RxMultiCast; ++ ++ memset(broadcast, 0xff, ETH_ALEN); ++ memset(catc->multicast, 0, 64); ++ ++ catc_multicast(broadcast, catc->multicast); ++ catc_multicast(netdev->dev_addr, catc->multicast); ++ ++ if (netdev->flags & IFF_PROMISC) { ++ memset(catc->multicast, 0xff, 64); ++ rx |= (!catc->is_f5u011) ? RxPromisc : AltRxPromisc; ++ } ++ ++ if (netdev->flags & IFF_ALLMULTI) { ++ memset(catc->multicast, 0xff, 64); ++ } else { ++ netdev_for_each_mc_addr(ha, netdev) { ++ u32 crc = ether_crc_le(6, ha->addr); ++ if (!catc->is_f5u011) { ++ catc->multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7); ++ } else { ++ catc->multicast[7-(crc >> 29)] |= 1 << ((crc >> 26) & 7); ++ } ++ } ++ } ++ if (!catc->is_f5u011) { ++ catc_set_reg_async(catc, RxUnit, rx); ++ catc_write_mem_async(catc, 0xfa80, catc->multicast, 64); ++ } else { ++ f5u011_mchash_async(catc, catc->multicast); ++ if (catc->rxmode[0] != rx) { ++ catc->rxmode[0] = rx; ++ netdev_dbg(catc->netdev, ++ "Setting RX mode to %2.2X %2.2X\n", ++ catc->rxmode[0], catc->rxmode[1]); ++ f5u011_rxmode_async(catc, catc->rxmode); ++ } ++ } ++} ++ ++static void catc_get_drvinfo(struct net_device *dev, ++ struct ethtool_drvinfo *info) ++{ ++ struct catc *catc = netdev_priv(dev); ++ strlcpy(info->driver, driver_name, sizeof(info->driver)); ++ strlcpy(info->version, DRIVER_VERSION, sizeof(info->version)); ++ usb_make_path(catc->usbdev, info->bus_info, sizeof(info->bus_info)); ++} ++ ++static int catc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) ++{ ++ struct catc *catc = netdev_priv(dev); ++ if (!catc->is_f5u011) ++ return -EOPNOTSUPP; ++ ++ cmd->supported = SUPPORTED_10baseT_Half | SUPPORTED_TP; ++ cmd->advertising = ADVERTISED_10baseT_Half | ADVERTISED_TP; ++ ethtool_cmd_speed_set(cmd, SPEED_10); ++ cmd->duplex = DUPLEX_HALF; ++ cmd->port = PORT_TP; ++ cmd->phy_address = 0; ++ cmd->transceiver = XCVR_INTERNAL; ++ cmd->autoneg = AUTONEG_DISABLE; ++ cmd->maxtxpkt = 1; ++ cmd->maxrxpkt = 1; ++ return 0; ++} ++ ++static const struct ethtool_ops ops = { ++ .get_drvinfo = catc_get_drvinfo, ++ .get_settings = catc_get_settings, ++ .get_link = ethtool_op_get_link ++}; ++ ++/* ++ * Open, close. ++ */ ++ ++static int catc_open(struct net_device *netdev) ++{ ++ struct catc *catc = netdev_priv(netdev); ++ int status; ++ ++ catc->irq_urb->dev = catc->usbdev; ++ if ((status = usb_submit_urb(catc->irq_urb, GFP_KERNEL)) < 0) { ++ dev_err(&catc->usbdev->dev, "submit(irq_urb) status %d\n", ++ status); ++ return -1; ++ } ++ ++ netif_start_queue(netdev); ++ ++ if (!catc->is_f5u011) ++ mod_timer(&catc->timer, jiffies + STATS_UPDATE); ++ ++ return 0; ++} ++ ++static int catc_stop(struct net_device *netdev) ++{ ++ struct catc *catc = netdev_priv(netdev); ++ ++ netif_stop_queue(netdev); ++ ++ if (!catc->is_f5u011) ++ del_timer_sync(&catc->timer); ++ ++ usb_kill_urb(catc->rx_urb); ++ usb_kill_urb(catc->tx_urb); ++ usb_kill_urb(catc->irq_urb); ++ usb_kill_urb(catc->ctrl_urb); ++ ++ return 0; ++} ++ ++static const struct net_device_ops catc_netdev_ops = { ++ .ndo_open = catc_open, ++ .ndo_stop = catc_stop, ++ .ndo_start_xmit = catc_start_xmit, ++ ++ .ndo_tx_timeout = catc_tx_timeout, ++ .ndo_set_rx_mode = catc_set_multicast_list, ++ .ndo_change_mtu = eth_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++}; ++ ++/* ++ * USB probe, disconnect. ++ */ ++ ++static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id) ++{ ++ struct device *dev = &intf->dev; ++ struct usb_device *usbdev = interface_to_usbdev(intf); ++ struct net_device *netdev; ++ struct catc *catc; ++ u8 broadcast[ETH_ALEN]; ++ int i, pktsz; ++ ++ if (usb_set_interface(usbdev, ++ intf->altsetting->desc.bInterfaceNumber, 1)) { ++ dev_err(dev, "Can't set altsetting 1.\n"); ++ return -EIO; ++ } ++ ++ netdev = alloc_etherdev(sizeof(struct catc)); ++ if (!netdev) ++ return -ENOMEM; ++ ++ catc = netdev_priv(netdev); ++ ++ netdev->netdev_ops = &catc_netdev_ops; ++ netdev->watchdog_timeo = TX_TIMEOUT; ++ netdev->ethtool_ops = &ops; ++ ++ catc->usbdev = usbdev; ++ catc->netdev = netdev; ++ ++ spin_lock_init(&catc->tx_lock); ++ spin_lock_init(&catc->ctrl_lock); ++ ++ init_timer(&catc->timer); ++ catc->timer.data = (long) catc; ++ catc->timer.function = catc_stats_timer; ++ ++ catc->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); ++ catc->tx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ catc->rx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ catc->irq_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if ((!catc->ctrl_urb) || (!catc->tx_urb) || ++ (!catc->rx_urb) || (!catc->irq_urb)) { ++ dev_err(&intf->dev, "No free urbs available.\n"); ++ usb_free_urb(catc->ctrl_urb); ++ usb_free_urb(catc->tx_urb); ++ usb_free_urb(catc->rx_urb); ++ usb_free_urb(catc->irq_urb); ++ free_netdev(netdev); ++ return -ENOMEM; ++ } ++ ++ /* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */ ++ if (le16_to_cpu(usbdev->descriptor.idVendor) == 0x0423 && ++ le16_to_cpu(usbdev->descriptor.idProduct) == 0xa && ++ le16_to_cpu(catc->usbdev->descriptor.bcdDevice) == 0x0130) { ++ dev_dbg(dev, "Testing for f5u011\n"); ++ catc->is_f5u011 = 1; ++ atomic_set(&catc->recq_sz, 0); ++ pktsz = RX_PKT_SZ; ++ } else { ++ pktsz = RX_MAX_BURST * (PKT_SZ + 2); ++ } ++ ++ usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), ++ NULL, NULL, 0, catc_ctrl_done, catc); ++ ++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), ++ NULL, 0, catc_tx_done, catc); ++ ++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), ++ catc->rx_buf, pktsz, catc_rx_done, catc); ++ ++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2), ++ catc->irq_buf, 2, catc_irq_done, catc, 1); ++ ++ if (!catc->is_f5u011) { ++ dev_dbg(dev, "Checking memory size\n"); ++ ++ i = 0x12345678; ++ catc_write_mem(catc, 0x7a80, &i, 4); ++ i = 0x87654321; ++ catc_write_mem(catc, 0xfa80, &i, 4); ++ catc_read_mem(catc, 0x7a80, &i, 4); ++ ++ switch (i) { ++ case 0x12345678: ++ catc_set_reg(catc, TxBufCount, 8); ++ catc_set_reg(catc, RxBufCount, 32); ++ dev_dbg(dev, "64k Memory\n"); ++ break; ++ default: ++ dev_warn(&intf->dev, ++ "Couldn't detect memory size, assuming 32k\n"); ++ case 0x87654321: ++ catc_set_reg(catc, TxBufCount, 4); ++ catc_set_reg(catc, RxBufCount, 16); ++ dev_dbg(dev, "32k Memory\n"); ++ break; ++ } ++ ++ dev_dbg(dev, "Getting MAC from SEEROM.\n"); ++ ++ catc_get_mac(catc, netdev->dev_addr); ++ ++ dev_dbg(dev, "Setting MAC into registers.\n"); ++ ++ for (i = 0; i < 6; i++) ++ catc_set_reg(catc, StationAddr0 - i, netdev->dev_addr[i]); ++ ++ dev_dbg(dev, "Filling the multicast list.\n"); ++ ++ memset(broadcast, 0xff, ETH_ALEN); ++ catc_multicast(broadcast, catc->multicast); ++ catc_multicast(netdev->dev_addr, catc->multicast); ++ catc_write_mem(catc, 0xfa80, catc->multicast, 64); ++ ++ dev_dbg(dev, "Clearing error counters.\n"); ++ ++ for (i = 0; i < 8; i++) ++ catc_set_reg(catc, EthStats + i, 0); ++ catc->last_stats = jiffies; ++ ++ dev_dbg(dev, "Enabling.\n"); ++ ++ catc_set_reg(catc, MaxBurst, RX_MAX_BURST); ++ catc_set_reg(catc, OpModes, OpTxMerge | OpRxMerge | OpLenInclude | Op3MemWaits); ++ catc_set_reg(catc, LEDCtrl, LEDLink); ++ catc_set_reg(catc, RxUnit, RxEnable | RxPolarity | RxMultiCast); ++ } else { ++ dev_dbg(dev, "Performing reset\n"); ++ catc_reset(catc); ++ catc_get_mac(catc, netdev->dev_addr); ++ ++ dev_dbg(dev, "Setting RX Mode\n"); ++ catc->rxmode[0] = RxEnable | RxPolarity | RxMultiCast; ++ catc->rxmode[1] = 0; ++ f5u011_rxmode(catc, catc->rxmode); ++ } ++ dev_dbg(dev, "Init done.\n"); ++ printk(KERN_INFO "%s: %s USB Ethernet at usb-%s-%s, %pM.\n", ++ netdev->name, (catc->is_f5u011) ? "Belkin F5U011" : "CATC EL1210A NetMate", ++ usbdev->bus->bus_name, usbdev->devpath, netdev->dev_addr); ++ usb_set_intfdata(intf, catc); ++ ++ SET_NETDEV_DEV(netdev, &intf->dev); ++ if (register_netdev(netdev) != 0) { ++ usb_set_intfdata(intf, NULL); ++ usb_free_urb(catc->ctrl_urb); ++ usb_free_urb(catc->tx_urb); ++ usb_free_urb(catc->rx_urb); ++ usb_free_urb(catc->irq_urb); ++ free_netdev(netdev); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static void catc_disconnect(struct usb_interface *intf) ++{ ++ struct catc *catc = usb_get_intfdata(intf); ++ ++ usb_set_intfdata(intf, NULL); ++ if (catc) { ++ unregister_netdev(catc->netdev); ++ usb_free_urb(catc->ctrl_urb); ++ usb_free_urb(catc->tx_urb); ++ usb_free_urb(catc->rx_urb); ++ usb_free_urb(catc->irq_urb); ++ free_netdev(catc->netdev); ++ } ++} ++ ++/* ++ * Module functions and tables. ++ */ ++ ++static struct usb_device_id catc_id_table [] = { ++ { USB_DEVICE(0x0423, 0xa) }, /* CATC Netmate, Belkin F5U011 */ ++ { USB_DEVICE(0x0423, 0xc) }, /* CATC Netmate II, Belkin F5U111 */ ++ { USB_DEVICE(0x08d1, 0x1) }, /* smartBridges smartNIC */ ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(usb, catc_id_table); ++ ++static struct usb_driver catc_driver = { ++ .name = driver_name, ++ .probe = catc_probe, ++ .disconnect = catc_disconnect, ++ .id_table = catc_id_table, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(catc_driver); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/cdc_eem.c backports-3.18.1-1/drivers/net/usb/cdc_eem.c +--- backports-3.18.1-1.org/drivers/net/usb/cdc_eem.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/cdc_eem.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,381 @@ ++/* ++ * USB CDC EEM network interface driver ++ * Copyright (C) 2009 Oberthur Technologies ++ * by Omar Laazimani, Olivier Condemine ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ctype.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/crc32.h> ++#include <linux/usb/cdc.h> ++#include <linux/usb/usbnet.h> ++#include <linux/gfp.h> ++#include <linux/if_vlan.h> ++ ++ ++/* ++ * This driver is an implementation of the CDC "Ethernet Emulation ++ * Model" (EEM) specification, which encapsulates Ethernet frames ++ * for transport over USB using a simpler USB device model than the ++ * previous CDC "Ethernet Control Model" (ECM, or "CDC Ethernet"). ++ * ++ * For details, see www.usb.org/developers/devclass_docs/CDC_EEM10.pdf ++ * ++ * This version has been tested with GIGAntIC WuaoW SIM Smart Card on 2.6.24, ++ * 2.6.27 and 2.6.30rc2 kernel. ++ * It has also been validated on Openmoko Om 2008.12 (based on 2.6.24 kernel). ++ * build on 23-April-2009 ++ */ ++ ++#define EEM_HEAD 2 /* 2 byte header */ ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void eem_linkcmd_complete(struct urb *urb) ++{ ++ dev_kfree_skb(urb->context); ++ usb_free_urb(urb); ++} ++ ++static void eem_linkcmd(struct usbnet *dev, struct sk_buff *skb) ++{ ++ struct urb *urb; ++ int status; ++ ++ urb = usb_alloc_urb(0, GFP_ATOMIC); ++ if (!urb) ++ goto fail; ++ ++ usb_fill_bulk_urb(urb, dev->udev, dev->out, ++ skb->data, skb->len, eem_linkcmd_complete, skb); ++ ++ status = usb_submit_urb(urb, GFP_ATOMIC); ++ if (status) { ++ usb_free_urb(urb); ++fail: ++ dev_kfree_skb(skb); ++ netdev_warn(dev->net, "link cmd failure\n"); ++ return; ++ } ++} ++ ++static int eem_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int status = 0; ++ ++ status = usbnet_get_endpoints(dev, intf); ++ if (status < 0) { ++ usb_set_intfdata(intf, NULL); ++ usb_driver_release_interface(driver_of(intf), intf); ++ return status; ++ } ++ ++ /* no jumbogram (16K) support for now */ ++ ++ dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN + VLAN_HLEN; ++ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; ++ ++ return 0; ++} ++ ++/* ++ * EEM permits packing multiple Ethernet frames into USB transfers ++ * (a "bundle"), but for TX we don't try to do that. ++ */ ++static struct sk_buff *eem_tx_fixup(struct usbnet *dev, struct sk_buff *skb, ++ gfp_t flags) ++{ ++ struct sk_buff *skb2 = NULL; ++ u16 len = skb->len; ++ u32 crc = 0; ++ int padlen = 0; ++ ++ /* When ((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket) is ++ * zero, stick two bytes of zero length EEM packet on the end. ++ * Else the framework would add invalid single byte padding, ++ * since it can't know whether ZLPs will be handled right by ++ * all the relevant hardware and software. ++ */ ++ if (!((len + EEM_HEAD + ETH_FCS_LEN) % dev->maxpacket)) ++ padlen += 2; ++ ++ if (!skb_cloned(skb)) { ++ int headroom = skb_headroom(skb); ++ int tailroom = skb_tailroom(skb); ++ ++ if ((tailroom >= ETH_FCS_LEN + padlen) && ++ (headroom >= EEM_HEAD)) ++ goto done; ++ ++ if ((headroom + tailroom) ++ > (EEM_HEAD + ETH_FCS_LEN + padlen)) { ++ skb->data = memmove(skb->head + ++ EEM_HEAD, ++ skb->data, ++ skb->len); ++ skb_set_tail_pointer(skb, len); ++ goto done; ++ } ++ } ++ ++ skb2 = skb_copy_expand(skb, EEM_HEAD, ETH_FCS_LEN + padlen, flags); ++ if (!skb2) ++ return NULL; ++ ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ ++done: ++ /* we don't use the "no Ethernet CRC" option */ ++ crc = crc32_le(~0, skb->data, skb->len); ++ crc = ~crc; ++ ++ put_unaligned_le32(crc, skb_put(skb, 4)); ++ ++ /* EEM packet header format: ++ * b0..13: length of ethernet frame ++ * b14: bmCRC (1 == valid Ethernet CRC) ++ * b15: bmType (0 == data) ++ */ ++ len = skb->len; ++ put_unaligned_le16(BIT(14) | len, skb_push(skb, 2)); ++ ++ /* Bundle a zero length EEM packet if needed */ ++ if (padlen) ++ put_unaligned_le16(0, skb_put(skb, 2)); ++ ++ return skb; ++} ++ ++static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ /* ++ * Our task here is to strip off framing, leaving skb with one ++ * data frame for the usbnet framework code to process. But we ++ * may have received multiple EEM payloads, or command payloads. ++ * So we must process _everything_ as if it's a header, except ++ * maybe the last data payload ++ * ++ * REVISIT the framework needs updating so that when we consume ++ * all payloads (the last or only message was a command, or a ++ * zero length EEM packet) that is not accounted as an rx_error. ++ */ ++ do { ++ struct sk_buff *skb2 = NULL; ++ u16 header; ++ u16 len = 0; ++ ++ /* incomplete EEM header? */ ++ if (skb->len < EEM_HEAD) ++ return 0; ++ ++ /* ++ * EEM packet header format: ++ * b0..14: EEM type dependent (Data or Command) ++ * b15: bmType ++ */ ++ header = get_unaligned_le16(skb->data); ++ skb_pull(skb, EEM_HEAD); ++ ++ /* ++ * The bmType bit helps to denote when EEM ++ * packet is data or command : ++ * bmType = 0 : EEM data payload ++ * bmType = 1 : EEM (link) command ++ */ ++ if (header & BIT(15)) { ++ u16 bmEEMCmd; ++ ++ /* ++ * EEM (link) command packet: ++ * b0..10: bmEEMCmdParam ++ * b11..13: bmEEMCmd ++ * b14: bmReserved (must be 0) ++ * b15: 1 (EEM command) ++ */ ++ if (header & BIT(14)) { ++ netdev_dbg(dev->net, "reserved command %04x\n", ++ header); ++ continue; ++ } ++ ++ bmEEMCmd = (header >> 11) & 0x7; ++ switch (bmEEMCmd) { ++ ++ /* Responding to echo requests is mandatory. */ ++ case 0: /* Echo command */ ++ len = header & 0x7FF; ++ ++ /* bogus command? */ ++ if (skb->len < len) ++ return 0; ++ ++ skb2 = skb_clone(skb, GFP_ATOMIC); ++ if (unlikely(!skb2)) ++ goto next; ++ skb_trim(skb2, len); ++ put_unaligned_le16(BIT(15) | (1 << 11) | len, ++ skb_push(skb2, 2)); ++ eem_linkcmd(dev, skb2); ++ break; ++ ++ /* ++ * Host may choose to ignore hints. ++ * - suspend: peripheral ready to suspend ++ * - response: suggest N millisec polling ++ * - response complete: suggest N sec polling ++ * ++ * Suspend is reported and maybe heeded. ++ */ ++ case 2: /* Suspend hint */ ++ usbnet_device_suggests_idle(dev); ++ continue; ++ case 3: /* Response hint */ ++ case 4: /* Response complete hint */ ++ continue; ++ ++ /* ++ * Hosts should never receive host-to-peripheral ++ * or reserved command codes; or responses to an ++ * echo command we didn't send. ++ */ ++ case 1: /* Echo response */ ++ case 5: /* Tickle */ ++ default: /* reserved */ ++ netdev_warn(dev->net, ++ "unexpected link command %d\n", ++ bmEEMCmd); ++ continue; ++ } ++ ++ } else { ++ u32 crc, crc2; ++ int is_last; ++ ++ /* zero length EEM packet? */ ++ if (header == 0) ++ continue; ++ ++ /* ++ * EEM data packet header : ++ * b0..13: length of ethernet frame ++ * b14: bmCRC ++ * b15: 0 (EEM data) ++ */ ++ len = header & 0x3FFF; ++ ++ /* bogus EEM payload? */ ++ if (skb->len < len) ++ return 0; ++ ++ /* bogus ethernet frame? */ ++ if (len < (ETH_HLEN + ETH_FCS_LEN)) ++ goto next; ++ ++ /* ++ * Treat the last payload differently: framework ++ * code expects our "fixup" to have stripped off ++ * headers, so "skb" is a data packet (or error). ++ * Else if it's not the last payload, keep "skb" ++ * for further processing. ++ */ ++ is_last = (len == skb->len); ++ if (is_last) ++ skb2 = skb; ++ else { ++ skb2 = skb_clone(skb, GFP_ATOMIC); ++ if (unlikely(!skb2)) ++ return 0; ++ } ++ ++ /* ++ * The bmCRC helps to denote when the CRC field in ++ * the Ethernet frame contains a calculated CRC: ++ * bmCRC = 1 : CRC is calculated ++ * bmCRC = 0 : CRC = 0xDEADBEEF ++ */ ++ if (header & BIT(14)) { ++ crc = get_unaligned_le32(skb2->data ++ + len - ETH_FCS_LEN); ++ crc2 = ~crc32_le(~0, skb2->data, skb2->len ++ - ETH_FCS_LEN); ++ } else { ++ crc = get_unaligned_be32(skb2->data ++ + len - ETH_FCS_LEN); ++ crc2 = 0xdeadbeef; ++ } ++ skb_trim(skb2, len - ETH_FCS_LEN); ++ ++ if (is_last) ++ return crc == crc2; ++ ++ if (unlikely(crc != crc2)) { ++ dev->net->stats.rx_errors++; ++ dev_kfree_skb_any(skb2); ++ } else ++ usbnet_skb_return(dev, skb2); ++ } ++ ++next: ++ skb_pull(skb, len); ++ } while (skb->len); ++ ++ return 1; ++} ++ ++static const struct driver_info eem_info = { ++ .description = "CDC EEM Device", ++ .flags = FLAG_ETHER | FLAG_POINTTOPOINT, ++ .bind = eem_bind, ++ .rx_fixup = eem_rx_fixup, ++ .tx_fixup = eem_tx_fixup, ++}; ++ ++/*-------------------------------------------------------------------------*/ ++ ++static const struct usb_device_id products[] = { ++{ ++ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_EEM, ++ USB_CDC_PROTO_EEM), ++ .driver_info = (unsigned long) &eem_info, ++}, ++{ ++ /* EMPTY == end of list */ ++}, ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver eem_driver = { ++ .name = "cdc_eem", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(eem_driver); ++ ++MODULE_AUTHOR("Omar Laazimani omar.oberthur@gmail.com"); ++MODULE_DESCRIPTION("USB CDC EEM"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/cdc-phonet.c backports-3.18.1-1/drivers/net/usb/cdc-phonet.c +--- backports-3.18.1-1.org/drivers/net/usb/cdc-phonet.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/cdc-phonet.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,466 @@ ++/* ++ * phonet.c -- USB CDC Phonet host driver ++ * ++ * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved. ++ * ++ * Author: Rémi Denis-Courmont ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * 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., 51 Franklin St, Fifth Floor, Boston, MA ++ * 02110-1301 USA ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/mm.h> ++#include <linux/module.h> ++#include <linux/gfp.h> ++#include <linux/usb.h> ++#include <linux/usb/cdc.h> ++#include <linux/netdevice.h> ++#include <linux/if_arp.h> ++#include <linux/if_phonet.h> ++#include <linux/phonet.h> ++ ++#define PN_MEDIA_USB 0x1B ++ ++static const unsigned rxq_size = 17; ++ ++struct usbpn_dev { ++ struct net_device *dev; ++ ++ struct usb_interface *intf, *data_intf; ++ struct usb_device *usb; ++ unsigned int tx_pipe, rx_pipe; ++ u8 active_setting; ++ u8 disconnected; ++ ++ unsigned tx_queue; ++ spinlock_t tx_lock; ++ ++ spinlock_t rx_lock; ++ struct sk_buff *rx_skb; ++ struct urb *urbs[0]; ++}; ++ ++static void tx_complete(struct urb *req); ++static void rx_complete(struct urb *req); ++ ++/* ++ * Network device callbacks ++ */ ++static netdev_tx_t usbpn_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct usbpn_dev *pnd = netdev_priv(dev); ++ struct urb *req = NULL; ++ unsigned long flags; ++ int err; ++ ++ if (skb->protocol != htons(ETH_P_PHONET)) ++ goto drop; ++ ++ req = usb_alloc_urb(0, GFP_ATOMIC); ++ if (!req) ++ goto drop; ++ usb_fill_bulk_urb(req, pnd->usb, pnd->tx_pipe, skb->data, skb->len, ++ tx_complete, skb); ++ req->transfer_flags = URB_ZERO_PACKET; ++ err = usb_submit_urb(req, GFP_ATOMIC); ++ if (err) { ++ usb_free_urb(req); ++ goto drop; ++ } ++ ++ spin_lock_irqsave(&pnd->tx_lock, flags); ++ pnd->tx_queue++; ++ if (pnd->tx_queue >= dev->tx_queue_len) ++ netif_stop_queue(dev); ++ spin_unlock_irqrestore(&pnd->tx_lock, flags); ++ return NETDEV_TX_OK; ++ ++drop: ++ dev_kfree_skb(skb); ++ dev->stats.tx_dropped++; ++ return NETDEV_TX_OK; ++} ++ ++static void tx_complete(struct urb *req) ++{ ++ struct sk_buff *skb = req->context; ++ struct net_device *dev = skb->dev; ++ struct usbpn_dev *pnd = netdev_priv(dev); ++ int status = req->status; ++ ++ switch (status) { ++ case 0: ++ dev->stats.tx_bytes += skb->len; ++ break; ++ ++ case -ENOENT: ++ case -ECONNRESET: ++ case -ESHUTDOWN: ++ dev->stats.tx_aborted_errors++; ++ default: ++ dev->stats.tx_errors++; ++ dev_dbg(&dev->dev, "TX error (%d)\n", status); ++ } ++ dev->stats.tx_packets++; ++ ++ spin_lock(&pnd->tx_lock); ++ pnd->tx_queue--; ++ netif_wake_queue(dev); ++ spin_unlock(&pnd->tx_lock); ++ ++ dev_kfree_skb_any(skb); ++ usb_free_urb(req); ++} ++ ++static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags) ++{ ++ struct net_device *dev = pnd->dev; ++ struct page *page; ++ int err; ++ ++ page = __skb_alloc_page(gfp_flags | __GFP_NOMEMALLOC, NULL); ++ if (!page) ++ return -ENOMEM; ++ ++ usb_fill_bulk_urb(req, pnd->usb, pnd->rx_pipe, page_address(page), ++ PAGE_SIZE, rx_complete, dev); ++ req->transfer_flags = 0; ++ err = usb_submit_urb(req, gfp_flags); ++ if (unlikely(err)) { ++ dev_dbg(&dev->dev, "RX submit error (%d)\n", err); ++ put_page(page); ++ } ++ return err; ++} ++ ++static void rx_complete(struct urb *req) ++{ ++ struct net_device *dev = req->context; ++ struct usbpn_dev *pnd = netdev_priv(dev); ++ struct page *page = virt_to_page(req->transfer_buffer); ++ struct sk_buff *skb; ++ unsigned long flags; ++ int status = req->status; ++ ++ switch (status) { ++ case 0: ++ spin_lock_irqsave(&pnd->rx_lock, flags); ++ skb = pnd->rx_skb; ++ if (!skb) { ++ skb = pnd->rx_skb = netdev_alloc_skb(dev, 12); ++ if (likely(skb)) { ++ /* Can't use pskb_pull() on page in IRQ */ ++ memcpy(skb_put(skb, 1), page_address(page), 1); ++ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, ++ page, 1, req->actual_length, ++ PAGE_SIZE); ++ page = NULL; ++ } ++ } else { ++ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, ++ page, 0, req->actual_length, ++ PAGE_SIZE); ++ page = NULL; ++ } ++ if (req->actual_length < PAGE_SIZE) ++ pnd->rx_skb = NULL; /* Last fragment */ ++ else ++ skb = NULL; ++ spin_unlock_irqrestore(&pnd->rx_lock, flags); ++ if (skb) { ++ skb->protocol = htons(ETH_P_PHONET); ++ skb_reset_mac_header(skb); ++ __skb_pull(skb, 1); ++ skb->dev = dev; ++ dev->stats.rx_packets++; ++ dev->stats.rx_bytes += skb->len; ++ ++ netif_rx(skb); ++ } ++ goto resubmit; ++ ++ case -ENOENT: ++ case -ECONNRESET: ++ case -ESHUTDOWN: ++ req = NULL; ++ break; ++ ++ case -EOVERFLOW: ++ dev->stats.rx_over_errors++; ++ dev_dbg(&dev->dev, "RX overflow\n"); ++ break; ++ ++ case -EILSEQ: ++ dev->stats.rx_crc_errors++; ++ break; ++ } ++ ++ dev->stats.rx_errors++; ++resubmit: ++ if (page) ++ put_page(page); ++ if (req) ++ rx_submit(pnd, req, GFP_ATOMIC | __GFP_COLD); ++} ++ ++static int usbpn_close(struct net_device *dev); ++ ++static int usbpn_open(struct net_device *dev) ++{ ++ struct usbpn_dev *pnd = netdev_priv(dev); ++ int err; ++ unsigned i; ++ unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; ++ ++ err = usb_set_interface(pnd->usb, num, pnd->active_setting); ++ if (err) ++ return err; ++ ++ for (i = 0; i < rxq_size; i++) { ++ struct urb *req = usb_alloc_urb(0, GFP_KERNEL); ++ ++ if (!req || rx_submit(pnd, req, GFP_KERNEL | __GFP_COLD)) { ++ usb_free_urb(req); ++ usbpn_close(dev); ++ return -ENOMEM; ++ } ++ pnd->urbs[i] = req; ++ } ++ ++ netif_wake_queue(dev); ++ return 0; ++} ++ ++static int usbpn_close(struct net_device *dev) ++{ ++ struct usbpn_dev *pnd = netdev_priv(dev); ++ unsigned i; ++ unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; ++ ++ netif_stop_queue(dev); ++ ++ for (i = 0; i < rxq_size; i++) { ++ struct urb *req = pnd->urbs[i]; ++ ++ if (!req) ++ continue; ++ usb_kill_urb(req); ++ usb_free_urb(req); ++ pnd->urbs[i] = NULL; ++ } ++ ++ return usb_set_interface(pnd->usb, num, !pnd->active_setting); ++} ++ ++static int usbpn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ++{ ++ struct if_phonet_req *req = (struct if_phonet_req *)ifr; ++ ++ switch (cmd) { ++ case SIOCPNGAUTOCONF: ++ req->ifr_phonet_autoconf.device = PN_DEV_PC; ++ return 0; ++ } ++ return -ENOIOCTLCMD; ++} ++ ++static int usbpn_set_mtu(struct net_device *dev, int new_mtu) ++{ ++ if ((new_mtu < PHONET_MIN_MTU) || (new_mtu > PHONET_MAX_MTU)) ++ return -EINVAL; ++ ++ dev->mtu = new_mtu; ++ return 0; ++} ++ ++static const struct net_device_ops usbpn_ops = { ++ .ndo_open = usbpn_open, ++ .ndo_stop = usbpn_close, ++ .ndo_start_xmit = usbpn_xmit, ++ .ndo_do_ioctl = usbpn_ioctl, ++ .ndo_change_mtu = usbpn_set_mtu, ++}; ++ ++static void usbpn_setup(struct net_device *dev) ++{ ++ dev->features = 0; ++ dev->netdev_ops = &usbpn_ops, ++ dev->header_ops = &phonet_header_ops; ++ dev->type = ARPHRD_PHONET; ++ dev->flags = IFF_POINTOPOINT | IFF_NOARP; ++ dev->mtu = PHONET_MAX_MTU; ++ dev->hard_header_len = 1; ++ dev->dev_addr[0] = PN_MEDIA_USB; ++ dev->addr_len = 1; ++ dev->tx_queue_len = 3; ++ ++ dev->destructor = free_netdev; ++} ++ ++/* ++ * USB driver callbacks ++ */ ++static struct usb_device_id usbpn_ids[] = { ++ { ++ .match_flags = USB_DEVICE_ID_MATCH_VENDOR ++ | USB_DEVICE_ID_MATCH_INT_CLASS ++ | USB_DEVICE_ID_MATCH_INT_SUBCLASS, ++ .idVendor = 0x0421, /* Nokia */ ++ .bInterfaceClass = USB_CLASS_COMM, ++ .bInterfaceSubClass = 0xFE, ++ }, ++ { }, ++}; ++ ++MODULE_DEVICE_TABLE(usb, usbpn_ids); ++ ++static struct usb_driver usbpn_driver; ++ ++static int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) ++{ ++ static const char ifname[] = "usbpn%d"; ++ const struct usb_cdc_union_desc *union_header = NULL; ++ const struct usb_host_interface *data_desc; ++ struct usb_interface *data_intf; ++ struct usb_device *usbdev = interface_to_usbdev(intf); ++ struct net_device *dev; ++ struct usbpn_dev *pnd; ++ u8 *data; ++ int phonet = 0; ++ int len, err; ++ ++ data = intf->altsetting->extra; ++ len = intf->altsetting->extralen; ++ while (len >= 3) { ++ u8 dlen = data[0]; ++ if (dlen < 3) ++ return -EINVAL; ++ ++ /* bDescriptorType */ ++ if (data[1] == USB_DT_CS_INTERFACE) { ++ /* bDescriptorSubType */ ++ switch (data[2]) { ++ case USB_CDC_UNION_TYPE: ++ if (union_header || dlen < 5) ++ break; ++ union_header = ++ (struct usb_cdc_union_desc *)data; ++ break; ++ case 0xAB: ++ phonet = 1; ++ break; ++ } ++ } ++ data += dlen; ++ len -= dlen; ++ } ++ ++ if (!union_header || !phonet) ++ return -EINVAL; ++ ++ data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0); ++ if (data_intf == NULL) ++ return -ENODEV; ++ /* Data interface has one inactive and one active setting */ ++ if (data_intf->num_altsetting != 2) ++ return -EINVAL; ++ if (data_intf->altsetting[0].desc.bNumEndpoints == 0 && ++ data_intf->altsetting[1].desc.bNumEndpoints == 2) ++ data_desc = data_intf->altsetting + 1; ++ else ++ if (data_intf->altsetting[0].desc.bNumEndpoints == 2 && ++ data_intf->altsetting[1].desc.bNumEndpoints == 0) ++ data_desc = data_intf->altsetting; ++ else ++ return -EINVAL; ++ ++ dev = alloc_netdev(sizeof(*pnd) + sizeof(pnd->urbs[0]) * rxq_size, ++ ifname, NET_NAME_UNKNOWN, usbpn_setup); ++ if (!dev) ++ return -ENOMEM; ++ ++ pnd = netdev_priv(dev); ++ SET_NETDEV_DEV(dev, &intf->dev); ++ ++ pnd->dev = dev; ++ pnd->usb = usbdev; ++ pnd->intf = intf; ++ pnd->data_intf = data_intf; ++ spin_lock_init(&pnd->tx_lock); ++ spin_lock_init(&pnd->rx_lock); ++ /* Endpoints */ ++ if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) { ++ pnd->rx_pipe = usb_rcvbulkpipe(usbdev, ++ data_desc->endpoint[0].desc.bEndpointAddress); ++ pnd->tx_pipe = usb_sndbulkpipe(usbdev, ++ data_desc->endpoint[1].desc.bEndpointAddress); ++ } else { ++ pnd->rx_pipe = usb_rcvbulkpipe(usbdev, ++ data_desc->endpoint[1].desc.bEndpointAddress); ++ pnd->tx_pipe = usb_sndbulkpipe(usbdev, ++ data_desc->endpoint[0].desc.bEndpointAddress); ++ } ++ pnd->active_setting = data_desc - data_intf->altsetting; ++ ++ err = usb_driver_claim_interface(&usbpn_driver, data_intf, pnd); ++ if (err) ++ goto out; ++ ++ /* Force inactive mode until the network device is brought UP */ ++ usb_set_interface(usbdev, union_header->bSlaveInterface0, ++ !pnd->active_setting); ++ usb_set_intfdata(intf, pnd); ++ ++ err = register_netdev(dev); ++ if (err) { ++ usb_driver_release_interface(&usbpn_driver, data_intf); ++ goto out; ++ } ++ ++ dev_dbg(&dev->dev, "USB CDC Phonet device found\n"); ++ return 0; ++ ++out: ++ usb_set_intfdata(intf, NULL); ++ free_netdev(dev); ++ return err; ++} ++ ++static void usbpn_disconnect(struct usb_interface *intf) ++{ ++ struct usbpn_dev *pnd = usb_get_intfdata(intf); ++ ++ if (pnd->disconnected) ++ return; ++ ++ pnd->disconnected = 1; ++ usb_driver_release_interface(&usbpn_driver, ++ (pnd->intf == intf) ? pnd->data_intf : pnd->intf); ++ unregister_netdev(pnd->dev); ++} ++ ++static struct usb_driver usbpn_driver = { ++ .name = "cdc_phonet", ++ .probe = usbpn_probe, ++ .disconnect = usbpn_disconnect, ++ .id_table = usbpn_ids, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(usbpn_driver); ++ ++MODULE_AUTHOR("Remi Denis-Courmont"); ++MODULE_DESCRIPTION("USB CDC Phonet host interface"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/cdc_subset.c backports-3.18.1-1/drivers/net/usb/cdc_subset.c +--- backports-3.18.1-1.org/drivers/net/usb/cdc_subset.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/cdc_subset.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,369 @@ ++/* ++ * Simple "CDC Subset" USB Networking Links ++ * Copyright (C) 2000-2005 by David Brownell ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include <linux/module.h> ++#include <linux/kmod.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/usb/usbnet.h> ++ ++ ++/* ++ * This supports simple USB network links that don't require any special ++ * framing or hardware control operations. The protocol used here is a ++ * strict subset of CDC Ethernet, with three basic differences reflecting ++ * the goal that almost any hardware should run it: ++ * ++ * - Minimal runtime control: one interface, no altsettings, and ++ * no vendor or class specific control requests. If a device is ++ * configured, it is allowed to exchange packets with the host. ++ * Fancier models would mean not working on some hardware. ++ * ++ * - Minimal manufacturing control: no IEEE "Organizationally ++ * Unique ID" required, or an EEPROMs to store one. Each host uses ++ * one random "locally assigned" Ethernet address instead, which can ++ * of course be overridden using standard tools like "ifconfig". ++ * (With 2^46 such addresses, same-net collisions are quite rare.) ++ * ++ * - There is no additional framing data for USB. Packets are written ++ * exactly as in CDC Ethernet, starting with an Ethernet header and ++ * terminated by a short packet. However, the host will never send a ++ * zero length packet; some systems can't handle those robustly. ++ * ++ * Anything that can transmit and receive USB bulk packets can implement ++ * this protocol. That includes both smart peripherals and quite a lot ++ * of "host-to-host" USB cables (which embed two devices back-to-back). ++ * ++ * Note that although Linux may use many of those host-to-host links ++ * with this "cdc_subset" framing, that doesn't mean there may not be a ++ * better approach. Handling the "other end unplugs/replugs" scenario ++ * well tends to require chip-specific vendor requests. Also, Windows ++ * peers at the other end of host-to-host cables may expect their own ++ * framing to be used rather than this "cdc_subset" model. ++ */ ++ ++#if defined(CONFIG_USB_EPSON2888) || defined(CONFIG_USB_ARMLINUX) ++/* PDA style devices are always connected if present */ ++static int always_connected (struct usbnet *dev) ++{ ++ return 0; ++} ++#endif ++ ++#ifdef CONFIG_USB_ALI_M5632 ++#define HAVE_HARDWARE ++ ++/*------------------------------------------------------------------------- ++ * ++ * ALi M5632 driver ... does high speed ++ * ++ * NOTE that the MS-Windows drivers for this chip use some funky and ++ * (naturally) undocumented 7-byte prefix to each packet, so this is a ++ * case where we don't currently interoperate. Also, once you unplug ++ * one end of the cable, you need to replug the other end too ... since ++ * chip docs are unavailable, there's no way to reset the relevant state ++ * short of a power cycle. ++ * ++ *-------------------------------------------------------------------------*/ ++ ++static void m5632_recover(struct usbnet *dev) ++{ ++ struct usb_device *udev = dev->udev; ++ struct usb_interface *intf = dev->intf; ++ int r; ++ ++ r = usb_lock_device_for_reset(udev, intf); ++ if (r < 0) ++ return; ++ ++ usb_reset_device(udev); ++ usb_unlock_device(udev); ++} ++ ++static const struct driver_info ali_m5632_info = { ++ .description = "ALi M5632", ++ .flags = FLAG_POINTTOPOINT, ++ .recover = m5632_recover, ++}; ++ ++#endif ++ ++#ifdef CONFIG_USB_AN2720 ++#define HAVE_HARDWARE ++ ++/*------------------------------------------------------------------------- ++ * ++ * AnchorChips 2720 driver ... http://www.cypress.com ++ * ++ * This doesn't seem to have a way to detect whether the peer is ++ * connected, or need any reset handshaking. It's got pretty big ++ * internal buffers (handles most of a frame's worth of data). ++ * Chip data sheets don't describe any vendor control messages. ++ * ++ *-------------------------------------------------------------------------*/ ++ ++static const struct driver_info an2720_info = { ++ .description = "AnchorChips/Cypress 2720", ++ .flags = FLAG_POINTTOPOINT, ++ // no reset available! ++ // no check_connect available! ++ ++ .in = 2, .out = 2, // direction distinguishes these ++}; ++ ++#endif /* CONFIG_USB_AN2720 */ ++ ++ ++#ifdef CONFIG_USB_BELKIN ++#define HAVE_HARDWARE ++ ++/*------------------------------------------------------------------------- ++ * ++ * Belkin F5U104 ... two NetChip 2280 devices + Atmel AVR microcontroller ++ * ++ * ... also two eTEK designs, including one sold as "Advance USBNET" ++ * ++ *-------------------------------------------------------------------------*/ ++ ++static const struct driver_info belkin_info = { ++ .description = "Belkin, eTEK, or compatible", ++ .flags = FLAG_POINTTOPOINT, ++}; ++ ++#endif /* CONFIG_USB_BELKIN */ ++ ++ ++ ++#ifdef CONFIG_USB_EPSON2888 ++#define HAVE_HARDWARE ++ ++/*------------------------------------------------------------------------- ++ * ++ * EPSON USB clients ++ * ++ * This is the same idea as Linux PDAs (below) except the firmware in the ++ * device might not be Tux-powered. Epson provides reference firmware that ++ * implements this interface. Product developers can reuse or modify that ++ * code, such as by using their own product and vendor codes. ++ * ++ * Support was from Juro Bystricky bystricky.juro@erd.epson.com ++ * ++ *-------------------------------------------------------------------------*/ ++ ++static const struct driver_info epson2888_info = { ++ .description = "Epson USB Device", ++ .check_connect = always_connected, ++ .flags = FLAG_POINTTOPOINT, ++ ++ .in = 4, .out = 3, ++}; ++ ++#endif /* CONFIG_USB_EPSON2888 */ ++ ++ ++/*------------------------------------------------------------------------- ++ * ++ * info from Jonathan McDowell noodles@earth.li ++ * ++ *-------------------------------------------------------------------------*/ ++#ifdef CONFIG_USB_KC2190 ++#define HAVE_HARDWARE ++static const struct driver_info kc2190_info = { ++ .description = "KC Technology KC-190", ++ .flags = FLAG_POINTTOPOINT, ++}; ++#endif /* CONFIG_USB_KC2190 */ ++ ++ ++#ifdef CONFIG_USB_ARMLINUX ++#define HAVE_HARDWARE ++ ++/*------------------------------------------------------------------------- ++ * ++ * Intel's SA-1100 chip integrates basic USB support, and is used ++ * in PDAs like some iPaqs, the Yopy, some Zaurus models, and more. ++ * When they run Linux, arch/arm/mach-sa1100/usb-eth.c may be used to ++ * network using minimal USB framing data. ++ * ++ * This describes the driver currently in standard ARM Linux kernels. ++ * The Zaurus uses a different driver (see later). ++ * ++ * PXA25x and PXA210 use XScale cores (ARM v5TE) with better USB support ++ * and different USB endpoint numbering than the SA1100 devices. The ++ * mach-pxa/usb-eth.c driver re-uses the device ids from mach-sa1100 ++ * so we rely on the endpoint descriptors. ++ * ++ *-------------------------------------------------------------------------*/ ++ ++static const struct driver_info linuxdev_info = { ++ .description = "Linux Device", ++ .check_connect = always_connected, ++ .flags = FLAG_POINTTOPOINT, ++}; ++ ++static const struct driver_info yopy_info = { ++ .description = "Yopy", ++ .check_connect = always_connected, ++ .flags = FLAG_POINTTOPOINT, ++}; ++ ++static const struct driver_info blob_info = { ++ .description = "Boot Loader OBject", ++ .check_connect = always_connected, ++ .flags = FLAG_POINTTOPOINT, ++}; ++ ++#endif /* CONFIG_USB_ARMLINUX */ ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++#ifndef HAVE_HARDWARE ++#warning You need to configure some hardware for this driver ++#endif ++ ++/* ++ * chip vendor names won't normally be on the cables, and ++ * may not be on the device. ++ */ ++ ++static const struct usb_device_id products [] = { ++ ++#ifdef CONFIG_USB_ALI_M5632 ++{ ++ USB_DEVICE (0x0402, 0x5632), // ALi defaults ++ .driver_info = (unsigned long) &ali_m5632_info, ++}, ++{ ++ USB_DEVICE (0x182d,0x207c), // SiteCom CN-124 ++ .driver_info = (unsigned long) &ali_m5632_info, ++}, ++#endif ++ ++#ifdef CONFIG_USB_AN2720 ++{ ++ USB_DEVICE (0x0547, 0x2720), // AnchorChips defaults ++ .driver_info = (unsigned long) &an2720_info, ++}, { ++ USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET ++ .driver_info = (unsigned long) &an2720_info, ++}, ++#endif ++ ++#ifdef CONFIG_USB_BELKIN ++{ ++ USB_DEVICE (0x050d, 0x0004), // Belkin ++ .driver_info = (unsigned long) &belkin_info, ++}, { ++ USB_DEVICE (0x056c, 0x8100), // eTEK ++ .driver_info = (unsigned long) &belkin_info, ++}, { ++ USB_DEVICE (0x0525, 0x9901), // Advance USBNET (eTEK) ++ .driver_info = (unsigned long) &belkin_info, ++}, ++#endif ++ ++#ifdef CONFIG_USB_EPSON2888 ++{ ++ USB_DEVICE (0x0525, 0x2888), // EPSON USB client ++ .driver_info = (unsigned long) &epson2888_info, ++}, ++#endif ++ ++#ifdef CONFIG_USB_KC2190 ++{ ++ USB_DEVICE (0x050f, 0x0190), // KC-190 ++ .driver_info = (unsigned long) &kc2190_info, ++}, ++#endif ++ ++#ifdef CONFIG_USB_ARMLINUX ++/* ++ * SA-1100 using standard ARM Linux kernels, or compatible. ++ * Often used when talking to Linux PDAs (iPaq, Yopy, etc). ++ * The sa-1100 "usb-eth" driver handles the basic framing. ++ * ++ * PXA25x or PXA210 ... these use a "usb-eth" driver much like ++ * the sa1100 one, but hardware uses different endpoint numbers. ++ * ++ * Or the Linux "Ethernet" gadget on hardware that can't talk ++ * CDC Ethernet (e.g., no altsettings), in either of two modes: ++ * - acting just like the old "usb-eth" firmware, though ++ * the implementation is different ++ * - supporting RNDIS as the first/default configuration for ++ * MS-Windows interop; Linux needs to use the other config ++ */ ++{ ++ // 1183 = 0x049F, both used as hex values? ++ // Compaq "Itsy" vendor/product id ++ USB_DEVICE (0x049F, 0x505A), // usb-eth, or compatible ++ .driver_info = (unsigned long) &linuxdev_info, ++}, { ++ USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy" ++ .driver_info = (unsigned long) &yopy_info, ++}, { ++ USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader ++ .driver_info = (unsigned long) &blob_info, ++}, { ++ USB_DEVICE (0x1286, 0x8001), // "blob" bootloader ++ .driver_info = (unsigned long) &blob_info, ++}, { ++ // Linux Ethernet/RNDIS gadget, mostly on PXA, second config ++ // e.g. Gumstix, current OpenZaurus, ... or anything else ++ // that just enables this gadget option. ++ USB_DEVICE (0x0525, 0xa4a2), ++ .driver_info = (unsigned long) &linuxdev_info, ++}, ++#endif ++ ++ { }, // END ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++/*-------------------------------------------------------------------------*/ ++static int dummy_prereset(struct usb_interface *intf) ++{ ++ return 0; ++} ++ ++static int dummy_postreset(struct usb_interface *intf) ++{ ++ return 0; ++} ++ ++static struct usb_driver cdc_subset_driver = { ++ .name = "cdc_subset", ++ .probe = usbnet_probe, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .pre_reset = dummy_prereset, ++ .post_reset = dummy_postreset, ++ .disconnect = usbnet_disconnect, ++ .id_table = products, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(cdc_subset_driver); ++ ++MODULE_AUTHOR("David Brownell"); ++MODULE_DESCRIPTION("Simple 'CDC Subset' USB networking links"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/cx82310_eth.c backports-3.18.1-1/drivers/net/usb/cx82310_eth.c +--- backports-3.18.1-1.org/drivers/net/usb/cx82310_eth.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/cx82310_eth.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,326 @@ ++/* ++ * Driver for USB ethernet port of Conexant CX82310-based ADSL routers ++ * Copyright (C) 2010 by Ondrej Zary ++ * some parts inspired by the cxacru driver ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/usb/usbnet.h> ++ ++enum cx82310_cmd { ++ CMD_START = 0x84, /* no effect? */ ++ CMD_STOP = 0x85, /* no effect? */ ++ CMD_GET_STATUS = 0x90, /* returns nothing? */ ++ CMD_GET_MAC_ADDR = 0x91, /* read MAC address */ ++ CMD_GET_LINK_STATUS = 0x92, /* not useful, link is always up */ ++ CMD_ETHERNET_MODE = 0x99, /* unknown, needed during init */ ++}; ++ ++enum cx82310_status { ++ STATUS_UNDEFINED, ++ STATUS_SUCCESS, ++ STATUS_ERROR, ++ STATUS_UNSUPPORTED, ++ STATUS_UNIMPLEMENTED, ++ STATUS_PARAMETER_ERROR, ++ STATUS_DBG_LOOPBACK, ++}; ++ ++#define CMD_PACKET_SIZE 64 ++/* first command after power on can take around 8 seconds */ ++#define CMD_TIMEOUT 15000 ++#define CMD_REPLY_RETRY 5 ++ ++#define CX82310_MTU 1514 ++#define CMD_EP 0x01 ++ ++/* ++ * execute control command ++ * - optionally send some data (command parameters) ++ * - optionally wait for the reply ++ * - optionally read some data from the reply ++ */ ++static int cx82310_cmd(struct usbnet *dev, enum cx82310_cmd cmd, bool reply, ++ u8 *wdata, int wlen, u8 *rdata, int rlen) ++{ ++ int actual_len, retries, ret; ++ struct usb_device *udev = dev->udev; ++ u8 *buf = kzalloc(CMD_PACKET_SIZE, GFP_KERNEL); ++ ++ if (!buf) ++ return -ENOMEM; ++ ++ /* create command packet */ ++ buf[0] = cmd; ++ if (wdata) ++ memcpy(buf + 4, wdata, min_t(int, wlen, CMD_PACKET_SIZE - 4)); ++ ++ /* send command packet */ ++ ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, CMD_EP), buf, ++ CMD_PACKET_SIZE, &actual_len, CMD_TIMEOUT); ++ if (ret < 0) { ++ dev_err(&dev->udev->dev, "send command %#x: error %d\n", ++ cmd, ret); ++ goto end; ++ } ++ ++ if (reply) { ++ /* wait for reply, retry if it's empty */ ++ for (retries = 0; retries < CMD_REPLY_RETRY; retries++) { ++ ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, CMD_EP), ++ buf, CMD_PACKET_SIZE, &actual_len, ++ CMD_TIMEOUT); ++ if (ret < 0) { ++ dev_err(&dev->udev->dev, ++ "reply receive error %d\n", ret); ++ goto end; ++ } ++ if (actual_len > 0) ++ break; ++ } ++ if (actual_len == 0) { ++ dev_err(&dev->udev->dev, "no reply to command %#x\n", ++ cmd); ++ ret = -EIO; ++ goto end; ++ } ++ if (buf[0] != cmd) { ++ dev_err(&dev->udev->dev, ++ "got reply to command %#x, expected: %#x\n", ++ buf[0], cmd); ++ ret = -EIO; ++ goto end; ++ } ++ if (buf[1] != STATUS_SUCCESS) { ++ dev_err(&dev->udev->dev, "command %#x failed: %#x\n", ++ cmd, buf[1]); ++ ret = -EIO; ++ goto end; ++ } ++ if (rdata) ++ memcpy(rdata, buf + 4, ++ min_t(int, rlen, CMD_PACKET_SIZE - 4)); ++ } ++end: ++ kfree(buf); ++ return ret; ++} ++ ++#define partial_len data[0] /* length of partial packet data */ ++#define partial_rem data[1] /* remaining (missing) data length */ ++#define partial_data data[2] /* partial packet data */ ++ ++static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int ret; ++ char buf[15]; ++ struct usb_device *udev = dev->udev; ++ ++ /* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */ ++ if (usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) > 0 ++ && strcmp(buf, "USB NET CARD")) { ++ dev_info(&udev->dev, "ignoring: probably an ADSL modem\n"); ++ return -ENODEV; ++ } ++ ++ ret = usbnet_get_endpoints(dev, intf); ++ if (ret) ++ return ret; ++ ++ /* ++ * this must not include ethernet header as the device can send partial ++ * packets with no header (and sometimes even empty URBs) ++ */ ++ dev->net->hard_header_len = 0; ++ /* we can send at most 1514 bytes of data (+ 2-byte header) per URB */ ++ dev->hard_mtu = CX82310_MTU + 2; ++ /* we can receive URBs up to 4KB from the device */ ++ dev->rx_urb_size = 4096; ++ ++ dev->partial_data = (unsigned long) kmalloc(dev->hard_mtu, GFP_KERNEL); ++ if (!dev->partial_data) ++ return -ENOMEM; ++ ++ /* enable ethernet mode (?) */ ++ ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0); ++ if (ret) { ++ dev_err(&udev->dev, "unable to enable ethernet mode: %d\n", ++ ret); ++ goto err; ++ } ++ ++ /* get the MAC address */ ++ ret = cx82310_cmd(dev, CMD_GET_MAC_ADDR, true, NULL, 0, ++ dev->net->dev_addr, ETH_ALEN); ++ if (ret) { ++ dev_err(&udev->dev, "unable to read MAC address: %d\n", ret); ++ goto err; ++ } ++ ++ /* start (does not seem to have any effect?) */ ++ ret = cx82310_cmd(dev, CMD_START, false, NULL, 0, NULL, 0); ++ if (ret) ++ goto err; ++ ++ return 0; ++err: ++ kfree((void *)dev->partial_data); ++ return ret; ++} ++ ++static void cx82310_unbind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ kfree((void *)dev->partial_data); ++} ++ ++/* ++ * RX is NOT easy - we can receive multiple packets per skb, each having 2-byte ++ * packet length at the beginning. ++ * The last packet might be incomplete (when it crosses the 4KB URB size), ++ * continuing in the next skb (without any headers). ++ * If a packet has odd length, there is one extra byte at the end (before next ++ * packet or at the end of the URB). ++ */ ++static int cx82310_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ int len; ++ struct sk_buff *skb2; ++ ++ /* ++ * If the last skb ended with an incomplete packet, this skb contains ++ * end of that packet at the beginning. ++ */ ++ if (dev->partial_rem) { ++ len = dev->partial_len + dev->partial_rem; ++ skb2 = alloc_skb(len, GFP_ATOMIC); ++ if (!skb2) ++ return 0; ++ skb_put(skb2, len); ++ memcpy(skb2->data, (void *)dev->partial_data, ++ dev->partial_len); ++ memcpy(skb2->data + dev->partial_len, skb->data, ++ dev->partial_rem); ++ usbnet_skb_return(dev, skb2); ++ skb_pull(skb, (dev->partial_rem + 1) & ~1); ++ dev->partial_rem = 0; ++ if (skb->len < 2) ++ return 1; ++ } ++ ++ /* a skb can contain multiple packets */ ++ while (skb->len > 1) { ++ /* first two bytes are packet length */ ++ len = skb->data[0] | (skb->data[1] << 8); ++ skb_pull(skb, 2); ++ ++ /* if last packet in the skb, let usbnet to process it */ ++ if (len == skb->len || len + 1 == skb->len) { ++ skb_trim(skb, len); ++ break; ++ } ++ ++ if (len > CX82310_MTU) { ++ dev_err(&dev->udev->dev, "RX packet too long: %d B\n", ++ len); ++ return 0; ++ } ++ ++ /* incomplete packet, save it for the next skb */ ++ if (len > skb->len) { ++ dev->partial_len = skb->len; ++ dev->partial_rem = len - skb->len; ++ memcpy((void *)dev->partial_data, skb->data, ++ dev->partial_len); ++ skb_pull(skb, skb->len); ++ break; ++ } ++ ++ skb2 = alloc_skb(len, GFP_ATOMIC); ++ if (!skb2) ++ return 0; ++ skb_put(skb2, len); ++ memcpy(skb2->data, skb->data, len); ++ /* process the packet */ ++ usbnet_skb_return(dev, skb2); ++ ++ skb_pull(skb, (len + 1) & ~1); ++ } ++ ++ /* let usbnet process the last packet */ ++ return 1; ++} ++ ++/* TX is easy, just add 2 bytes of length at the beginning */ ++static struct sk_buff *cx82310_tx_fixup(struct usbnet *dev, struct sk_buff *skb, ++ gfp_t flags) ++{ ++ int len = skb->len; ++ ++ if (skb_headroom(skb) < 2) { ++ struct sk_buff *skb2 = skb_copy_expand(skb, 2, 0, flags); ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ if (!skb) ++ return NULL; ++ } ++ skb_push(skb, 2); ++ ++ skb->data[0] = len; ++ skb->data[1] = len >> 8; ++ ++ return skb; ++} ++ ++ ++static const struct driver_info cx82310_info = { ++ .description = "Conexant CX82310 USB ethernet", ++ .flags = FLAG_ETHER, ++ .bind = cx82310_bind, ++ .unbind = cx82310_unbind, ++ .rx_fixup = cx82310_rx_fixup, ++ .tx_fixup = cx82310_tx_fixup, ++}; ++ ++static const struct usb_device_id products[] = { ++ { ++ USB_DEVICE_AND_INTERFACE_INFO(0x0572, 0xcb01, 0xff, 0, 0), ++ .driver_info = (unsigned long) &cx82310_info ++ }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver cx82310_driver = { ++ .name = "cx82310_eth", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(cx82310_driver); ++ ++MODULE_AUTHOR("Ondrej Zary"); ++MODULE_DESCRIPTION("Conexant CX82310-based ADSL router USB ethernet driver"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/dm9601.c backports-3.18.1-1/drivers/net/usb/dm9601.c +--- backports-3.18.1-1.org/drivers/net/usb/dm9601.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/dm9601.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,647 @@ ++/* ++ * Davicom DM96xx USB 10/100Mbps ethernet devices ++ * ++ * Peter Korsgaard jacmet@sunsite.dk ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++//#define DEBUG ++ ++#include <linux/module.h> ++#include <linux/sched.h> ++#include <linux/stddef.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/crc32.h> ++#include <linux/usb/usbnet.h> ++#include <linux/slab.h> ++ ++/* datasheet: ++ http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914... ++*/ ++ ++/* control requests */ ++#define DM_READ_REGS 0x00 ++#define DM_WRITE_REGS 0x01 ++#define DM_READ_MEMS 0x02 ++#define DM_WRITE_REG 0x03 ++#define DM_WRITE_MEMS 0x05 ++#define DM_WRITE_MEM 0x07 ++ ++/* registers */ ++#define DM_NET_CTRL 0x00 ++#define DM_RX_CTRL 0x05 ++#define DM_SHARED_CTRL 0x0b ++#define DM_SHARED_ADDR 0x0c ++#define DM_SHARED_DATA 0x0d /* low + high */ ++#define DM_PHY_ADDR 0x10 /* 6 bytes */ ++#define DM_MCAST_ADDR 0x16 /* 8 bytes */ ++#define DM_GPR_CTRL 0x1e ++#define DM_GPR_DATA 0x1f ++#define DM_CHIP_ID 0x2c ++#define DM_MODE_CTRL 0x91 /* only on dm9620 */ ++ ++/* chip id values */ ++#define ID_DM9601 0 ++#define ID_DM9620 1 ++ ++#define DM_MAX_MCAST 64 ++#define DM_MCAST_SIZE 8 ++#define DM_EEPROM_LEN 256 ++#define DM_TX_OVERHEAD 2 /* 2 byte header */ ++#define DM_RX_OVERHEAD 7 /* 3 byte header + 4 byte crc tail */ ++#define DM_TIMEOUT 1000 ++ ++static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data) ++{ ++ int err; ++ err = usbnet_read_cmd(dev, DM_READ_REGS, ++ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ 0, reg, data, length); ++ if(err != length && err >= 0) ++ err = -EINVAL; ++ return err; ++} ++ ++static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value) ++{ ++ return dm_read(dev, reg, 1, value); ++} ++ ++static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data) ++{ ++ int err; ++ err = usbnet_write_cmd(dev, DM_WRITE_REGS, ++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ 0, reg, data, length); ++ ++ if (err >= 0 && err < length) ++ err = -EINVAL; ++ return err; ++} ++ ++static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value) ++{ ++ return usbnet_write_cmd(dev, DM_WRITE_REG, ++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ value, reg, NULL, 0); ++} ++ ++static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) ++{ ++ usbnet_write_cmd_async(dev, DM_WRITE_REGS, ++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ 0, reg, data, length); ++} ++ ++static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value) ++{ ++ usbnet_write_cmd_async(dev, DM_WRITE_REG, ++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ value, reg, NULL, 0); ++} ++ ++static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *value) ++{ ++ int ret, i; ++ ++ mutex_lock(&dev->phy_mutex); ++ ++ dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg); ++ dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0xc : 0x4); ++ ++ for (i = 0; i < DM_TIMEOUT; i++) { ++ u8 tmp = 0; ++ ++ udelay(1); ++ ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp); ++ if (ret < 0) ++ goto out; ++ ++ /* ready */ ++ if ((tmp & 1) == 0) ++ break; ++ } ++ ++ if (i == DM_TIMEOUT) { ++ netdev_err(dev->net, "%s read timed out!\n", phy ? "phy" : "eeprom"); ++ ret = -EIO; ++ goto out; ++ } ++ ++ dm_write_reg(dev, DM_SHARED_CTRL, 0x0); ++ ret = dm_read(dev, DM_SHARED_DATA, 2, value); ++ ++ netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n", ++ phy, reg, *value, ret); ++ ++ out: ++ mutex_unlock(&dev->phy_mutex); ++ return ret; ++} ++ ++static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 value) ++{ ++ int ret, i; ++ ++ mutex_lock(&dev->phy_mutex); ++ ++ ret = dm_write(dev, DM_SHARED_DATA, 2, &value); ++ if (ret < 0) ++ goto out; ++ ++ dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg); ++ dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1a : 0x12); ++ ++ for (i = 0; i < DM_TIMEOUT; i++) { ++ u8 tmp = 0; ++ ++ udelay(1); ++ ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp); ++ if (ret < 0) ++ goto out; ++ ++ /* ready */ ++ if ((tmp & 1) == 0) ++ break; ++ } ++ ++ if (i == DM_TIMEOUT) { ++ netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom"); ++ ret = -EIO; ++ goto out; ++ } ++ ++ dm_write_reg(dev, DM_SHARED_CTRL, 0x0); ++ ++out: ++ mutex_unlock(&dev->phy_mutex); ++ return ret; ++} ++ ++static int dm_read_eeprom_word(struct usbnet *dev, u8 offset, void *value) ++{ ++ return dm_read_shared_word(dev, 0, offset, value); ++} ++ ++ ++ ++static int dm9601_get_eeprom_len(struct net_device *dev) ++{ ++ return DM_EEPROM_LEN; ++} ++ ++static int dm9601_get_eeprom(struct net_device *net, ++ struct ethtool_eeprom *eeprom, u8 * data) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ __le16 *ebuf = (__le16 *) data; ++ int i; ++ ++ /* access is 16bit */ ++ if ((eeprom->offset % 2) || (eeprom->len % 2)) ++ return -EINVAL; ++ ++ for (i = 0; i < eeprom->len / 2; i++) { ++ if (dm_read_eeprom_word(dev, eeprom->offset / 2 + i, ++ &ebuf[i]) < 0) ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int dm9601_mdio_read(struct net_device *netdev, int phy_id, int loc) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ ++ __le16 res; ++ ++ if (phy_id) { ++ netdev_dbg(dev->net, "Only internal phy supported\n"); ++ return 0; ++ } ++ ++ dm_read_shared_word(dev, 1, loc, &res); ++ ++ netdev_dbg(dev->net, ++ "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", ++ phy_id, loc, le16_to_cpu(res)); ++ ++ return le16_to_cpu(res); ++} ++ ++static void dm9601_mdio_write(struct net_device *netdev, int phy_id, int loc, ++ int val) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ __le16 res = cpu_to_le16(val); ++ ++ if (phy_id) { ++ netdev_dbg(dev->net, "Only internal phy supported\n"); ++ return; ++ } ++ ++ netdev_dbg(dev->net, "dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", ++ phy_id, loc, val); ++ ++ dm_write_shared_word(dev, 1, loc, res); ++} ++ ++static void dm9601_get_drvinfo(struct net_device *net, ++ struct ethtool_drvinfo *info) ++{ ++ /* Inherit standard device info */ ++ usbnet_get_drvinfo(net, info); ++ info->eedump_len = DM_EEPROM_LEN; ++} ++ ++static u32 dm9601_get_link(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ return mii_link_ok(&dev->mii); ++} ++ ++static int dm9601_ioctl(struct net_device *net, struct ifreq *rq, int cmd) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); ++} ++ ++static const struct ethtool_ops dm9601_ethtool_ops = { ++ .get_drvinfo = dm9601_get_drvinfo, ++ .get_link = dm9601_get_link, ++ .get_msglevel = usbnet_get_msglevel, ++ .set_msglevel = usbnet_set_msglevel, ++ .get_eeprom_len = dm9601_get_eeprom_len, ++ .get_eeprom = dm9601_get_eeprom, ++ .get_settings = usbnet_get_settings, ++ .set_settings = usbnet_set_settings, ++ .nway_reset = usbnet_nway_reset, ++}; ++ ++static void dm9601_set_multicast(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ /* We use the 20 byte dev->data for our 8 byte filter buffer ++ * to avoid allocating memory that is tricky to free later */ ++ u8 *hashes = (u8 *) & dev->data; ++ u8 rx_ctl = 0x31; ++ ++ memset(hashes, 0x00, DM_MCAST_SIZE); ++ hashes[DM_MCAST_SIZE - 1] |= 0x80; /* broadcast address */ ++ ++ if (net->flags & IFF_PROMISC) { ++ rx_ctl |= 0x02; ++ } else if (net->flags & IFF_ALLMULTI || ++ netdev_mc_count(net) > DM_MAX_MCAST) { ++ rx_ctl |= 0x08; ++ } else if (!netdev_mc_empty(net)) { ++ struct netdev_hw_addr *ha; ++ ++ netdev_for_each_mc_addr(ha, net) { ++ u32 crc = ether_crc(ETH_ALEN, ha->addr) >> 26; ++ hashes[crc >> 3] |= 1 << (crc & 0x7); ++ } ++ } ++ ++ dm_write_async(dev, DM_MCAST_ADDR, DM_MCAST_SIZE, hashes); ++ dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl); ++} ++ ++static void __dm9601_set_mac_address(struct usbnet *dev) ++{ ++ dm_write_async(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr); ++} ++ ++static int dm9601_set_mac_address(struct net_device *net, void *p) ++{ ++ struct sockaddr *addr = p; ++ struct usbnet *dev = netdev_priv(net); ++ ++ if (!is_valid_ether_addr(addr->sa_data)) { ++ dev_err(&net->dev, "not setting invalid mac address %pM\n", ++ addr->sa_data); ++ return -EINVAL; ++ } ++ ++ memcpy(net->dev_addr, addr->sa_data, net->addr_len); ++ __dm9601_set_mac_address(dev); ++ ++ return 0; ++} ++ ++static const struct net_device_ops dm9601_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = usbnet_change_mtu, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = dm9601_ioctl, ++ .ndo_set_rx_mode = dm9601_set_multicast, ++ .ndo_set_mac_address = dm9601_set_mac_address, ++}; ++ ++static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int ret; ++ u8 mac[ETH_ALEN], id; ++ ++ ret = usbnet_get_endpoints(dev, intf); ++ if (ret) ++ goto out; ++ ++ dev->net->netdev_ops = &dm9601_netdev_ops; ++ dev->net->ethtool_ops = &dm9601_ethtool_ops; ++ dev->net->hard_header_len += DM_TX_OVERHEAD; ++ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; ++ ++ /* dm9620/21a require room for 4 byte padding, even in dm9601 ++ * mode, so we need +1 to be able to receive full size ++ * ethernet frames. ++ */ ++ dev->rx_urb_size = dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD + 1; ++ ++ dev->mii.dev = dev->net; ++ dev->mii.mdio_read = dm9601_mdio_read; ++ dev->mii.mdio_write = dm9601_mdio_write; ++ dev->mii.phy_id_mask = 0x1f; ++ dev->mii.reg_num_mask = 0x1f; ++ ++ /* reset */ ++ dm_write_reg(dev, DM_NET_CTRL, 1); ++ udelay(20); ++ ++ /* read MAC */ ++ if (dm_read(dev, DM_PHY_ADDR, ETH_ALEN, mac) < 0) { ++ printk(KERN_ERR "Error reading MAC address\n"); ++ ret = -ENODEV; ++ goto out; ++ } ++ ++ /* ++ * Overwrite the auto-generated address only with good ones. ++ */ ++ if (is_valid_ether_addr(mac)) ++ memcpy(dev->net->dev_addr, mac, ETH_ALEN); ++ else { ++ printk(KERN_WARNING ++ "dm9601: No valid MAC address in EEPROM, using %pM\n", ++ dev->net->dev_addr); ++ __dm9601_set_mac_address(dev); ++ } ++ ++ if (dm_read_reg(dev, DM_CHIP_ID, &id) < 0) { ++ netdev_err(dev->net, "Error reading chip ID\n"); ++ ret = -ENODEV; ++ goto out; ++ } ++ ++ /* put dm9620 devices in dm9601 mode */ ++ if (id == ID_DM9620) { ++ u8 mode; ++ ++ if (dm_read_reg(dev, DM_MODE_CTRL, &mode) < 0) { ++ netdev_err(dev->net, "Error reading MODE_CTRL\n"); ++ ret = -ENODEV; ++ goto out; ++ } ++ dm_write_reg(dev, DM_MODE_CTRL, mode & 0x7f); ++ } ++ ++ /* power up phy */ ++ dm_write_reg(dev, DM_GPR_CTRL, 1); ++ dm_write_reg(dev, DM_GPR_DATA, 0); ++ ++ /* receive broadcast packets */ ++ dm9601_set_multicast(dev->net); ++ ++ dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); ++ dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ++ ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); ++ mii_nway_restart(&dev->mii); ++ ++out: ++ return ret; ++} ++ ++static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ u8 status; ++ int len; ++ ++ /* format: ++ b1: rx status ++ b2: packet length (incl crc) low ++ b3: packet length (incl crc) high ++ b4..n-4: packet data ++ bn-3..bn: ethernet crc ++ */ ++ ++ if (unlikely(skb->len < DM_RX_OVERHEAD)) { ++ dev_err(&dev->udev->dev, "unexpected tiny rx frame\n"); ++ return 0; ++ } ++ ++ status = skb->data[0]; ++ len = (skb->data[1] | (skb->data[2] << 8)) - 4; ++ ++ if (unlikely(status & 0xbf)) { ++ if (status & 0x01) dev->net->stats.rx_fifo_errors++; ++ if (status & 0x02) dev->net->stats.rx_crc_errors++; ++ if (status & 0x04) dev->net->stats.rx_frame_errors++; ++ if (status & 0x20) dev->net->stats.rx_missed_errors++; ++ if (status & 0x90) dev->net->stats.rx_length_errors++; ++ return 0; ++ } ++ ++ skb_pull(skb, 3); ++ skb_trim(skb, len); ++ ++ return 1; ++} ++ ++static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, ++ gfp_t flags) ++{ ++ int len, pad; ++ ++ /* format: ++ b1: packet length low ++ b2: packet length high ++ b3..n: packet data ++ */ ++ ++ len = skb->len + DM_TX_OVERHEAD; ++ ++ /* workaround for dm962x errata with tx fifo getting out of ++ * sync if a USB bulk transfer retry happens right after a ++ * packet with odd / maxpacket length by adding up to 3 bytes ++ * padding. ++ */ ++ while ((len & 1) || !(len % dev->maxpacket)) ++ len++; ++ ++ len -= DM_TX_OVERHEAD; /* hw header doesn't count as part of length */ ++ pad = len - skb->len; ++ ++ if (skb_headroom(skb) < DM_TX_OVERHEAD || skb_tailroom(skb) < pad) { ++ struct sk_buff *skb2; ++ ++ skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, pad, flags); ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ if (!skb) ++ return NULL; ++ } ++ ++ __skb_push(skb, DM_TX_OVERHEAD); ++ ++ if (pad) { ++ memset(skb->data + skb->len, 0, pad); ++ __skb_put(skb, pad); ++ } ++ ++ skb->data[0] = len; ++ skb->data[1] = len >> 8; ++ ++ return skb; ++} ++ ++static void dm9601_status(struct usbnet *dev, struct urb *urb) ++{ ++ int link; ++ u8 *buf; ++ ++ /* format: ++ b0: net status ++ b1: tx status 1 ++ b2: tx status 2 ++ b3: rx status ++ b4: rx overflow ++ b5: rx count ++ b6: tx count ++ b7: gpr ++ */ ++ ++ if (urb->actual_length < 8) ++ return; ++ ++ buf = urb->transfer_buffer; ++ ++ link = !!(buf[0] & 0x40); ++ if (netif_carrier_ok(dev->net) != link) { ++ usbnet_link_change(dev, link, 1); ++ netdev_dbg(dev->net, "Link Status is: %d\n", link); ++ } ++} ++ ++static int dm9601_link_reset(struct usbnet *dev) ++{ ++ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; ++ ++ mii_check_media(&dev->mii, 1, 1); ++ mii_ethtool_gset(&dev->mii, &ecmd); ++ ++ netdev_dbg(dev->net, "link_reset() speed: %u duplex: %d\n", ++ ethtool_cmd_speed(&ecmd), ecmd.duplex); ++ ++ return 0; ++} ++ ++static const struct driver_info dm9601_info = { ++ .description = "Davicom DM96xx USB 10/100 Ethernet", ++ .flags = FLAG_ETHER | FLAG_LINK_INTR, ++ .bind = dm9601_bind, ++ .rx_fixup = dm9601_rx_fixup, ++ .tx_fixup = dm9601_tx_fixup, ++ .status = dm9601_status, ++ .link_reset = dm9601_link_reset, ++ .reset = dm9601_link_reset, ++}; ++ ++static const struct usb_device_id products[] = { ++ { ++ USB_DEVICE(0x07aa, 0x9601), /* Corega FEther USB-TXC */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0a46, 0x9601), /* Davicom USB-100 */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0a46, 0x6688), /* ZT6688 USB NIC */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0a46, 0x0268), /* ShanTou ST268 USB NIC */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0a46, 0x8515), /* ADMtek ADM8515 USB NIC */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0a47, 0x9601), /* Hirose USB-100 */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0fe6, 0x8101), /* DM9601 USB to Fast Ethernet Adapter */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0fe6, 0x9700), /* DM9601 USB to Fast Ethernet Adapter */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0a46, 0x9000), /* DM9000E */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0a46, 0x9620), /* DM9620 USB to Fast Ethernet Adapter */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0a46, 0x9621), /* DM9621A USB to Fast Ethernet Adapter */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0a46, 0x9622), /* DM9622 USB to Fast Ethernet Adapter */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0a46, 0x0269), /* DM962OA USB to Fast Ethernet Adapter */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ { ++ USB_DEVICE(0x0a46, 0x1269), /* DM9621A USB to Fast Ethernet Adapter */ ++ .driver_info = (unsigned long)&dm9601_info, ++ }, ++ {}, // END ++}; ++ ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver dm9601_driver = { ++ .name = "dm9601", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(dm9601_driver); ++ ++MODULE_AUTHOR("Peter Korsgaard jacmet@sunsite.dk"); ++MODULE_DESCRIPTION("Davicom DM96xx USB 10/100 ethernet devices"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/gl620a.c backports-3.18.1-1/drivers/net/usb/gl620a.c +--- backports-3.18.1-1.org/drivers/net/usb/gl620a.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/gl620a.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,242 @@ ++/* ++ * GeneSys GL620USB-A based links ++ * Copyright (C) 2001 by Jiun-Jie Huang huangjj@genesyslogic.com.tw ++ * Copyright (C) 2001 by Stanislav Brabec utx@penguin.cz ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++// #define DEBUG // error path messages, extra info ++// #define VERBOSE // more; success messages ++ ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/usb/usbnet.h> ++#include <linux/gfp.h> ++ ++ ++/* ++ * GeneSys GL620USB-A (www.genesyslogic.com.tw) ++ * ++ * ... should partially interop with the Win32 driver for this hardware. ++ * The GeneSys docs imply there's some NDIS issue motivating this framing. ++ * ++ * Some info from GeneSys: ++ * - GL620USB-A is full duplex; GL620USB is only half duplex for bulk. ++ * (Some cables, like the BAFO-100c, use the half duplex version.) ++ * - For the full duplex model, the low bit of the version code says ++ * which side is which ("left/right"). ++ * - For the half duplex type, a control/interrupt handshake settles ++ * the transfer direction. (That's disabled here, partially coded.) ++ * A control URB would block until other side writes an interrupt. ++ * ++ * Original code from Jiun-Jie Huang huangjj@genesyslogic.com.tw ++ * and merged into "usbnet" by Stanislav Brabec utx@penguin.cz. ++ */ ++ ++// control msg write command ++#define GENELINK_CONNECT_WRITE 0xF0 ++// interrupt pipe index ++#define GENELINK_INTERRUPT_PIPE 0x03 ++// interrupt read buffer size ++#define INTERRUPT_BUFSIZE 0x08 ++// interrupt pipe interval value ++#define GENELINK_INTERRUPT_INTERVAL 0x10 ++// max transmit packet number per transmit ++#define GL_MAX_TRANSMIT_PACKETS 32 ++// max packet length ++#define GL_MAX_PACKET_LEN 1514 ++// max receive buffer size ++#define GL_RCV_BUF_SIZE \ ++ (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4) ++ ++struct gl_packet { ++ __le32 packet_length; ++ char packet_data [1]; ++}; ++ ++struct gl_header { ++ __le32 packet_count; ++ struct gl_packet packets; ++}; ++ ++static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ struct gl_header *header; ++ struct gl_packet *packet; ++ struct sk_buff *gl_skb; ++ u32 size; ++ u32 count; ++ ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ ++ header = (struct gl_header *) skb->data; ++ ++ // get the packet count of the received skb ++ count = le32_to_cpu(header->packet_count); ++ if (count > GL_MAX_TRANSMIT_PACKETS) { ++ netdev_dbg(dev->net, ++ "genelink: invalid received packet count %u\n", ++ count); ++ return 0; ++ } ++ ++ // set the current packet pointer to the first packet ++ packet = &header->packets; ++ ++ // decrement the length for the packet count size 4 bytes ++ skb_pull(skb, 4); ++ ++ while (count > 1) { ++ // get the packet length ++ size = le32_to_cpu(packet->packet_length); ++ ++ // this may be a broken packet ++ if (size > GL_MAX_PACKET_LEN) { ++ netdev_dbg(dev->net, "genelink: invalid rx length %d\n", ++ size); ++ return 0; ++ } ++ ++ // allocate the skb for the individual packet ++ gl_skb = alloc_skb(size, GFP_ATOMIC); ++ if (gl_skb) { ++ ++ // copy the packet data to the new skb ++ memcpy(skb_put(gl_skb, size), ++ packet->packet_data, size); ++ usbnet_skb_return(dev, gl_skb); ++ } ++ ++ // advance to the next packet ++ packet = (struct gl_packet *)&packet->packet_data[size]; ++ count--; ++ ++ // shift the data pointer to the next gl_packet ++ skb_pull(skb, size + 4); ++ } ++ ++ // skip the packet length field 4 bytes ++ skb_pull(skb, 4); ++ ++ if (skb->len > GL_MAX_PACKET_LEN) { ++ netdev_dbg(dev->net, "genelink: invalid rx length %d\n", ++ skb->len); ++ return 0; ++ } ++ return 1; ++} ++ ++static struct sk_buff * ++genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) ++{ ++ int padlen; ++ int length = skb->len; ++ int headroom = skb_headroom(skb); ++ int tailroom = skb_tailroom(skb); ++ __le32 *packet_count; ++ __le32 *packet_len; ++ ++ // FIXME: magic numbers, bleech ++ padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1; ++ ++ if ((!skb_cloned(skb)) ++ && ((headroom + tailroom) >= (padlen + (4 + 4*1)))) { ++ if ((headroom < (4 + 4*1)) || (tailroom < padlen)) { ++ skb->data = memmove(skb->head + (4 + 4*1), ++ skb->data, skb->len); ++ skb_set_tail_pointer(skb, skb->len); ++ } ++ } else { ++ struct sk_buff *skb2; ++ skb2 = skb_copy_expand(skb, (4 + 4*1) , padlen, flags); ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ if (!skb) ++ return NULL; ++ } ++ ++ // attach the packet count to the header ++ packet_count = (__le32 *) skb_push(skb, (4 + 4*1)); ++ packet_len = packet_count + 1; ++ ++ *packet_count = cpu_to_le32(1); ++ *packet_len = cpu_to_le32(length); ++ ++ // add padding byte ++ if ((skb->len % dev->maxpacket) == 0) ++ skb_put(skb, 1); ++ ++ return skb; ++} ++ ++static int genelink_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ dev->hard_mtu = GL_RCV_BUF_SIZE; ++ dev->net->hard_header_len += 4; ++ dev->in = usb_rcvbulkpipe(dev->udev, dev->driver_info->in); ++ dev->out = usb_sndbulkpipe(dev->udev, dev->driver_info->out); ++ return 0; ++} ++ ++static const struct driver_info genelink_info = { ++ .description = "Genesys GeneLink", ++ .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_GL | FLAG_NO_SETINT, ++ .bind = genelink_bind, ++ .rx_fixup = genelink_rx_fixup, ++ .tx_fixup = genelink_tx_fixup, ++ ++ .in = 1, .out = 2, ++ ++#ifdef GENELINK_ACK ++ .check_connect =genelink_check_connect, ++#endif ++}; ++ ++static const struct usb_device_id products [] = { ++ ++{ ++ USB_DEVICE(0x05e3, 0x0502), // GL620USB-A ++ .driver_info = (unsigned long) &genelink_info, ++}, ++ /* NOT: USB_DEVICE(0x05e3, 0x0501), // GL620USB ++ * that's half duplex, not currently supported ++ */ ++ { }, // END ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver gl620a_driver = { ++ .name = "gl620a", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(gl620a_driver); ++ ++MODULE_AUTHOR("Jiun-Jie Huang"); ++MODULE_DESCRIPTION("GL620-USB-A Host-to-Host Link cables"); ++MODULE_LICENSE("GPL"); ++ +diff -Naur backports-3.18.1-1.org/drivers/net/usb/hso.c backports-3.18.1-1/drivers/net/usb/hso.c +--- backports-3.18.1-1.org/drivers/net/usb/hso.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/hso.c 2015-01-03 13:42:25.000000000 +0100 +@@ -0,0 +1,3326 @@ ++/****************************************************************************** ++ * ++ * Driver for Option High Speed Mobile Devices. ++ * ++ * Copyright (C) 2008 Option International ++ * Filip Aben f.aben@option.com ++ * Denis Joseph Barrow d.barow@option.com ++ * Jan Dumon j.dumon@option.com ++ * Copyright (C) 2007 Andrew Bird (Sphere Systems Ltd) ++ * ajb@spheresystems.co.uk ++ * Copyright (C) 2008 Greg Kroah-Hartman gregkh@suse.de ++ * Copyright (C) 2008 Novell, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++ * USA ++ * ++ * ++ *****************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * Description of the device: ++ * ++ * Interface 0: Contains the IP network interface on the bulk end points. ++ * The multiplexed serial ports are using the interrupt and ++ * control endpoints. ++ * Interrupt contains a bitmap telling which multiplexed ++ * serialport needs servicing. ++ * ++ * Interface 1: Diagnostics port, uses bulk only, do not submit urbs until the ++ * port is opened, as this have a huge impact on the network port ++ * throughput. ++ * ++ * Interface 2: Standard modem interface - circuit switched interface, this ++ * can be used to make a standard ppp connection however it ++ * should not be used in conjunction with the IP network interface ++ * enabled for USB performance reasons i.e. if using this set ++ * ideally disable_net=1. ++ * ++ *****************************************************************************/ ++ ++#include <linux/sched.h> ++#include <linux/slab.h> ++#include <linux/init.h> ++#include <linux/delay.h> ++#include <linux/netdevice.h> ++#include <linux/module.h> ++#include <linux/ethtool.h> ++#include <linux/usb.h> ++#include <linux/timer.h> ++#include <linux/tty.h> ++#include <linux/tty_driver.h> ++#include <linux/tty_flip.h> ++#include <linux/kmod.h> ++#include <linux/rfkill.h> ++#include <linux/ip.h> ++#include <linux/uaccess.h> ++#include <linux/usb/cdc.h> ++#include <net/arp.h> ++#include <asm/byteorder.h> ++#include <linux/serial_core.h> ++#include <linux/serial.h> ++#include <asm/local.h> ++ ++#define MOD_AUTHOR "Option Wireless" ++#define MOD_DESCRIPTION "USB High Speed Option driver" ++#define MOD_LICENSE "GPL" ++ ++#define HSO_MAX_NET_DEVICES 10 ++#define HSO__MAX_MTU 2048 ++#define DEFAULT_MTU 1500 ++#define DEFAULT_MRU 1500 ++ ++#define CTRL_URB_RX_SIZE 1024 ++#define CTRL_URB_TX_SIZE 64 ++ ++#define BULK_URB_RX_SIZE 4096 ++#define BULK_URB_TX_SIZE 8192 ++ ++#define MUX_BULK_RX_BUF_SIZE HSO__MAX_MTU ++#define MUX_BULK_TX_BUF_SIZE HSO__MAX_MTU ++#define MUX_BULK_RX_BUF_COUNT 4 ++#define USB_TYPE_OPTION_VENDOR 0x20 ++ ++/* These definitions are used with the struct hso_net flags element */ ++/* - use *_bit operations on it. (bit indices not values.) */ ++#define HSO_NET_RUNNING 0 ++ ++#define HSO_NET_TX_TIMEOUT (HZ*10) ++ ++#define HSO_SERIAL_MAGIC 0x48534f31 ++ ++/* Number of ttys to handle */ ++#define HSO_SERIAL_TTY_MINORS 256 ++ ++#define MAX_RX_URBS 2 ++ ++/*****************************************************************************/ ++/* Debugging functions */ ++/*****************************************************************************/ ++#define D__(lvl_, fmt, arg...) \ ++ do { \ ++ printk(lvl_ "[%d:%s]: " fmt "\n", \ ++ __LINE__, __func__, ## arg); \ ++ } while (0) ++ ++#define D_(lvl, args...) \ ++ do { \ ++ if (lvl & debug) \ ++ D__(KERN_INFO, args); \ ++ } while (0) ++ ++#define D1(args...) D_(0x01, ##args) ++#define D2(args...) D_(0x02, ##args) ++#define D3(args...) D_(0x04, ##args) ++#define D4(args...) D_(0x08, ##args) ++#define D5(args...) D_(0x10, ##args) ++ ++/*****************************************************************************/ ++/* Enumerators */ ++/*****************************************************************************/ ++enum pkt_parse_state { ++ WAIT_IP, ++ WAIT_DATA, ++ WAIT_SYNC ++}; ++ ++/*****************************************************************************/ ++/* Structs */ ++/*****************************************************************************/ ++ ++struct hso_shared_int { ++ struct usb_endpoint_descriptor *intr_endp; ++ void *shared_intr_buf; ++ struct urb *shared_intr_urb; ++ struct usb_device *usb; ++ int use_count; ++ int ref_count; ++ struct mutex shared_int_lock; ++}; ++ ++struct hso_net { ++ struct hso_device *parent; ++ struct net_device *net; ++ struct rfkill *rfkill; ++ ++ struct usb_endpoint_descriptor *in_endp; ++ struct usb_endpoint_descriptor *out_endp; ++ ++ struct urb *mux_bulk_rx_urb_pool[MUX_BULK_RX_BUF_COUNT]; ++ struct urb *mux_bulk_tx_urb; ++ void *mux_bulk_rx_buf_pool[MUX_BULK_RX_BUF_COUNT]; ++ void *mux_bulk_tx_buf; ++ ++ struct sk_buff *skb_rx_buf; ++ struct sk_buff *skb_tx_buf; ++ ++ enum pkt_parse_state rx_parse_state; ++ spinlock_t net_lock; ++ ++ unsigned short rx_buf_size; ++ unsigned short rx_buf_missing; ++ struct iphdr rx_ip_hdr; ++ ++ unsigned long flags; ++}; ++ ++enum rx_ctrl_state{ ++ RX_IDLE, ++ RX_SENT, ++ RX_PENDING ++}; ++ ++#define BM_REQUEST_TYPE (0xa1) ++#define B_NOTIFICATION (0x20) ++#define W_VALUE (0x0) ++#define W_LENGTH (0x2) ++ ++#define B_OVERRUN (0x1<<6) ++#define B_PARITY (0x1<<5) ++#define B_FRAMING (0x1<<4) ++#define B_RING_SIGNAL (0x1<<3) ++#define B_BREAK (0x1<<2) ++#define B_TX_CARRIER (0x1<<1) ++#define B_RX_CARRIER (0x1<<0) ++ ++struct hso_serial_state_notification { ++ u8 bmRequestType; ++ u8 bNotification; ++ u16 wValue; ++ u16 wIndex; ++ u16 wLength; ++ u16 UART_state_bitmap; ++} __packed; ++ ++struct hso_tiocmget { ++ struct mutex mutex; ++ wait_queue_head_t waitq; ++ int intr_completed; ++ struct usb_endpoint_descriptor *endp; ++ struct urb *urb; ++ struct hso_serial_state_notification serial_state_notification; ++ u16 prev_UART_state_bitmap; ++ struct uart_icount icount; ++}; ++ ++ ++struct hso_serial { ++ struct hso_device *parent; ++ int magic; ++ u8 minor; ++ ++ struct hso_shared_int *shared_int; ++ ++ /* rx/tx urb could be either a bulk urb or a control urb depending ++ on which serial port it is used on. */ ++ struct urb *rx_urb[MAX_RX_URBS]; ++ u8 num_rx_urbs; ++ u8 *rx_data[MAX_RX_URBS]; ++ u16 rx_data_length; /* should contain allocated length */ ++ ++ struct urb *tx_urb; ++ u8 *tx_data; ++ u8 *tx_buffer; ++ u16 tx_data_length; /* should contain allocated length */ ++ u16 tx_data_count; ++ u16 tx_buffer_count; ++ struct usb_ctrlrequest ctrl_req_tx; ++ struct usb_ctrlrequest ctrl_req_rx; ++ ++ struct usb_endpoint_descriptor *in_endp; ++ struct usb_endpoint_descriptor *out_endp; ++ ++ enum rx_ctrl_state rx_state; ++ u8 rts_state; ++ u8 dtr_state; ++ unsigned tx_urb_used:1; ++ ++ struct tty_port port; ++ /* from usb_serial_port */ ++ spinlock_t serial_lock; ++ ++ int (*write_data) (struct hso_serial *serial); ++ struct hso_tiocmget *tiocmget; ++ /* Hacks required to get flow control ++ * working on the serial receive buffers ++ * so as not to drop characters on the floor. ++ */ ++ int curr_rx_urb_idx; ++ u8 rx_urb_filled[MAX_RX_URBS]; ++ struct tasklet_struct unthrottle_tasklet; ++}; ++ ++struct hso_device { ++ union { ++ struct hso_serial *dev_serial; ++ struct hso_net *dev_net; ++ } port_data; ++ ++ u32 port_spec; ++ ++ u8 is_active; ++ u8 usb_gone; ++ struct work_struct async_get_intf; ++ struct work_struct async_put_intf; ++ struct work_struct reset_device; ++ ++ struct usb_device *usb; ++ struct usb_interface *interface; ++ ++ struct device *dev; ++ struct kref ref; ++ struct mutex mutex; ++}; ++ ++/* Type of interface */ ++#define HSO_INTF_MASK 0xFF00 ++#define HSO_INTF_MUX 0x0100 ++#define HSO_INTF_BULK 0x0200 ++ ++/* Type of port */ ++#define HSO_PORT_MASK 0xFF ++#define HSO_PORT_NO_PORT 0x0 ++#define HSO_PORT_CONTROL 0x1 ++#define HSO_PORT_APP 0x2 ++#define HSO_PORT_GPS 0x3 ++#define HSO_PORT_PCSC 0x4 ++#define HSO_PORT_APP2 0x5 ++#define HSO_PORT_GPS_CONTROL 0x6 ++#define HSO_PORT_MSD 0x7 ++#define HSO_PORT_VOICE 0x8 ++#define HSO_PORT_DIAG2 0x9 ++#define HSO_PORT_DIAG 0x10 ++#define HSO_PORT_MODEM 0x11 ++#define HSO_PORT_NETWORK 0x12 ++ ++/* Additional device info */ ++#define HSO_INFO_MASK 0xFF000000 ++#define HSO_INFO_CRC_BUG 0x01000000 ++ ++/*****************************************************************************/ ++/* Prototypes */ ++/*****************************************************************************/ ++/* Serial driver functions */ ++static int hso_serial_tiocmset(struct tty_struct *tty, ++ unsigned int set, unsigned int clear); ++static void ctrl_callback(struct urb *urb); ++static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial); ++static void hso_kick_transmit(struct hso_serial *serial); ++/* Helper functions */ ++static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int, ++ struct usb_device *usb, gfp_t gfp); ++static void handle_usb_error(int status, const char *function, ++ struct hso_device *hso_dev); ++static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf, ++ int type, int dir); ++static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports); ++static void hso_free_interface(struct usb_interface *intf); ++static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags); ++static int hso_stop_serial_device(struct hso_device *hso_dev); ++static int hso_start_net_device(struct hso_device *hso_dev); ++static void hso_free_shared_int(struct hso_shared_int *shared_int); ++static int hso_stop_net_device(struct hso_device *hso_dev); ++static void hso_serial_ref_free(struct kref *ref); ++static void hso_std_serial_read_bulk_callback(struct urb *urb); ++static int hso_mux_serial_read(struct hso_serial *serial); ++static void async_get_intf(struct work_struct *data); ++static void async_put_intf(struct work_struct *data); ++static int hso_put_activity(struct hso_device *hso_dev); ++static int hso_get_activity(struct hso_device *hso_dev); ++static void tiocmget_intr_callback(struct urb *urb); ++static void reset_device(struct work_struct *data); ++/*****************************************************************************/ ++/* Helping functions */ ++/*****************************************************************************/ ++ ++/* #define DEBUG */ ++ ++static inline struct hso_net *dev2net(struct hso_device *hso_dev) ++{ ++ return hso_dev->port_data.dev_net; ++} ++ ++static inline struct hso_serial *dev2ser(struct hso_device *hso_dev) ++{ ++ return hso_dev->port_data.dev_serial; ++} ++ ++/* Debugging functions */ ++#ifdef DEBUG ++static void dbg_dump(int line_count, const char *func_name, unsigned char *buf, ++ unsigned int len) ++{ ++ static char name[255]; ++ ++ sprintf(name, "hso[%d:%s]", line_count, func_name); ++ print_hex_dump_bytes(name, DUMP_PREFIX_NONE, buf, len); ++} ++ ++#define DUMP(buf_, len_) \ ++ dbg_dump(__LINE__, __func__, (unsigned char *)buf_, len_) ++ ++#define DUMP1(buf_, len_) \ ++ do { \ ++ if (0x01 & debug) \ ++ DUMP(buf_, len_); \ ++ } while (0) ++#else ++#define DUMP(buf_, len_) ++#define DUMP1(buf_, len_) ++#endif ++ ++/* module parameters */ ++static int debug; ++static int tty_major; ++static int disable_net; ++ ++/* driver info */ ++static const char driver_name[] = "hso"; ++static const char tty_filename[] = "ttyHS"; ++static const char *version = __FILE__ ": " MOD_AUTHOR; ++/* the usb driver itself (registered in hso_init) */ ++static struct usb_driver hso_driver; ++/* serial structures */ ++static struct tty_driver *tty_drv; ++static struct hso_device *serial_table[HSO_SERIAL_TTY_MINORS]; ++static struct hso_device *network_table[HSO_MAX_NET_DEVICES]; ++static spinlock_t serial_table_lock; ++ ++static const s32 default_port_spec[] = { ++ HSO_INTF_MUX | HSO_PORT_NETWORK, ++ HSO_INTF_BULK | HSO_PORT_DIAG, ++ HSO_INTF_BULK | HSO_PORT_MODEM, ++ 0 ++}; ++ ++static const s32 icon321_port_spec[] = { ++ HSO_INTF_MUX | HSO_PORT_NETWORK, ++ HSO_INTF_BULK | HSO_PORT_DIAG2, ++ HSO_INTF_BULK | HSO_PORT_MODEM, ++ HSO_INTF_BULK | HSO_PORT_DIAG, ++ 0 ++}; ++ ++#define default_port_device(vendor, product) \ ++ USB_DEVICE(vendor, product), \ ++ .driver_info = (kernel_ulong_t)default_port_spec ++ ++#define icon321_port_device(vendor, product) \ ++ USB_DEVICE(vendor, product), \ ++ .driver_info = (kernel_ulong_t)icon321_port_spec ++ ++/* list of devices we support */ ++static const struct usb_device_id hso_ids[] = { ++ {default_port_device(0x0af0, 0x6711)}, ++ {default_port_device(0x0af0, 0x6731)}, ++ {default_port_device(0x0af0, 0x6751)}, ++ {default_port_device(0x0af0, 0x6771)}, ++ {default_port_device(0x0af0, 0x6791)}, ++ {default_port_device(0x0af0, 0x6811)}, ++ {default_port_device(0x0af0, 0x6911)}, ++ {default_port_device(0x0af0, 0x6951)}, ++ {default_port_device(0x0af0, 0x6971)}, ++ {default_port_device(0x0af0, 0x7011)}, ++ {default_port_device(0x0af0, 0x7031)}, ++ {default_port_device(0x0af0, 0x7051)}, ++ {default_port_device(0x0af0, 0x7071)}, ++ {default_port_device(0x0af0, 0x7111)}, ++ {default_port_device(0x0af0, 0x7211)}, ++ {default_port_device(0x0af0, 0x7251)}, ++ {default_port_device(0x0af0, 0x7271)}, ++ {default_port_device(0x0af0, 0x7311)}, ++ {default_port_device(0x0af0, 0xc031)}, /* Icon-Edge */ ++ {icon321_port_device(0x0af0, 0xd013)}, /* Module HSxPA */ ++ {icon321_port_device(0x0af0, 0xd031)}, /* Icon-321 */ ++ {icon321_port_device(0x0af0, 0xd033)}, /* Icon-322 */ ++ {USB_DEVICE(0x0af0, 0x7301)}, /* GE40x */ ++ {USB_DEVICE(0x0af0, 0x7361)}, /* GE40x */ ++ {USB_DEVICE(0x0af0, 0x7381)}, /* GE40x */ ++ {USB_DEVICE(0x0af0, 0x7401)}, /* GI 0401 */ ++ {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ ++ {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ ++ {USB_DEVICE(0x0af0, 0x7701)}, ++ {USB_DEVICE(0x0af0, 0x7706)}, ++ {USB_DEVICE(0x0af0, 0x7801)}, ++ {USB_DEVICE(0x0af0, 0x7901)}, ++ {USB_DEVICE(0x0af0, 0x7A01)}, ++ {USB_DEVICE(0x0af0, 0x7A05)}, ++ {USB_DEVICE(0x0af0, 0x8200)}, ++ {USB_DEVICE(0x0af0, 0x8201)}, ++ {USB_DEVICE(0x0af0, 0x8300)}, ++ {USB_DEVICE(0x0af0, 0x8302)}, ++ {USB_DEVICE(0x0af0, 0x8304)}, ++ {USB_DEVICE(0x0af0, 0x8400)}, ++ {USB_DEVICE(0x0af0, 0x8600)}, ++ {USB_DEVICE(0x0af0, 0x8800)}, ++ {USB_DEVICE(0x0af0, 0x8900)}, ++ {USB_DEVICE(0x0af0, 0x9000)}, ++ {USB_DEVICE(0x0af0, 0x9200)}, /* Option GTM671WFS */ ++ {USB_DEVICE(0x0af0, 0xd035)}, ++ {USB_DEVICE(0x0af0, 0xd055)}, ++ {USB_DEVICE(0x0af0, 0xd155)}, ++ {USB_DEVICE(0x0af0, 0xd255)}, ++ {USB_DEVICE(0x0af0, 0xd057)}, ++ {USB_DEVICE(0x0af0, 0xd157)}, ++ {USB_DEVICE(0x0af0, 0xd257)}, ++ {USB_DEVICE(0x0af0, 0xd357)}, ++ {USB_DEVICE(0x0af0, 0xd058)}, ++ {USB_DEVICE(0x0af0, 0xc100)}, ++ {} ++}; ++MODULE_DEVICE_TABLE(usb, hso_ids); ++ ++/* Sysfs attribute */ ++static ssize_t hso_sysfs_show_porttype(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct hso_device *hso_dev = dev_get_drvdata(dev); ++ char *port_name; ++ ++ if (!hso_dev) ++ return 0; ++ ++ switch (hso_dev->port_spec & HSO_PORT_MASK) { ++ case HSO_PORT_CONTROL: ++ port_name = "Control"; ++ break; ++ case HSO_PORT_APP: ++ port_name = "Application"; ++ break; ++ case HSO_PORT_APP2: ++ port_name = "Application2"; ++ break; ++ case HSO_PORT_GPS: ++ port_name = "GPS"; ++ break; ++ case HSO_PORT_GPS_CONTROL: ++ port_name = "GPS Control"; ++ break; ++ case HSO_PORT_PCSC: ++ port_name = "PCSC"; ++ break; ++ case HSO_PORT_DIAG: ++ port_name = "Diagnostic"; ++ break; ++ case HSO_PORT_DIAG2: ++ port_name = "Diagnostic2"; ++ break; ++ case HSO_PORT_MODEM: ++ port_name = "Modem"; ++ break; ++ case HSO_PORT_NETWORK: ++ port_name = "Network"; ++ break; ++ default: ++ port_name = "Unknown"; ++ break; ++ } ++ ++ return sprintf(buf, "%s\n", port_name); ++} ++static DEVICE_ATTR(hsotype, S_IRUGO, hso_sysfs_show_porttype, NULL); ++ ++static int hso_urb_to_index(struct hso_serial *serial, struct urb *urb) ++{ ++ int idx; ++ ++ for (idx = 0; idx < serial->num_rx_urbs; idx++) ++ if (serial->rx_urb[idx] == urb) ++ return idx; ++ dev_err(serial->parent->dev, "hso_urb_to_index failed\n"); ++ return -1; ++} ++ ++/* converts mux value to a port spec value */ ++static u32 hso_mux_to_port(int mux) ++{ ++ u32 result; ++ ++ switch (mux) { ++ case 0x1: ++ result = HSO_PORT_CONTROL; ++ break; ++ case 0x2: ++ result = HSO_PORT_APP; ++ break; ++ case 0x4: ++ result = HSO_PORT_PCSC; ++ break; ++ case 0x8: ++ result = HSO_PORT_GPS; ++ break; ++ case 0x10: ++ result = HSO_PORT_APP2; ++ break; ++ default: ++ result = HSO_PORT_NO_PORT; ++ } ++ return result; ++} ++ ++/* converts port spec value to a mux value */ ++static u32 hso_port_to_mux(int port) ++{ ++ u32 result; ++ ++ switch (port & HSO_PORT_MASK) { ++ case HSO_PORT_CONTROL: ++ result = 0x0; ++ break; ++ case HSO_PORT_APP: ++ result = 0x1; ++ break; ++ case HSO_PORT_PCSC: ++ result = 0x2; ++ break; ++ case HSO_PORT_GPS: ++ result = 0x3; ++ break; ++ case HSO_PORT_APP2: ++ result = 0x4; ++ break; ++ default: ++ result = 0x0; ++ } ++ return result; ++} ++ ++static struct hso_serial *get_serial_by_shared_int_and_type( ++ struct hso_shared_int *shared_int, ++ int mux) ++{ ++ int i, port; ++ ++ port = hso_mux_to_port(mux); ++ ++ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { ++ if (serial_table[i] && ++ (dev2ser(serial_table[i])->shared_int == shared_int) && ++ ((serial_table[i]->port_spec & HSO_PORT_MASK) == port)) { ++ return dev2ser(serial_table[i]); ++ } ++ } ++ ++ return NULL; ++} ++ ++static struct hso_serial *get_serial_by_index(unsigned index) ++{ ++ struct hso_serial *serial = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&serial_table_lock, flags); ++ if (serial_table[index]) ++ serial = dev2ser(serial_table[index]); ++ spin_unlock_irqrestore(&serial_table_lock, flags); ++ ++ return serial; ++} ++ ++static int get_free_serial_index(void) ++{ ++ int index; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&serial_table_lock, flags); ++ for (index = 0; index < HSO_SERIAL_TTY_MINORS; index++) { ++ if (serial_table[index] == NULL) { ++ spin_unlock_irqrestore(&serial_table_lock, flags); ++ return index; ++ } ++ } ++ spin_unlock_irqrestore(&serial_table_lock, flags); ++ ++ printk(KERN_ERR "%s: no free serial devices in table\n", __func__); ++ return -1; ++} ++ ++static void set_serial_by_index(unsigned index, struct hso_serial *serial) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&serial_table_lock, flags); ++ if (serial) ++ serial_table[index] = serial->parent; ++ else ++ serial_table[index] = NULL; ++ spin_unlock_irqrestore(&serial_table_lock, flags); ++} ++ ++static void handle_usb_error(int status, const char *function, ++ struct hso_device *hso_dev) ++{ ++ char *explanation; ++ ++ switch (status) { ++ case -ENODEV: ++ explanation = "no device"; ++ break; ++ case -ENOENT: ++ explanation = "endpoint not enabled"; ++ break; ++ case -EPIPE: ++ explanation = "endpoint stalled"; ++ break; ++ case -ENOSPC: ++ explanation = "not enough bandwidth"; ++ break; ++ case -ESHUTDOWN: ++ explanation = "device disabled"; ++ break; ++ case -EHOSTUNREACH: ++ explanation = "device suspended"; ++ break; ++ case -EINVAL: ++ case -EAGAIN: ++ case -EFBIG: ++ case -EMSGSIZE: ++ explanation = "internal error"; ++ break; ++ case -EILSEQ: ++ case -EPROTO: ++ case -ETIME: ++ case -ETIMEDOUT: ++ explanation = "protocol error"; ++ if (hso_dev) ++ schedule_work(&hso_dev->reset_device); ++ break; ++ default: ++ explanation = "unknown status"; ++ break; ++ } ++ ++ /* log a meaningful explanation of an USB status */ ++ D1("%s: received USB status - %s (%d)", function, explanation, status); ++} ++ ++/* Network interface functions */ ++ ++/* called when net interface is brought up by ifconfig */ ++static int hso_net_open(struct net_device *net) ++{ ++ struct hso_net *odev = netdev_priv(net); ++ unsigned long flags = 0; ++ ++ if (!odev) { ++ dev_err(&net->dev, "No net device !\n"); ++ return -ENODEV; ++ } ++ ++ odev->skb_tx_buf = NULL; ++ ++ /* setup environment */ ++ spin_lock_irqsave(&odev->net_lock, flags); ++ odev->rx_parse_state = WAIT_IP; ++ odev->rx_buf_size = 0; ++ odev->rx_buf_missing = sizeof(struct iphdr); ++ spin_unlock_irqrestore(&odev->net_lock, flags); ++ ++ /* We are up and running. */ ++ set_bit(HSO_NET_RUNNING, &odev->flags); ++ hso_start_net_device(odev->parent); ++ ++ /* Tell the kernel we are ready to start receiving from it */ ++ netif_start_queue(net); ++ ++ return 0; ++} ++ ++/* called when interface is brought down by ifconfig */ ++static int hso_net_close(struct net_device *net) ++{ ++ struct hso_net *odev = netdev_priv(net); ++ ++ /* we don't need the queue anymore */ ++ netif_stop_queue(net); ++ /* no longer running */ ++ clear_bit(HSO_NET_RUNNING, &odev->flags); ++ ++ hso_stop_net_device(odev->parent); ++ ++ /* done */ ++ return 0; ++} ++ ++/* USB tells is xmit done, we should start the netqueue again */ ++static void write_bulk_callback(struct urb *urb) ++{ ++ struct hso_net *odev = urb->context; ++ int status = urb->status; ++ ++ /* Sanity check */ ++ if (!odev || !test_bit(HSO_NET_RUNNING, &odev->flags)) { ++ dev_err(&urb->dev->dev, "%s: device not running\n", __func__); ++ return; ++ } ++ ++ /* Do we still have a valid kernel network device? */ ++ if (!netif_device_present(odev->net)) { ++ dev_err(&urb->dev->dev, "%s: net device not present\n", ++ __func__); ++ return; ++ } ++ ++ /* log status, but don't act on it, we don't need to resubmit anything ++ * anyhow */ ++ if (status) ++ handle_usb_error(status, __func__, odev->parent); ++ ++ hso_put_activity(odev->parent); ++ ++ /* Tell the network interface we are ready for another frame */ ++ netif_wake_queue(odev->net); ++} ++ ++/* called by kernel when we need to transmit a packet */ ++static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb, ++ struct net_device *net) ++{ ++ struct hso_net *odev = netdev_priv(net); ++ int result; ++ ++ /* Tell the kernel, "No more frames 'til we are done with this one." */ ++ netif_stop_queue(net); ++ if (hso_get_activity(odev->parent) == -EAGAIN) { ++ odev->skb_tx_buf = skb; ++ return NETDEV_TX_OK; ++ } ++ ++ /* log if asked */ ++ DUMP1(skb->data, skb->len); ++ /* Copy it from kernel memory to OUR memory */ ++ memcpy(odev->mux_bulk_tx_buf, skb->data, skb->len); ++ D1("len: %d/%d", skb->len, MUX_BULK_TX_BUF_SIZE); ++ ++ /* Fill in the URB for shipping it out. */ ++ usb_fill_bulk_urb(odev->mux_bulk_tx_urb, ++ odev->parent->usb, ++ usb_sndbulkpipe(odev->parent->usb, ++ odev->out_endp-> ++ bEndpointAddress & 0x7F), ++ odev->mux_bulk_tx_buf, skb->len, write_bulk_callback, ++ odev); ++ ++ /* Deal with the Zero Length packet problem, I hope */ ++ odev->mux_bulk_tx_urb->transfer_flags |= URB_ZERO_PACKET; ++ ++ /* Send the URB on its merry way. */ ++ result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC); ++ if (result) { ++ dev_warn(&odev->parent->interface->dev, ++ "failed mux_bulk_tx_urb %d\n", result); ++ net->stats.tx_errors++; ++ netif_start_queue(net); ++ } else { ++ net->stats.tx_packets++; ++ net->stats.tx_bytes += skb->len; ++ } ++ dev_kfree_skb(skb); ++ /* we're done */ ++ return NETDEV_TX_OK; ++} ++ ++static const struct ethtool_ops ops = { ++ .get_link = ethtool_op_get_link ++}; ++ ++/* called when a packet did not ack after watchdogtimeout */ ++static void hso_net_tx_timeout(struct net_device *net) ++{ ++ struct hso_net *odev = netdev_priv(net); ++ ++ if (!odev) ++ return; ++ ++ /* Tell syslog we are hosed. */ ++ dev_warn(&net->dev, "Tx timed out.\n"); ++ ++ /* Tear the waiting frame off the list */ ++ if (odev->mux_bulk_tx_urb && ++ (odev->mux_bulk_tx_urb->status == -EINPROGRESS)) ++ usb_unlink_urb(odev->mux_bulk_tx_urb); ++ ++ /* Update statistics */ ++ net->stats.tx_errors++; ++} ++ ++/* make a real packet from the received USB buffer */ ++static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, ++ unsigned int count, unsigned char is_eop) ++{ ++ unsigned short temp_bytes; ++ unsigned short buffer_offset = 0; ++ unsigned short frame_len; ++ unsigned char *tmp_rx_buf; ++ ++ /* log if needed */ ++ D1("Rx %d bytes", count); ++ DUMP(ip_pkt, min(128, (int)count)); ++ ++ while (count) { ++ switch (odev->rx_parse_state) { ++ case WAIT_IP: ++ /* waiting for IP header. */ ++ /* wanted bytes - size of ip header */ ++ temp_bytes = ++ (count < ++ odev->rx_buf_missing) ? count : odev-> ++ rx_buf_missing; ++ ++ memcpy(((unsigned char *)(&odev->rx_ip_hdr)) + ++ odev->rx_buf_size, ip_pkt + buffer_offset, ++ temp_bytes); ++ ++ odev->rx_buf_size += temp_bytes; ++ buffer_offset += temp_bytes; ++ odev->rx_buf_missing -= temp_bytes; ++ count -= temp_bytes; ++ ++ if (!odev->rx_buf_missing) { ++ /* header is complete allocate an sk_buffer and ++ * continue to WAIT_DATA */ ++ frame_len = ntohs(odev->rx_ip_hdr.tot_len); ++ ++ if ((frame_len > DEFAULT_MRU) || ++ (frame_len < sizeof(struct iphdr))) { ++ dev_err(&odev->net->dev, ++ "Invalid frame (%d) length\n", ++ frame_len); ++ odev->rx_parse_state = WAIT_SYNC; ++ continue; ++ } ++ /* Allocate an sk_buff */ ++ odev->skb_rx_buf = netdev_alloc_skb(odev->net, ++ frame_len); ++ if (!odev->skb_rx_buf) { ++ /* We got no receive buffer. */ ++ D1("could not allocate memory"); ++ odev->rx_parse_state = WAIT_SYNC; ++ return; ++ } ++ ++ /* Copy what we got so far. make room for iphdr ++ * after tail. */ ++ tmp_rx_buf = ++ skb_put(odev->skb_rx_buf, ++ sizeof(struct iphdr)); ++ memcpy(tmp_rx_buf, (char *)&(odev->rx_ip_hdr), ++ sizeof(struct iphdr)); ++ ++ /* ETH_HLEN */ ++ odev->rx_buf_size = sizeof(struct iphdr); ++ ++ /* Filip actually use .tot_len */ ++ odev->rx_buf_missing = ++ frame_len - sizeof(struct iphdr); ++ odev->rx_parse_state = WAIT_DATA; ++ } ++ break; ++ ++ case WAIT_DATA: ++ temp_bytes = (count < odev->rx_buf_missing) ++ ? count : odev->rx_buf_missing; ++ ++ /* Copy the rest of the bytes that are left in the ++ * buffer into the waiting sk_buf. */ ++ /* Make room for temp_bytes after tail. */ ++ tmp_rx_buf = skb_put(odev->skb_rx_buf, temp_bytes); ++ memcpy(tmp_rx_buf, ip_pkt + buffer_offset, temp_bytes); ++ ++ odev->rx_buf_missing -= temp_bytes; ++ count -= temp_bytes; ++ buffer_offset += temp_bytes; ++ odev->rx_buf_size += temp_bytes; ++ if (!odev->rx_buf_missing) { ++ /* Packet is complete. Inject into stack. */ ++ /* We have IP packet here */ ++ odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP); ++ skb_reset_mac_header(odev->skb_rx_buf); ++ ++ /* Ship it off to the kernel */ ++ netif_rx(odev->skb_rx_buf); ++ /* No longer our buffer. */ ++ odev->skb_rx_buf = NULL; ++ ++ /* update out statistics */ ++ odev->net->stats.rx_packets++; ++ ++ odev->net->stats.rx_bytes += odev->rx_buf_size; ++ ++ odev->rx_buf_size = 0; ++ odev->rx_buf_missing = sizeof(struct iphdr); ++ odev->rx_parse_state = WAIT_IP; ++ } ++ break; ++ ++ case WAIT_SYNC: ++ D1(" W_S"); ++ count = 0; ++ break; ++ default: ++ D1(" "); ++ count--; ++ break; ++ } ++ } ++ ++ /* Recovery mechanism for WAIT_SYNC state. */ ++ if (is_eop) { ++ if (odev->rx_parse_state == WAIT_SYNC) { ++ odev->rx_parse_state = WAIT_IP; ++ odev->rx_buf_size = 0; ++ odev->rx_buf_missing = sizeof(struct iphdr); ++ } ++ } ++} ++ ++static void fix_crc_bug(struct urb *urb, __le16 max_packet_size) ++{ ++ static const u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; ++ u32 rest = urb->actual_length % le16_to_cpu(max_packet_size); ++ ++ if (((rest == 5) || (rest == 6)) && ++ !memcmp(((u8 *)urb->transfer_buffer) + urb->actual_length - 4, ++ crc_check, 4)) { ++ urb->actual_length -= 4; ++ } ++} ++ ++/* Moving data from usb to kernel (in interrupt state) */ ++static void read_bulk_callback(struct urb *urb) ++{ ++ struct hso_net *odev = urb->context; ++ struct net_device *net; ++ int result; ++ int status = urb->status; ++ ++ /* is al ok? (Filip: Who's Al ?) */ ++ if (status) { ++ handle_usb_error(status, __func__, odev->parent); ++ return; ++ } ++ ++ /* Sanity check */ ++ if (!odev || !test_bit(HSO_NET_RUNNING, &odev->flags)) { ++ D1("BULK IN callback but driver is not active!"); ++ return; ++ } ++ usb_mark_last_busy(urb->dev); ++ ++ net = odev->net; ++ ++ if (!netif_device_present(net)) { ++ /* Somebody killed our network interface... */ ++ return; ++ } ++ ++ if (odev->parent->port_spec & HSO_INFO_CRC_BUG) ++ fix_crc_bug(urb, odev->in_endp->wMaxPacketSize); ++ ++ /* do we even have a packet? */ ++ if (urb->actual_length) { ++ /* Handle the IP stream, add header and push it onto network ++ * stack if the packet is complete. */ ++ spin_lock(&odev->net_lock); ++ packetizeRx(odev, urb->transfer_buffer, urb->actual_length, ++ (urb->transfer_buffer_length > ++ urb->actual_length) ? 1 : 0); ++ spin_unlock(&odev->net_lock); ++ } ++ ++ /* We are done with this URB, resubmit it. Prep the USB to wait for ++ * another frame. Reuse same as received. */ ++ usb_fill_bulk_urb(urb, ++ odev->parent->usb, ++ usb_rcvbulkpipe(odev->parent->usb, ++ odev->in_endp-> ++ bEndpointAddress & 0x7F), ++ urb->transfer_buffer, MUX_BULK_RX_BUF_SIZE, ++ read_bulk_callback, odev); ++ ++ /* Give this to the USB subsystem so it can tell us when more data ++ * arrives. */ ++ result = usb_submit_urb(urb, GFP_ATOMIC); ++ if (result) ++ dev_warn(&odev->parent->interface->dev, ++ "%s failed submit mux_bulk_rx_urb %d\n", __func__, ++ result); ++} ++ ++/* Serial driver functions */ ++ ++static void hso_init_termios(struct ktermios *termios) ++{ ++ /* ++ * The default requirements for this device are: ++ */ ++ termios->c_iflag &= ++ ~(IGNBRK /* disable ignore break */ ++ | BRKINT /* disable break causes interrupt */ ++ | PARMRK /* disable mark parity errors */ ++ | ISTRIP /* disable clear high bit of input characters */ ++ | INLCR /* disable translate NL to CR */ ++ | IGNCR /* disable ignore CR */ ++ | ICRNL /* disable translate CR to NL */ ++ | IXON); /* disable enable XON/XOFF flow control */ ++ ++ /* disable postprocess output characters */ ++ termios->c_oflag &= ~OPOST; ++ ++ termios->c_lflag &= ++ ~(ECHO /* disable echo input characters */ ++ | ECHONL /* disable echo new line */ ++ | ICANON /* disable erase, kill, werase, and rprnt ++ special characters */ ++ | ISIG /* disable interrupt, quit, and suspend special ++ characters */ ++ | IEXTEN); /* disable non-POSIX special characters */ ++ ++ termios->c_cflag &= ++ ~(CSIZE /* no size */ ++ | PARENB /* disable parity bit */ ++ | CBAUD /* clear current baud rate */ ++ | CBAUDEX); /* clear current buad rate */ ++ ++ termios->c_cflag |= CS8; /* character size 8 bits */ ++ ++ /* baud rate 115200 */ ++ tty_termios_encode_baud_rate(termios, 115200, 115200); ++} ++ ++static void _hso_serial_set_termios(struct tty_struct *tty, ++ struct ktermios *old) ++{ ++ struct hso_serial *serial = tty->driver_data; ++ ++ if (!serial) { ++ printk(KERN_ERR "%s: no tty structures", __func__); ++ return; ++ } ++ ++ D4("port %d", serial->minor); ++ ++ /* ++ * Fix up unsupported bits ++ */ ++ tty->termios.c_iflag &= ~IXON; /* disable enable XON/XOFF flow control */ ++ ++ tty->termios.c_cflag &= ++ ~(CSIZE /* no size */ ++ | PARENB /* disable parity bit */ ++ | CBAUD /* clear current baud rate */ ++ | CBAUDEX); /* clear current buad rate */ ++ ++ tty->termios.c_cflag |= CS8; /* character size 8 bits */ ++ ++ /* baud rate 115200 */ ++ tty_encode_baud_rate(tty, 115200, 115200); ++} ++ ++static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb) ++{ ++ int result; ++ /* We are done with this URB, resubmit it. Prep the USB to wait for ++ * another frame */ ++ usb_fill_bulk_urb(urb, serial->parent->usb, ++ usb_rcvbulkpipe(serial->parent->usb, ++ serial->in_endp-> ++ bEndpointAddress & 0x7F), ++ urb->transfer_buffer, serial->rx_data_length, ++ hso_std_serial_read_bulk_callback, serial); ++ /* Give this to the USB subsystem so it can tell us when more data ++ * arrives. */ ++ result = usb_submit_urb(urb, GFP_ATOMIC); ++ if (result) { ++ dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d\n", ++ __func__, result); ++ } ++} ++ ++ ++ ++ ++static void put_rxbuf_data_and_resubmit_bulk_urb(struct hso_serial *serial) ++{ ++ int count; ++ struct urb *curr_urb; ++ ++ while (serial->rx_urb_filled[serial->curr_rx_urb_idx]) { ++ curr_urb = serial->rx_urb[serial->curr_rx_urb_idx]; ++ count = put_rxbuf_data(curr_urb, serial); ++ if (count == -1) ++ return; ++ if (count == 0) { ++ serial->curr_rx_urb_idx++; ++ if (serial->curr_rx_urb_idx >= serial->num_rx_urbs) ++ serial->curr_rx_urb_idx = 0; ++ hso_resubmit_rx_bulk_urb(serial, curr_urb); ++ } ++ } ++} ++ ++static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial) ++{ ++ int count = 0; ++ struct urb *urb; ++ ++ urb = serial->rx_urb[0]; ++ if (atomic_read(&serial->port.count) > 0) { ++ count = put_rxbuf_data(urb, serial); ++ if (count == -1) ++ return; ++ } ++ /* Re issue a read as long as we receive data. */ ++ ++ if (count == 0 && ((urb->actual_length != 0) || ++ (serial->rx_state == RX_PENDING))) { ++ serial->rx_state = RX_SENT; ++ hso_mux_serial_read(serial); ++ } else ++ serial->rx_state = RX_IDLE; ++} ++ ++ ++/* read callback for Diag and CS port */ ++static void hso_std_serial_read_bulk_callback(struct urb *urb) ++{ ++ struct hso_serial *serial = urb->context; ++ int status = urb->status; ++ ++ D4("\n--- Got serial_read_bulk callback %02x ---", status); ++ ++ /* sanity check */ ++ if (!serial) { ++ D1("serial == NULL"); ++ return; ++ } ++ if (status) { ++ handle_usb_error(status, __func__, serial->parent); ++ return; ++ } ++ ++ D1("Actual length = %d\n", urb->actual_length); ++ DUMP1(urb->transfer_buffer, urb->actual_length); ++ ++ /* Anyone listening? */ ++ if (atomic_read(&serial->port.count) == 0) ++ return; ++ ++ if (serial->parent->port_spec & HSO_INFO_CRC_BUG) ++ fix_crc_bug(urb, serial->in_endp->wMaxPacketSize); ++ /* Valid data, handle RX data */ ++ spin_lock(&serial->serial_lock); ++ serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; ++ put_rxbuf_data_and_resubmit_bulk_urb(serial); ++ spin_unlock(&serial->serial_lock); ++} ++ ++/* ++ * This needs to be a tasklet otherwise we will ++ * end up recursively calling this function. ++ */ ++static void hso_unthrottle_tasklet(struct hso_serial *serial) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&serial->serial_lock, flags); ++ if ((serial->parent->port_spec & HSO_INTF_MUX)) ++ put_rxbuf_data_and_resubmit_ctrl_urb(serial); ++ else ++ put_rxbuf_data_and_resubmit_bulk_urb(serial); ++ spin_unlock_irqrestore(&serial->serial_lock, flags); ++} ++ ++static void hso_unthrottle(struct tty_struct *tty) ++{ ++ struct hso_serial *serial = tty->driver_data; ++ ++ tasklet_hi_schedule(&serial->unthrottle_tasklet); ++} ++ ++/* open the requested serial port */ ++static int hso_serial_open(struct tty_struct *tty, struct file *filp) ++{ ++ struct hso_serial *serial = get_serial_by_index(tty->index); ++ int result; ++ ++ /* sanity check */ ++ if (serial == NULL || serial->magic != HSO_SERIAL_MAGIC) { ++ WARN_ON(1); ++ tty->driver_data = NULL; ++ D1("Failed to open port"); ++ return -ENODEV; ++ } ++ ++ mutex_lock(&serial->parent->mutex); ++ result = usb_autopm_get_interface(serial->parent->interface); ++ if (result < 0) ++ goto err_out; ++ ++ D1("Opening %d", serial->minor); ++ kref_get(&serial->parent->ref); ++ ++ /* setup */ ++ tty->driver_data = serial; ++ tty_port_tty_set(&serial->port, tty); ++ ++ /* check for port already opened, if not set the termios */ ++ if (atomic_inc_return(&serial->port.count) == 1) { ++ serial->rx_state = RX_IDLE; ++ /* Force default termio settings */ ++ _hso_serial_set_termios(tty, NULL); ++ tasklet_init(&serial->unthrottle_tasklet, ++ (void (*)(unsigned long))hso_unthrottle_tasklet, ++ (unsigned long)serial); ++ result = hso_start_serial_device(serial->parent, GFP_KERNEL); ++ if (result) { ++ hso_stop_serial_device(serial->parent); ++ atomic_dec(&serial->port.count); ++ kref_put(&serial->parent->ref, hso_serial_ref_free); ++ } ++ } else { ++ D1("Port was already open"); ++ } ++ ++ usb_autopm_put_interface(serial->parent->interface); ++ ++ /* done */ ++ if (result) ++ hso_serial_tiocmset(tty, TIOCM_RTS | TIOCM_DTR, 0); ++err_out: ++ mutex_unlock(&serial->parent->mutex); ++ return result; ++} ++ ++/* close the requested serial port */ ++static void hso_serial_close(struct tty_struct *tty, struct file *filp) ++{ ++ struct hso_serial *serial = tty->driver_data; ++ u8 usb_gone; ++ ++ D1("Closing serial port"); ++ ++ /* Open failed, no close cleanup required */ ++ if (serial == NULL) ++ return; ++ ++ mutex_lock(&serial->parent->mutex); ++ usb_gone = serial->parent->usb_gone; ++ ++ if (!usb_gone) ++ usb_autopm_get_interface(serial->parent->interface); ++ ++ /* reset the rts and dtr */ ++ /* do the actual close */ ++ atomic_dec(&serial->port.count); ++ ++ if (atomic_read(&serial->port.count) <= 0) { ++ atomic_set(&serial->port.count, 0); ++ tty_port_tty_set(&serial->port, NULL); ++ if (!usb_gone) ++ hso_stop_serial_device(serial->parent); ++ tasklet_kill(&serial->unthrottle_tasklet); ++ } ++ ++ if (!usb_gone) ++ usb_autopm_put_interface(serial->parent->interface); ++ ++ mutex_unlock(&serial->parent->mutex); ++ ++ kref_put(&serial->parent->ref, hso_serial_ref_free); ++} ++ ++/* close the requested serial port */ ++static int hso_serial_write(struct tty_struct *tty, const unsigned char *buf, ++ int count) ++{ ++ struct hso_serial *serial = tty->driver_data; ++ int space, tx_bytes; ++ unsigned long flags; ++ ++ /* sanity check */ ++ if (serial == NULL) { ++ printk(KERN_ERR "%s: serial is NULL\n", __func__); ++ return -ENODEV; ++ } ++ ++ spin_lock_irqsave(&serial->serial_lock, flags); ++ ++ space = serial->tx_data_length - serial->tx_buffer_count; ++ tx_bytes = (count < space) ? count : space; ++ ++ if (!tx_bytes) ++ goto out; ++ ++ memcpy(serial->tx_buffer + serial->tx_buffer_count, buf, tx_bytes); ++ serial->tx_buffer_count += tx_bytes; ++ ++out: ++ spin_unlock_irqrestore(&serial->serial_lock, flags); ++ ++ hso_kick_transmit(serial); ++ /* done */ ++ return tx_bytes; ++} ++ ++/* how much room is there for writing */ ++static int hso_serial_write_room(struct tty_struct *tty) ++{ ++ struct hso_serial *serial = tty->driver_data; ++ int room; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&serial->serial_lock, flags); ++ room = serial->tx_data_length - serial->tx_buffer_count; ++ spin_unlock_irqrestore(&serial->serial_lock, flags); ++ ++ /* return free room */ ++ return room; ++} ++ ++/* setup the term */ ++static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) ++{ ++ struct hso_serial *serial = tty->driver_data; ++ unsigned long flags; ++ ++ if (old) ++ D5("Termios called with: cflags new[%d] - old[%d]", ++ tty->termios.c_cflag, old->c_cflag); ++ ++ /* the actual setup */ ++ spin_lock_irqsave(&serial->serial_lock, flags); ++ if (atomic_read(&serial->port.count)) ++ _hso_serial_set_termios(tty, old); ++ else ++ tty->termios = *old; ++ spin_unlock_irqrestore(&serial->serial_lock, flags); ++ ++ /* done */ ++} ++ ++/* how many characters in the buffer */ ++static int hso_serial_chars_in_buffer(struct tty_struct *tty) ++{ ++ struct hso_serial *serial = tty->driver_data; ++ int chars; ++ unsigned long flags; ++ ++ /* sanity check */ ++ if (serial == NULL) ++ return 0; ++ ++ spin_lock_irqsave(&serial->serial_lock, flags); ++ chars = serial->tx_buffer_count; ++ spin_unlock_irqrestore(&serial->serial_lock, flags); ++ ++ return chars; ++} ++static int tiocmget_submit_urb(struct hso_serial *serial, ++ struct hso_tiocmget *tiocmget, ++ struct usb_device *usb) ++{ ++ int result; ++ ++ if (serial->parent->usb_gone) ++ return -ENODEV; ++ usb_fill_int_urb(tiocmget->urb, usb, ++ usb_rcvintpipe(usb, ++ tiocmget->endp-> ++ bEndpointAddress & 0x7F), ++ &tiocmget->serial_state_notification, ++ sizeof(struct hso_serial_state_notification), ++ tiocmget_intr_callback, serial, ++ tiocmget->endp->bInterval); ++ result = usb_submit_urb(tiocmget->urb, GFP_ATOMIC); ++ if (result) { ++ dev_warn(&usb->dev, "%s usb_submit_urb failed %d\n", __func__, ++ result); ++ } ++ return result; ++ ++} ++ ++static void tiocmget_intr_callback(struct urb *urb) ++{ ++ struct hso_serial *serial = urb->context; ++ struct hso_tiocmget *tiocmget; ++ int status = urb->status; ++ u16 UART_state_bitmap, prev_UART_state_bitmap; ++ struct uart_icount *icount; ++ struct hso_serial_state_notification *serial_state_notification; ++ struct usb_device *usb; ++ int if_num; ++ ++ /* Sanity checks */ ++ if (!serial) ++ return; ++ if (status) { ++ handle_usb_error(status, __func__, serial->parent); ++ return; ++ } ++ ++ /* tiocmget is only supported on HSO_PORT_MODEM */ ++ tiocmget = serial->tiocmget; ++ if (!tiocmget) ++ return; ++ BUG_ON((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM); ++ ++ usb = serial->parent->usb; ++ if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; ++ ++ /* wIndex should be the USB interface number of the port to which the ++ * notification applies, which should always be the Modem port. ++ */ ++ serial_state_notification = &tiocmget->serial_state_notification; ++ if (serial_state_notification->bmRequestType != BM_REQUEST_TYPE || ++ serial_state_notification->bNotification != B_NOTIFICATION || ++ le16_to_cpu(serial_state_notification->wValue) != W_VALUE || ++ le16_to_cpu(serial_state_notification->wIndex) != if_num || ++ le16_to_cpu(serial_state_notification->wLength) != W_LENGTH) { ++ dev_warn(&usb->dev, ++ "hso received invalid serial state notification\n"); ++ DUMP(serial_state_notification, ++ sizeof(struct hso_serial_state_notification)); ++ } else { ++ ++ UART_state_bitmap = le16_to_cpu(serial_state_notification-> ++ UART_state_bitmap); ++ prev_UART_state_bitmap = tiocmget->prev_UART_state_bitmap; ++ icount = &tiocmget->icount; ++ spin_lock(&serial->serial_lock); ++ if ((UART_state_bitmap & B_OVERRUN) != ++ (prev_UART_state_bitmap & B_OVERRUN)) ++ icount->parity++; ++ if ((UART_state_bitmap & B_PARITY) != ++ (prev_UART_state_bitmap & B_PARITY)) ++ icount->parity++; ++ if ((UART_state_bitmap & B_FRAMING) != ++ (prev_UART_state_bitmap & B_FRAMING)) ++ icount->frame++; ++ if ((UART_state_bitmap & B_RING_SIGNAL) && ++ !(prev_UART_state_bitmap & B_RING_SIGNAL)) ++ icount->rng++; ++ if ((UART_state_bitmap & B_BREAK) != ++ (prev_UART_state_bitmap & B_BREAK)) ++ icount->brk++; ++ if ((UART_state_bitmap & B_TX_CARRIER) != ++ (prev_UART_state_bitmap & B_TX_CARRIER)) ++ icount->dsr++; ++ if ((UART_state_bitmap & B_RX_CARRIER) != ++ (prev_UART_state_bitmap & B_RX_CARRIER)) ++ icount->dcd++; ++ tiocmget->prev_UART_state_bitmap = UART_state_bitmap; ++ spin_unlock(&serial->serial_lock); ++ tiocmget->intr_completed = 1; ++ wake_up_interruptible(&tiocmget->waitq); ++ } ++ memset(serial_state_notification, 0, ++ sizeof(struct hso_serial_state_notification)); ++ tiocmget_submit_urb(serial, ++ tiocmget, ++ serial->parent->usb); ++} ++ ++/* ++ * next few functions largely stolen from drivers/serial/serial_core.c ++ */ ++/* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change ++ * - mask passed in arg for lines of interest ++ * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) ++ * Caller should use TIOCGICOUNT to see which one it was ++ */ ++static int ++hso_wait_modem_status(struct hso_serial *serial, unsigned long arg) ++{ ++ DECLARE_WAITQUEUE(wait, current); ++ struct uart_icount cprev, cnow; ++ struct hso_tiocmget *tiocmget; ++ int ret; ++ ++ tiocmget = serial->tiocmget; ++ if (!tiocmget) ++ return -ENOENT; ++ /* ++ * note the counters on entry ++ */ ++ spin_lock_irq(&serial->serial_lock); ++ memcpy(&cprev, &tiocmget->icount, sizeof(struct uart_icount)); ++ spin_unlock_irq(&serial->serial_lock); ++ add_wait_queue(&tiocmget->waitq, &wait); ++ for (;;) { ++ spin_lock_irq(&serial->serial_lock); ++ memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount)); ++ spin_unlock_irq(&serial->serial_lock); ++ set_current_state(TASK_INTERRUPTIBLE); ++ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ++ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ++ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd))) { ++ ret = 0; ++ break; ++ } ++ schedule(); ++ /* see if a signal did it */ ++ if (signal_pending(current)) { ++ ret = -ERESTARTSYS; ++ break; ++ } ++ cprev = cnow; ++ } ++ current->state = TASK_RUNNING; ++ remove_wait_queue(&tiocmget->waitq, &wait); ++ ++ return ret; ++} ++ ++/* ++ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) ++ * Return: write counters to the user passed counter struct ++ * NB: both 1->0 and 0->1 transitions are counted except for ++ * RI where only 0->1 is counted. ++ */ ++static int hso_get_count(struct tty_struct *tty, ++ struct serial_icounter_struct *icount) ++{ ++ struct uart_icount cnow; ++ struct hso_serial *serial = tty->driver_data; ++ struct hso_tiocmget *tiocmget = serial->tiocmget; ++ ++ memset(icount, 0, sizeof(struct serial_icounter_struct)); ++ ++ if (!tiocmget) ++ return -ENOENT; ++ spin_lock_irq(&serial->serial_lock); ++ memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount)); ++ spin_unlock_irq(&serial->serial_lock); ++ ++ icount->cts = cnow.cts; ++ icount->dsr = cnow.dsr; ++ icount->rng = cnow.rng; ++ icount->dcd = cnow.dcd; ++ icount->rx = cnow.rx; ++ icount->tx = cnow.tx; ++ icount->frame = cnow.frame; ++ icount->overrun = cnow.overrun; ++ icount->parity = cnow.parity; ++ icount->brk = cnow.brk; ++ icount->buf_overrun = cnow.buf_overrun; ++ ++ return 0; ++} ++ ++ ++static int hso_serial_tiocmget(struct tty_struct *tty) ++{ ++ int retval; ++ struct hso_serial *serial = tty->driver_data; ++ struct hso_tiocmget *tiocmget; ++ u16 UART_state_bitmap; ++ ++ /* sanity check */ ++ if (!serial) { ++ D1("no tty structures"); ++ return -EINVAL; ++ } ++ spin_lock_irq(&serial->serial_lock); ++ retval = ((serial->rts_state) ? TIOCM_RTS : 0) | ++ ((serial->dtr_state) ? TIOCM_DTR : 0); ++ tiocmget = serial->tiocmget; ++ if (tiocmget) { ++ ++ UART_state_bitmap = le16_to_cpu( ++ tiocmget->prev_UART_state_bitmap); ++ if (UART_state_bitmap & B_RING_SIGNAL) ++ retval |= TIOCM_RNG; ++ if (UART_state_bitmap & B_RX_CARRIER) ++ retval |= TIOCM_CD; ++ if (UART_state_bitmap & B_TX_CARRIER) ++ retval |= TIOCM_DSR; ++ } ++ spin_unlock_irq(&serial->serial_lock); ++ return retval; ++} ++ ++static int hso_serial_tiocmset(struct tty_struct *tty, ++ unsigned int set, unsigned int clear) ++{ ++ int val = 0; ++ unsigned long flags; ++ int if_num; ++ struct hso_serial *serial = tty->driver_data; ++ ++ /* sanity check */ ++ if (!serial) { ++ D1("no tty structures"); ++ return -EINVAL; ++ } ++ ++ if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM) ++ return -EINVAL; ++ ++ if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; ++ ++ spin_lock_irqsave(&serial->serial_lock, flags); ++ if (set & TIOCM_RTS) ++ serial->rts_state = 1; ++ if (set & TIOCM_DTR) ++ serial->dtr_state = 1; ++ ++ if (clear & TIOCM_RTS) ++ serial->rts_state = 0; ++ if (clear & TIOCM_DTR) ++ serial->dtr_state = 0; ++ ++ if (serial->dtr_state) ++ val |= 0x01; ++ if (serial->rts_state) ++ val |= 0x02; ++ ++ spin_unlock_irqrestore(&serial->serial_lock, flags); ++ ++ return usb_control_msg(serial->parent->usb, ++ usb_rcvctrlpipe(serial->parent->usb, 0), 0x22, ++ 0x21, val, if_num, NULL, 0, ++ USB_CTRL_SET_TIMEOUT); ++} ++ ++static int hso_serial_ioctl(struct tty_struct *tty, ++ unsigned int cmd, unsigned long arg) ++{ ++ struct hso_serial *serial = tty->driver_data; ++ int ret = 0; ++ D4("IOCTL cmd: %d, arg: %ld", cmd, arg); ++ ++ if (!serial) ++ return -ENODEV; ++ switch (cmd) { ++ case TIOCMIWAIT: ++ ret = hso_wait_modem_status(serial, arg); ++ break; ++ default: ++ ret = -ENOIOCTLCMD; ++ break; ++ } ++ return ret; ++} ++ ++ ++/* starts a transmit */ ++static void hso_kick_transmit(struct hso_serial *serial) ++{ ++ u8 *temp; ++ unsigned long flags; ++ int res; ++ ++ spin_lock_irqsave(&serial->serial_lock, flags); ++ if (!serial->tx_buffer_count) ++ goto out; ++ ++ if (serial->tx_urb_used) ++ goto out; ++ ++ /* Wakeup USB interface if necessary */ ++ if (hso_get_activity(serial->parent) == -EAGAIN) ++ goto out; ++ ++ /* Switch pointers around to avoid memcpy */ ++ temp = serial->tx_buffer; ++ serial->tx_buffer = serial->tx_data; ++ serial->tx_data = temp; ++ serial->tx_data_count = serial->tx_buffer_count; ++ serial->tx_buffer_count = 0; ++ ++ /* If temp is set, it means we switched buffers */ ++ if (temp && serial->write_data) { ++ res = serial->write_data(serial); ++ if (res >= 0) ++ serial->tx_urb_used = 1; ++ } ++out: ++ spin_unlock_irqrestore(&serial->serial_lock, flags); ++} ++ ++/* make a request (for reading and writing data to muxed serial port) */ ++static int mux_device_request(struct hso_serial *serial, u8 type, u16 port, ++ struct urb *ctrl_urb, ++ struct usb_ctrlrequest *ctrl_req, ++ u8 *ctrl_urb_data, u32 size) ++{ ++ int result; ++ int pipe; ++ ++ /* Sanity check */ ++ if (!serial || !ctrl_urb || !ctrl_req) { ++ printk(KERN_ERR "%s: Wrong arguments\n", __func__); ++ return -EINVAL; ++ } ++ ++ /* initialize */ ++ ctrl_req->wValue = 0; ++ ctrl_req->wIndex = cpu_to_le16(hso_port_to_mux(port)); ++ ctrl_req->wLength = cpu_to_le16(size); ++ ++ if (type == USB_CDC_GET_ENCAPSULATED_RESPONSE) { ++ /* Reading command */ ++ ctrl_req->bRequestType = USB_DIR_IN | ++ USB_TYPE_OPTION_VENDOR | ++ USB_RECIP_INTERFACE; ++ ctrl_req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; ++ pipe = usb_rcvctrlpipe(serial->parent->usb, 0); ++ } else { ++ /* Writing command */ ++ ctrl_req->bRequestType = USB_DIR_OUT | ++ USB_TYPE_OPTION_VENDOR | ++ USB_RECIP_INTERFACE; ++ ctrl_req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; ++ pipe = usb_sndctrlpipe(serial->parent->usb, 0); ++ } ++ /* syslog */ ++ D2("%s command (%02x) len: %d, port: %d", ++ type == USB_CDC_GET_ENCAPSULATED_RESPONSE ? "Read" : "Write", ++ ctrl_req->bRequestType, ctrl_req->wLength, port); ++ ++ /* Load ctrl urb */ ++ ctrl_urb->transfer_flags = 0; ++ usb_fill_control_urb(ctrl_urb, ++ serial->parent->usb, ++ pipe, ++ (u8 *) ctrl_req, ++ ctrl_urb_data, size, ctrl_callback, serial); ++ /* Send it on merry way */ ++ result = usb_submit_urb(ctrl_urb, GFP_ATOMIC); ++ if (result) { ++ dev_err(&ctrl_urb->dev->dev, ++ "%s failed submit ctrl_urb %d type %d\n", __func__, ++ result, type); ++ return result; ++ } ++ ++ /* done */ ++ return size; ++} ++ ++/* called by intr_callback when read occurs */ ++static int hso_mux_serial_read(struct hso_serial *serial) ++{ ++ if (!serial) ++ return -EINVAL; ++ ++ /* clean data */ ++ memset(serial->rx_data[0], 0, CTRL_URB_RX_SIZE); ++ /* make the request */ ++ ++ if (serial->num_rx_urbs != 1) { ++ dev_err(&serial->parent->interface->dev, ++ "ERROR: mux'd reads with multiple buffers " ++ "not possible\n"); ++ return 0; ++ } ++ return mux_device_request(serial, ++ USB_CDC_GET_ENCAPSULATED_RESPONSE, ++ serial->parent->port_spec & HSO_PORT_MASK, ++ serial->rx_urb[0], ++ &serial->ctrl_req_rx, ++ serial->rx_data[0], serial->rx_data_length); ++} ++ ++/* used for muxed serial port callback (muxed serial read) */ ++static void intr_callback(struct urb *urb) ++{ ++ struct hso_shared_int *shared_int = urb->context; ++ struct hso_serial *serial; ++ unsigned char *port_req; ++ int status = urb->status; ++ int i; ++ ++ usb_mark_last_busy(urb->dev); ++ ++ /* sanity check */ ++ if (!shared_int) ++ return; ++ ++ /* status check */ ++ if (status) { ++ handle_usb_error(status, __func__, NULL); ++ return; ++ } ++ D4("\n--- Got intr callback 0x%02X ---", status); ++ ++ /* what request? */ ++ port_req = urb->transfer_buffer; ++ D4(" port_req = 0x%.2X\n", *port_req); ++ /* loop over all muxed ports to find the one sending this */ ++ for (i = 0; i < 8; i++) { ++ /* max 8 channels on MUX */ ++ if (*port_req & (1 << i)) { ++ serial = get_serial_by_shared_int_and_type(shared_int, ++ (1 << i)); ++ if (serial != NULL) { ++ D1("Pending read interrupt on port %d\n", i); ++ spin_lock(&serial->serial_lock); ++ if (serial->rx_state == RX_IDLE && ++ atomic_read(&serial->port.count) > 0) { ++ /* Setup and send a ctrl req read on ++ * port i */ ++ if (!serial->rx_urb_filled[0]) { ++ serial->rx_state = RX_SENT; ++ hso_mux_serial_read(serial); ++ } else ++ serial->rx_state = RX_PENDING; ++ } else { ++ D1("Already a read pending on " ++ "port %d or port not open\n", i); ++ } ++ spin_unlock(&serial->serial_lock); ++ } ++ } ++ } ++ /* Resubmit interrupt urb */ ++ hso_mux_submit_intr_urb(shared_int, urb->dev, GFP_ATOMIC); ++} ++ ++/* called for writing to muxed serial port */ ++static int hso_mux_serial_write_data(struct hso_serial *serial) ++{ ++ if (NULL == serial) ++ return -EINVAL; ++ ++ return mux_device_request(serial, ++ USB_CDC_SEND_ENCAPSULATED_COMMAND, ++ serial->parent->port_spec & HSO_PORT_MASK, ++ serial->tx_urb, ++ &serial->ctrl_req_tx, ++ serial->tx_data, serial->tx_data_count); ++} ++ ++/* write callback for Diag and CS port */ ++static void hso_std_serial_write_bulk_callback(struct urb *urb) ++{ ++ struct hso_serial *serial = urb->context; ++ int status = urb->status; ++ ++ /* sanity check */ ++ if (!serial) { ++ D1("serial == NULL"); ++ return; ++ } ++ ++ spin_lock(&serial->serial_lock); ++ serial->tx_urb_used = 0; ++ spin_unlock(&serial->serial_lock); ++ if (status) { ++ handle_usb_error(status, __func__, serial->parent); ++ return; ++ } ++ hso_put_activity(serial->parent); ++ tty_port_tty_wakeup(&serial->port); ++ hso_kick_transmit(serial); ++ ++ D1(" "); ++} ++ ++/* called for writing diag or CS serial port */ ++static int hso_std_serial_write_data(struct hso_serial *serial) ++{ ++ int count = serial->tx_data_count; ++ int result; ++ ++ usb_fill_bulk_urb(serial->tx_urb, ++ serial->parent->usb, ++ usb_sndbulkpipe(serial->parent->usb, ++ serial->out_endp-> ++ bEndpointAddress & 0x7F), ++ serial->tx_data, serial->tx_data_count, ++ hso_std_serial_write_bulk_callback, serial); ++ ++ result = usb_submit_urb(serial->tx_urb, GFP_ATOMIC); ++ if (result) { ++ dev_warn(&serial->parent->usb->dev, ++ "Failed to submit urb - res %d\n", result); ++ return result; ++ } ++ ++ return count; ++} ++ ++/* callback after read or write on muxed serial port */ ++static void ctrl_callback(struct urb *urb) ++{ ++ struct hso_serial *serial = urb->context; ++ struct usb_ctrlrequest *req; ++ int status = urb->status; ++ ++ /* sanity check */ ++ if (!serial) ++ return; ++ ++ spin_lock(&serial->serial_lock); ++ serial->tx_urb_used = 0; ++ spin_unlock(&serial->serial_lock); ++ if (status) { ++ handle_usb_error(status, __func__, serial->parent); ++ return; ++ } ++ ++ /* what request? */ ++ req = (struct usb_ctrlrequest *)(urb->setup_packet); ++ D4("\n--- Got muxed ctrl callback 0x%02X ---", status); ++ D4("Actual length of urb = %d\n", urb->actual_length); ++ DUMP1(urb->transfer_buffer, urb->actual_length); ++ ++ if (req->bRequestType == ++ (USB_DIR_IN | USB_TYPE_OPTION_VENDOR | USB_RECIP_INTERFACE)) { ++ /* response to a read command */ ++ serial->rx_urb_filled[0] = 1; ++ spin_lock(&serial->serial_lock); ++ put_rxbuf_data_and_resubmit_ctrl_urb(serial); ++ spin_unlock(&serial->serial_lock); ++ } else { ++ hso_put_activity(serial->parent); ++ tty_port_tty_wakeup(&serial->port); ++ /* response to a write command */ ++ hso_kick_transmit(serial); ++ } ++} ++ ++/* handle RX data for serial port */ ++static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) ++{ ++ struct tty_struct *tty; ++ int count; ++ ++ /* Sanity check */ ++ if (urb == NULL || serial == NULL) { ++ D1("serial = NULL"); ++ return -2; ++ } ++ ++ tty = tty_port_tty_get(&serial->port); ++ ++ if (tty && test_bit(TTY_THROTTLED, &tty->flags)) { ++ tty_kref_put(tty); ++ return -1; ++ } ++ ++ /* Push data to tty */ ++ D1("data to push to tty"); ++ count = tty_buffer_request_room(&serial->port, urb->actual_length); ++ if (count >= urb->actual_length) { ++ tty_insert_flip_string(&serial->port, urb->transfer_buffer, ++ urb->actual_length); ++ tty_flip_buffer_push(&serial->port); ++ } else { ++ dev_warn(&serial->parent->usb->dev, ++ "dropping data, %d bytes lost\n", urb->actual_length); ++ } ++ ++ tty_kref_put(tty); ++ ++ serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; ++ ++ return 0; ++} ++ ++ ++/* Base driver functions */ ++ ++static void hso_log_port(struct hso_device *hso_dev) ++{ ++ char *port_type; ++ char port_dev[20]; ++ ++ switch (hso_dev->port_spec & HSO_PORT_MASK) { ++ case HSO_PORT_CONTROL: ++ port_type = "Control"; ++ break; ++ case HSO_PORT_APP: ++ port_type = "Application"; ++ break; ++ case HSO_PORT_GPS: ++ port_type = "GPS"; ++ break; ++ case HSO_PORT_GPS_CONTROL: ++ port_type = "GPS control"; ++ break; ++ case HSO_PORT_APP2: ++ port_type = "Application2"; ++ break; ++ case HSO_PORT_PCSC: ++ port_type = "PCSC"; ++ break; ++ case HSO_PORT_DIAG: ++ port_type = "Diagnostic"; ++ break; ++ case HSO_PORT_DIAG2: ++ port_type = "Diagnostic2"; ++ break; ++ case HSO_PORT_MODEM: ++ port_type = "Modem"; ++ break; ++ case HSO_PORT_NETWORK: ++ port_type = "Network"; ++ break; ++ default: ++ port_type = "Unknown"; ++ break; ++ } ++ if ((hso_dev->port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) { ++ sprintf(port_dev, "%s", dev2net(hso_dev)->net->name); ++ } else ++ sprintf(port_dev, "/dev/%s%d", tty_filename, ++ dev2ser(hso_dev)->minor); ++ ++ dev_dbg(&hso_dev->interface->dev, "HSO: Found %s port %s\n", ++ port_type, port_dev); ++} ++ ++static int hso_start_net_device(struct hso_device *hso_dev) ++{ ++ int i, result = 0; ++ struct hso_net *hso_net = dev2net(hso_dev); ++ ++ if (!hso_net) ++ return -ENODEV; ++ ++ /* send URBs for all read buffers */ ++ for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { ++ ++ /* Prep a receive URB */ ++ usb_fill_bulk_urb(hso_net->mux_bulk_rx_urb_pool[i], ++ hso_dev->usb, ++ usb_rcvbulkpipe(hso_dev->usb, ++ hso_net->in_endp-> ++ bEndpointAddress & 0x7F), ++ hso_net->mux_bulk_rx_buf_pool[i], ++ MUX_BULK_RX_BUF_SIZE, read_bulk_callback, ++ hso_net); ++ ++ /* Put it out there so the device can send us stuff */ ++ result = usb_submit_urb(hso_net->mux_bulk_rx_urb_pool[i], ++ GFP_NOIO); ++ if (result) ++ dev_warn(&hso_dev->usb->dev, ++ "%s failed mux_bulk_rx_urb[%d] %d\n", __func__, ++ i, result); ++ } ++ ++ return result; ++} ++ ++static int hso_stop_net_device(struct hso_device *hso_dev) ++{ ++ int i; ++ struct hso_net *hso_net = dev2net(hso_dev); ++ ++ if (!hso_net) ++ return -ENODEV; ++ ++ for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { ++ if (hso_net->mux_bulk_rx_urb_pool[i]) ++ usb_kill_urb(hso_net->mux_bulk_rx_urb_pool[i]); ++ ++ } ++ if (hso_net->mux_bulk_tx_urb) ++ usb_kill_urb(hso_net->mux_bulk_tx_urb); ++ ++ return 0; ++} ++ ++static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags) ++{ ++ int i, result = 0; ++ struct hso_serial *serial = dev2ser(hso_dev); ++ ++ if (!serial) ++ return -ENODEV; ++ ++ /* If it is not the MUX port fill in and submit a bulk urb (already ++ * allocated in hso_serial_start) */ ++ if (!(serial->parent->port_spec & HSO_INTF_MUX)) { ++ for (i = 0; i < serial->num_rx_urbs; i++) { ++ usb_fill_bulk_urb(serial->rx_urb[i], ++ serial->parent->usb, ++ usb_rcvbulkpipe(serial->parent->usb, ++ serial->in_endp-> ++ bEndpointAddress & ++ 0x7F), ++ serial->rx_data[i], ++ serial->rx_data_length, ++ hso_std_serial_read_bulk_callback, ++ serial); ++ result = usb_submit_urb(serial->rx_urb[i], flags); ++ if (result) { ++ dev_warn(&serial->parent->usb->dev, ++ "Failed to submit urb - res %d\n", ++ result); ++ break; ++ } ++ } ++ } else { ++ mutex_lock(&serial->shared_int->shared_int_lock); ++ if (!serial->shared_int->use_count) { ++ result = ++ hso_mux_submit_intr_urb(serial->shared_int, ++ hso_dev->usb, flags); ++ } ++ serial->shared_int->use_count++; ++ mutex_unlock(&serial->shared_int->shared_int_lock); ++ } ++ if (serial->tiocmget) ++ tiocmget_submit_urb(serial, ++ serial->tiocmget, ++ serial->parent->usb); ++ return result; ++} ++ ++static int hso_stop_serial_device(struct hso_device *hso_dev) ++{ ++ int i; ++ struct hso_serial *serial = dev2ser(hso_dev); ++ struct hso_tiocmget *tiocmget; ++ ++ if (!serial) ++ return -ENODEV; ++ ++ for (i = 0; i < serial->num_rx_urbs; i++) { ++ if (serial->rx_urb[i]) { ++ usb_kill_urb(serial->rx_urb[i]); ++ serial->rx_urb_filled[i] = 0; ++ } ++ } ++ serial->curr_rx_urb_idx = 0; ++ ++ if (serial->tx_urb) ++ usb_kill_urb(serial->tx_urb); ++ ++ if (serial->shared_int) { ++ mutex_lock(&serial->shared_int->shared_int_lock); ++ if (serial->shared_int->use_count && ++ (--serial->shared_int->use_count == 0)) { ++ struct urb *urb; ++ ++ urb = serial->shared_int->shared_intr_urb; ++ if (urb) ++ usb_kill_urb(urb); ++ } ++ mutex_unlock(&serial->shared_int->shared_int_lock); ++ } ++ tiocmget = serial->tiocmget; ++ if (tiocmget) { ++ wake_up_interruptible(&tiocmget->waitq); ++ usb_kill_urb(tiocmget->urb); ++ } ++ ++ return 0; ++} ++ ++static void hso_serial_common_free(struct hso_serial *serial) ++{ ++ int i; ++ ++ if (serial->parent->dev) ++ device_remove_file(serial->parent->dev, &dev_attr_hsotype); ++ ++ tty_unregister_device(tty_drv, serial->minor); ++ ++ for (i = 0; i < serial->num_rx_urbs; i++) { ++ /* unlink and free RX URB */ ++ usb_free_urb(serial->rx_urb[i]); ++ /* free the RX buffer */ ++ kfree(serial->rx_data[i]); ++ } ++ ++ /* unlink and free TX URB */ ++ usb_free_urb(serial->tx_urb); ++ kfree(serial->tx_data); ++ tty_port_destroy(&serial->port); ++} ++ ++static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, ++ int rx_size, int tx_size) ++{ ++ struct device *dev; ++ int minor; ++ int i; ++ ++ tty_port_init(&serial->port); ++ ++ minor = get_free_serial_index(); ++ if (minor < 0) ++ goto exit; ++ ++ /* register our minor number */ ++ serial->parent->dev = tty_port_register_device(&serial->port, tty_drv, ++ minor, &serial->parent->interface->dev); ++ dev = serial->parent->dev; ++ dev_set_drvdata(dev, serial->parent); ++ i = device_create_file(dev, &dev_attr_hsotype); ++ ++ /* fill in specific data for later use */ ++ serial->minor = minor; ++ serial->magic = HSO_SERIAL_MAGIC; ++ spin_lock_init(&serial->serial_lock); ++ serial->num_rx_urbs = num_urbs; ++ ++ /* RX, allocate urb and initialize */ ++ ++ /* prepare our RX buffer */ ++ serial->rx_data_length = rx_size; ++ for (i = 0; i < serial->num_rx_urbs; i++) { ++ serial->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); ++ if (!serial->rx_urb[i]) { ++ dev_err(dev, "Could not allocate urb?\n"); ++ goto exit; ++ } ++ serial->rx_urb[i]->transfer_buffer = NULL; ++ serial->rx_urb[i]->transfer_buffer_length = 0; ++ serial->rx_data[i] = kzalloc(serial->rx_data_length, ++ GFP_KERNEL); ++ if (!serial->rx_data[i]) ++ goto exit; ++ } ++ ++ /* TX, allocate urb and initialize */ ++ serial->tx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!serial->tx_urb) { ++ dev_err(dev, "Could not allocate urb?\n"); ++ goto exit; ++ } ++ serial->tx_urb->transfer_buffer = NULL; ++ serial->tx_urb->transfer_buffer_length = 0; ++ /* prepare our TX buffer */ ++ serial->tx_data_count = 0; ++ serial->tx_buffer_count = 0; ++ serial->tx_data_length = tx_size; ++ serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL); ++ if (!serial->tx_data) ++ goto exit; ++ ++ serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL); ++ if (!serial->tx_buffer) ++ goto exit; ++ ++ return 0; ++exit: ++ hso_serial_common_free(serial); ++ return -1; ++} ++ ++/* Creates a general hso device */ ++static struct hso_device *hso_create_device(struct usb_interface *intf, ++ int port_spec) ++{ ++ struct hso_device *hso_dev; ++ ++ hso_dev = kzalloc(sizeof(*hso_dev), GFP_ATOMIC); ++ if (!hso_dev) ++ return NULL; ++ ++ hso_dev->port_spec = port_spec; ++ hso_dev->usb = interface_to_usbdev(intf); ++ hso_dev->interface = intf; ++ kref_init(&hso_dev->ref); ++ mutex_init(&hso_dev->mutex); ++ ++ INIT_WORK(&hso_dev->async_get_intf, async_get_intf); ++ INIT_WORK(&hso_dev->async_put_intf, async_put_intf); ++ INIT_WORK(&hso_dev->reset_device, reset_device); ++ ++ return hso_dev; ++} ++ ++/* Removes a network device in the network device table */ ++static int remove_net_device(struct hso_device *hso_dev) ++{ ++ int i; ++ ++ for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { ++ if (network_table[i] == hso_dev) { ++ network_table[i] = NULL; ++ break; ++ } ++ } ++ if (i == HSO_MAX_NET_DEVICES) ++ return -1; ++ return 0; ++} ++ ++/* Frees our network device */ ++static void hso_free_net_device(struct hso_device *hso_dev) ++{ ++ int i; ++ struct hso_net *hso_net = dev2net(hso_dev); ++ ++ if (!hso_net) ++ return; ++ ++ remove_net_device(hso_net->parent); ++ ++ if (hso_net->net) ++ unregister_netdev(hso_net->net); ++ ++ /* start freeing */ ++ for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { ++ usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]); ++ kfree(hso_net->mux_bulk_rx_buf_pool[i]); ++ hso_net->mux_bulk_rx_buf_pool[i] = NULL; ++ } ++ usb_free_urb(hso_net->mux_bulk_tx_urb); ++ kfree(hso_net->mux_bulk_tx_buf); ++ hso_net->mux_bulk_tx_buf = NULL; ++ ++ if (hso_net->net) ++ free_netdev(hso_net->net); ++ ++ kfree(hso_dev); ++} ++ ++static const struct net_device_ops hso_netdev_ops = { ++ .ndo_open = hso_net_open, ++ .ndo_stop = hso_net_close, ++ .ndo_start_xmit = hso_net_start_xmit, ++ .ndo_tx_timeout = hso_net_tx_timeout, ++}; ++ ++/* initialize the network interface */ ++static void hso_net_init(struct net_device *net) ++{ ++ struct hso_net *hso_net = netdev_priv(net); ++ ++ D1("sizeof hso_net is %d", (int)sizeof(*hso_net)); ++ ++ /* fill in the other fields */ ++ net->netdev_ops = &hso_netdev_ops; ++ net->watchdog_timeo = HSO_NET_TX_TIMEOUT; ++ net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; ++ net->type = ARPHRD_NONE; ++ net->mtu = DEFAULT_MTU - 14; ++ net->tx_queue_len = 10; ++ net->ethtool_ops = &ops; ++ ++ /* and initialize the semaphore */ ++ spin_lock_init(&hso_net->net_lock); ++} ++ ++/* Adds a network device in the network device table */ ++static int add_net_device(struct hso_device *hso_dev) ++{ ++ int i; ++ ++ for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { ++ if (network_table[i] == NULL) { ++ network_table[i] = hso_dev; ++ break; ++ } ++ } ++ if (i == HSO_MAX_NET_DEVICES) ++ return -1; ++ return 0; ++} ++ ++static int hso_rfkill_set_block(void *data, bool blocked) ++{ ++ struct hso_device *hso_dev = data; ++ int enabled = !blocked; ++ int rv; ++ ++ mutex_lock(&hso_dev->mutex); ++ if (hso_dev->usb_gone) ++ rv = 0; ++ else ++ rv = usb_control_msg(hso_dev->usb, usb_rcvctrlpipe(hso_dev->usb, 0), ++ enabled ? 0x82 : 0x81, 0x40, 0, 0, NULL, 0, ++ USB_CTRL_SET_TIMEOUT); ++ mutex_unlock(&hso_dev->mutex); ++ return rv; ++} ++ ++static const struct rfkill_ops hso_rfkill_ops = { ++ .set_block = hso_rfkill_set_block, ++}; ++ ++/* Creates and sets up everything for rfkill */ ++static void hso_create_rfkill(struct hso_device *hso_dev, ++ struct usb_interface *interface) ++{ ++ struct hso_net *hso_net = dev2net(hso_dev); ++ struct device *dev = &hso_net->net->dev; ++ char *rfkn; ++ ++ rfkn = kzalloc(20, GFP_KERNEL); ++ if (!rfkn) ++ dev_err(dev, "%s - Out of memory\n", __func__); ++ ++ snprintf(rfkn, 20, "hso-%d", ++ interface->altsetting->desc.bInterfaceNumber); ++ ++ hso_net->rfkill = rfkill_alloc(rfkn, ++ &interface_to_usbdev(interface)->dev, ++ RFKILL_TYPE_WWAN, ++ &hso_rfkill_ops, hso_dev); ++ if (!hso_net->rfkill) { ++ dev_err(dev, "%s - Out of memory\n", __func__); ++ kfree(rfkn); ++ return; ++ } ++ if (rfkill_register(hso_net->rfkill) < 0) { ++ rfkill_destroy(hso_net->rfkill); ++ kfree(rfkn); ++ hso_net->rfkill = NULL; ++ dev_err(dev, "%s - Failed to register rfkill\n", __func__); ++ return; ++ } ++} ++ ++static struct device_type hso_type = { ++ .name = "wwan", ++}; ++ ++/* Creates our network device */ ++static struct hso_device *hso_create_net_device(struct usb_interface *interface, ++ int port_spec) ++{ ++ int result, i; ++ struct net_device *net; ++ struct hso_net *hso_net; ++ struct hso_device *hso_dev; ++ ++ hso_dev = hso_create_device(interface, port_spec); ++ if (!hso_dev) ++ return NULL; ++ ++ /* allocate our network device, then we can put in our private data */ ++ /* call hso_net_init to do the basic initialization */ ++ net = alloc_netdev(sizeof(struct hso_net), "hso%d", NET_NAME_UNKNOWN, ++ hso_net_init); ++ if (!net) { ++ dev_err(&interface->dev, "Unable to create ethernet device\n"); ++ goto exit; ++ } ++ ++ hso_net = netdev_priv(net); ++ ++ hso_dev->port_data.dev_net = hso_net; ++ hso_net->net = net; ++ hso_net->parent = hso_dev; ++ ++ hso_net->in_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, ++ USB_DIR_IN); ++ if (!hso_net->in_endp) { ++ dev_err(&interface->dev, "Can't find BULK IN endpoint\n"); ++ goto exit; ++ } ++ hso_net->out_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, ++ USB_DIR_OUT); ++ if (!hso_net->out_endp) { ++ dev_err(&interface->dev, "Can't find BULK OUT endpoint\n"); ++ goto exit; ++ } ++ SET_NETDEV_DEV(net, &interface->dev); ++ SET_NETDEV_DEVTYPE(net, &hso_type); ++ ++ /* registering our net device */ ++ result = register_netdev(net); ++ if (result) { ++ dev_err(&interface->dev, "Failed to register device\n"); ++ goto exit; ++ } ++ ++ /* start allocating */ ++ for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { ++ hso_net->mux_bulk_rx_urb_pool[i] = usb_alloc_urb(0, GFP_KERNEL); ++ if (!hso_net->mux_bulk_rx_urb_pool[i]) { ++ dev_err(&interface->dev, "Could not allocate rx urb\n"); ++ goto exit; ++ } ++ hso_net->mux_bulk_rx_buf_pool[i] = kzalloc(MUX_BULK_RX_BUF_SIZE, ++ GFP_KERNEL); ++ if (!hso_net->mux_bulk_rx_buf_pool[i]) ++ goto exit; ++ } ++ hso_net->mux_bulk_tx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!hso_net->mux_bulk_tx_urb) { ++ dev_err(&interface->dev, "Could not allocate tx urb\n"); ++ goto exit; ++ } ++ hso_net->mux_bulk_tx_buf = kzalloc(MUX_BULK_TX_BUF_SIZE, GFP_KERNEL); ++ if (!hso_net->mux_bulk_tx_buf) ++ goto exit; ++ ++ add_net_device(hso_dev); ++ ++ hso_log_port(hso_dev); ++ ++ hso_create_rfkill(hso_dev, interface); ++ ++ return hso_dev; ++exit: ++ hso_free_net_device(hso_dev); ++ return NULL; ++} ++ ++static void hso_free_tiomget(struct hso_serial *serial) ++{ ++ struct hso_tiocmget *tiocmget; ++ if (!serial) ++ return; ++ tiocmget = serial->tiocmget; ++ if (tiocmget) { ++ usb_free_urb(tiocmget->urb); ++ tiocmget->urb = NULL; ++ serial->tiocmget = NULL; ++ kfree(tiocmget); ++ } ++} ++ ++/* Frees an AT channel ( goes for both mux and non-mux ) */ ++static void hso_free_serial_device(struct hso_device *hso_dev) ++{ ++ struct hso_serial *serial = dev2ser(hso_dev); ++ ++ if (!serial) ++ return; ++ set_serial_by_index(serial->minor, NULL); ++ ++ hso_serial_common_free(serial); ++ ++ if (serial->shared_int) { ++ mutex_lock(&serial->shared_int->shared_int_lock); ++ if (--serial->shared_int->ref_count == 0) ++ hso_free_shared_int(serial->shared_int); ++ else ++ mutex_unlock(&serial->shared_int->shared_int_lock); ++ } ++ hso_free_tiomget(serial); ++ kfree(serial); ++ kfree(hso_dev); ++} ++ ++/* Creates a bulk AT channel */ ++static struct hso_device *hso_create_bulk_serial_device( ++ struct usb_interface *interface, int port) ++{ ++ struct hso_device *hso_dev; ++ struct hso_serial *serial; ++ int num_urbs; ++ struct hso_tiocmget *tiocmget; ++ ++ hso_dev = hso_create_device(interface, port); ++ if (!hso_dev) ++ return NULL; ++ ++ serial = kzalloc(sizeof(*serial), GFP_KERNEL); ++ if (!serial) ++ goto exit; ++ ++ serial->parent = hso_dev; ++ hso_dev->port_data.dev_serial = serial; ++ ++ if ((port & HSO_PORT_MASK) == HSO_PORT_MODEM) { ++ num_urbs = 2; ++ serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget), ++ GFP_KERNEL); ++ /* it isn't going to break our heart if serial->tiocmget ++ * allocation fails don't bother checking this. ++ */ ++ if (serial->tiocmget) { ++ tiocmget = serial->tiocmget; ++ tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (tiocmget->urb) { ++ mutex_init(&tiocmget->mutex); ++ init_waitqueue_head(&tiocmget->waitq); ++ tiocmget->endp = hso_get_ep( ++ interface, ++ USB_ENDPOINT_XFER_INT, ++ USB_DIR_IN); ++ } else ++ hso_free_tiomget(serial); ++ } ++ } ++ else ++ num_urbs = 1; ++ ++ if (hso_serial_common_create(serial, num_urbs, BULK_URB_RX_SIZE, ++ BULK_URB_TX_SIZE)) ++ goto exit; ++ ++ serial->in_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, ++ USB_DIR_IN); ++ if (!serial->in_endp) { ++ dev_err(&interface->dev, "Failed to find BULK IN ep\n"); ++ goto exit2; ++ } ++ ++ if (! ++ (serial->out_endp = ++ hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT))) { ++ dev_err(&interface->dev, "Failed to find BULK IN ep\n"); ++ goto exit2; ++ } ++ ++ serial->write_data = hso_std_serial_write_data; ++ ++ /* and record this serial */ ++ set_serial_by_index(serial->minor, serial); ++ ++ /* setup the proc dirs and files if needed */ ++ hso_log_port(hso_dev); ++ ++ /* done, return it */ ++ return hso_dev; ++ ++exit2: ++ hso_serial_common_free(serial); ++exit: ++ hso_free_tiomget(serial); ++ kfree(serial); ++ kfree(hso_dev); ++ return NULL; ++} ++ ++/* Creates a multiplexed AT channel */ ++static ++struct hso_device *hso_create_mux_serial_device(struct usb_interface *interface, ++ int port, ++ struct hso_shared_int *mux) ++{ ++ struct hso_device *hso_dev; ++ struct hso_serial *serial; ++ int port_spec; ++ ++ port_spec = HSO_INTF_MUX; ++ port_spec &= ~HSO_PORT_MASK; ++ ++ port_spec |= hso_mux_to_port(port); ++ if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NO_PORT) ++ return NULL; ++ ++ hso_dev = hso_create_device(interface, port_spec); ++ if (!hso_dev) ++ return NULL; ++ ++ serial = kzalloc(sizeof(*serial), GFP_KERNEL); ++ if (!serial) ++ goto exit; ++ ++ hso_dev->port_data.dev_serial = serial; ++ serial->parent = hso_dev; ++ ++ if (hso_serial_common_create ++ (serial, 1, CTRL_URB_RX_SIZE, CTRL_URB_TX_SIZE)) ++ goto exit; ++ ++ serial->tx_data_length--; ++ serial->write_data = hso_mux_serial_write_data; ++ ++ serial->shared_int = mux; ++ mutex_lock(&serial->shared_int->shared_int_lock); ++ serial->shared_int->ref_count++; ++ mutex_unlock(&serial->shared_int->shared_int_lock); ++ ++ /* and record this serial */ ++ set_serial_by_index(serial->minor, serial); ++ ++ /* setup the proc dirs and files if needed */ ++ hso_log_port(hso_dev); ++ ++ /* done, return it */ ++ return hso_dev; ++ ++exit: ++ if (serial) { ++ tty_unregister_device(tty_drv, serial->minor); ++ kfree(serial); ++ } ++ if (hso_dev) ++ kfree(hso_dev); ++ return NULL; ++ ++} ++ ++static void hso_free_shared_int(struct hso_shared_int *mux) ++{ ++ usb_free_urb(mux->shared_intr_urb); ++ kfree(mux->shared_intr_buf); ++ mutex_unlock(&mux->shared_int_lock); ++ kfree(mux); ++} ++ ++static ++struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface) ++{ ++ struct hso_shared_int *mux = kzalloc(sizeof(*mux), GFP_KERNEL); ++ ++ if (!mux) ++ return NULL; ++ ++ mux->intr_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_INT, ++ USB_DIR_IN); ++ if (!mux->intr_endp) { ++ dev_err(&interface->dev, "Can't find INT IN endpoint\n"); ++ goto exit; ++ } ++ ++ mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!mux->shared_intr_urb) { ++ dev_err(&interface->dev, "Could not allocate intr urb?\n"); ++ goto exit; ++ } ++ mux->shared_intr_buf = ++ kzalloc(le16_to_cpu(mux->intr_endp->wMaxPacketSize), ++ GFP_KERNEL); ++ if (!mux->shared_intr_buf) ++ goto exit; ++ ++ mutex_init(&mux->shared_int_lock); ++ ++ return mux; ++ ++exit: ++ kfree(mux->shared_intr_buf); ++ usb_free_urb(mux->shared_intr_urb); ++ kfree(mux); ++ return NULL; ++} ++ ++/* Gets the port spec for a certain interface */ ++static int hso_get_config_data(struct usb_interface *interface) ++{ ++ struct usb_device *usbdev = interface_to_usbdev(interface); ++ u8 *config_data = kmalloc(17, GFP_KERNEL); ++ u32 if_num = interface->altsetting->desc.bInterfaceNumber; ++ s32 result; ++ ++ if (!config_data) ++ return -ENOMEM; ++ if (usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), ++ 0x86, 0xC0, 0, 0, config_data, 17, ++ USB_CTRL_SET_TIMEOUT) != 0x11) { ++ kfree(config_data); ++ return -EIO; ++ } ++ ++ switch (config_data[if_num]) { ++ case 0x0: ++ result = 0; ++ break; ++ case 0x1: ++ result = HSO_PORT_DIAG; ++ break; ++ case 0x2: ++ result = HSO_PORT_GPS; ++ break; ++ case 0x3: ++ result = HSO_PORT_GPS_CONTROL; ++ break; ++ case 0x4: ++ result = HSO_PORT_APP; ++ break; ++ case 0x5: ++ result = HSO_PORT_APP2; ++ break; ++ case 0x6: ++ result = HSO_PORT_CONTROL; ++ break; ++ case 0x7: ++ result = HSO_PORT_NETWORK; ++ break; ++ case 0x8: ++ result = HSO_PORT_MODEM; ++ break; ++ case 0x9: ++ result = HSO_PORT_MSD; ++ break; ++ case 0xa: ++ result = HSO_PORT_PCSC; ++ break; ++ case 0xb: ++ result = HSO_PORT_VOICE; ++ break; ++ default: ++ result = 0; ++ } ++ ++ if (result) ++ result |= HSO_INTF_BULK; ++ ++ if (config_data[16] & 0x1) ++ result |= HSO_INFO_CRC_BUG; ++ ++ kfree(config_data); ++ return result; ++} ++ ++/* called once for each interface upon device insertion */ ++static int hso_probe(struct usb_interface *interface, ++ const struct usb_device_id *id) ++{ ++ int mux, i, if_num, port_spec; ++ unsigned char port_mask; ++ struct hso_device *hso_dev = NULL; ++ struct hso_shared_int *shared_int; ++ struct hso_device *tmp_dev = NULL; ++ ++ if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) { ++ dev_err(&interface->dev, "Not our interface\n"); ++ return -ENODEV; ++ } ++ ++ if_num = interface->altsetting->desc.bInterfaceNumber; ++ ++ /* Get the interface/port specification from either driver_info or from ++ * the device itself */ ++ if (id->driver_info) ++ port_spec = ((u32 *)(id->driver_info))[if_num]; ++ else ++ port_spec = hso_get_config_data(interface); ++ ++ /* Check if we need to switch to alt interfaces prior to port ++ * configuration */ ++ if (interface->num_altsetting > 1) ++ usb_set_interface(interface_to_usbdev(interface), if_num, 1); ++ interface->needs_remote_wakeup = 1; ++ ++ /* Allocate new hso device(s) */ ++ switch (port_spec & HSO_INTF_MASK) { ++ case HSO_INTF_MUX: ++ if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) { ++ /* Create the network device */ ++ if (!disable_net) { ++ hso_dev = hso_create_net_device(interface, ++ port_spec); ++ if (!hso_dev) ++ goto exit; ++ tmp_dev = hso_dev; ++ } ++ } ++ ++ if (hso_get_mux_ports(interface, &port_mask)) ++ /* TODO: de-allocate everything */ ++ goto exit; ++ ++ shared_int = hso_create_shared_int(interface); ++ if (!shared_int) ++ goto exit; ++ ++ for (i = 1, mux = 0; i < 0x100; i = i << 1, mux++) { ++ if (port_mask & i) { ++ hso_dev = hso_create_mux_serial_device( ++ interface, i, shared_int); ++ if (!hso_dev) ++ goto exit; ++ } ++ } ++ ++ if (tmp_dev) ++ hso_dev = tmp_dev; ++ break; ++ ++ case HSO_INTF_BULK: ++ /* It's a regular bulk interface */ ++ if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) { ++ if (!disable_net) ++ hso_dev = ++ hso_create_net_device(interface, port_spec); ++ } else { ++ hso_dev = ++ hso_create_bulk_serial_device(interface, port_spec); ++ } ++ if (!hso_dev) ++ goto exit; ++ break; ++ default: ++ goto exit; ++ } ++ ++ /* save our data pointer in this device */ ++ usb_set_intfdata(interface, hso_dev); ++ ++ /* done */ ++ return 0; ++exit: ++ hso_free_interface(interface); ++ return -ENODEV; ++} ++ ++/* device removed, cleaning up */ ++static void hso_disconnect(struct usb_interface *interface) ++{ ++ hso_free_interface(interface); ++ ++ /* remove reference of our private data */ ++ usb_set_intfdata(interface, NULL); ++} ++ ++static void async_get_intf(struct work_struct *data) ++{ ++ struct hso_device *hso_dev = ++ container_of(data, struct hso_device, async_get_intf); ++ usb_autopm_get_interface(hso_dev->interface); ++} ++ ++static void async_put_intf(struct work_struct *data) ++{ ++ struct hso_device *hso_dev = ++ container_of(data, struct hso_device, async_put_intf); ++ usb_autopm_put_interface(hso_dev->interface); ++} ++ ++static int hso_get_activity(struct hso_device *hso_dev) ++{ ++ if (hso_dev->usb->state == USB_STATE_SUSPENDED) { ++ if (!hso_dev->is_active) { ++ hso_dev->is_active = 1; ++ schedule_work(&hso_dev->async_get_intf); ++ } ++ } ++ ++ if (hso_dev->usb->state != USB_STATE_CONFIGURED) ++ return -EAGAIN; ++ ++ usb_mark_last_busy(hso_dev->usb); ++ ++ return 0; ++} ++ ++static int hso_put_activity(struct hso_device *hso_dev) ++{ ++ if (hso_dev->usb->state != USB_STATE_SUSPENDED) { ++ if (hso_dev->is_active) { ++ hso_dev->is_active = 0; ++ schedule_work(&hso_dev->async_put_intf); ++ return -EAGAIN; ++ } ++ } ++ hso_dev->is_active = 0; ++ return 0; ++} ++ ++/* called by kernel when we need to suspend device */ ++static int hso_suspend(struct usb_interface *iface, pm_message_t message) ++{ ++ int i, result; ++ ++ /* Stop all serial ports */ ++ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { ++ if (serial_table[i] && (serial_table[i]->interface == iface)) { ++ result = hso_stop_serial_device(serial_table[i]); ++ if (result) ++ goto out; ++ } ++ } ++ ++ /* Stop all network ports */ ++ for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { ++ if (network_table[i] && ++ (network_table[i]->interface == iface)) { ++ result = hso_stop_net_device(network_table[i]); ++ if (result) ++ goto out; ++ } ++ } ++ ++out: ++ return 0; ++} ++ ++/* called by kernel when we need to resume device */ ++static int hso_resume(struct usb_interface *iface) ++{ ++ int i, result = 0; ++ struct hso_net *hso_net; ++ ++ /* Start all serial ports */ ++ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { ++ if (serial_table[i] && (serial_table[i]->interface == iface)) { ++ if (atomic_read(&dev2ser(serial_table[i])->port.count)) { ++ result = ++ hso_start_serial_device(serial_table[i], GFP_NOIO); ++ hso_kick_transmit(dev2ser(serial_table[i])); ++ if (result) ++ goto out; ++ } ++ } ++ } ++ ++ /* Start all network ports */ ++ for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { ++ if (network_table[i] && ++ (network_table[i]->interface == iface)) { ++ hso_net = dev2net(network_table[i]); ++ if (hso_net->flags & IFF_UP) { ++ /* First transmit any lingering data, ++ then restart the device. */ ++ if (hso_net->skb_tx_buf) { ++ dev_dbg(&iface->dev, ++ "Transmitting" ++ " lingering data\n"); ++ hso_net_start_xmit(hso_net->skb_tx_buf, ++ hso_net->net); ++ hso_net->skb_tx_buf = NULL; ++ } ++ result = hso_start_net_device(network_table[i]); ++ if (result) ++ goto out; ++ } ++ } ++ } ++ ++out: ++ return result; ++} ++ ++static void reset_device(struct work_struct *data) ++{ ++ struct hso_device *hso_dev = ++ container_of(data, struct hso_device, reset_device); ++ struct usb_device *usb = hso_dev->usb; ++ int result; ++ ++ if (hso_dev->usb_gone) { ++ D1("No reset during disconnect\n"); ++ } else { ++ result = usb_lock_device_for_reset(usb, hso_dev->interface); ++ if (result < 0) ++ D1("unable to lock device for reset: %d\n", result); ++ else { ++ usb_reset_device(usb); ++ usb_unlock_device(usb); ++ } ++ } ++} ++ ++static void hso_serial_ref_free(struct kref *ref) ++{ ++ struct hso_device *hso_dev = container_of(ref, struct hso_device, ref); ++ ++ hso_free_serial_device(hso_dev); ++} ++ ++static void hso_free_interface(struct usb_interface *interface) ++{ ++ struct hso_serial *hso_dev; ++ int i; ++ ++ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { ++ if (serial_table[i] && ++ (serial_table[i]->interface == interface)) { ++ hso_dev = dev2ser(serial_table[i]); ++ tty_port_tty_hangup(&hso_dev->port, false); ++ mutex_lock(&hso_dev->parent->mutex); ++ hso_dev->parent->usb_gone = 1; ++ mutex_unlock(&hso_dev->parent->mutex); ++ kref_put(&serial_table[i]->ref, hso_serial_ref_free); ++ } ++ } ++ ++ for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { ++ if (network_table[i] && ++ (network_table[i]->interface == interface)) { ++ struct rfkill *rfk = dev2net(network_table[i])->rfkill; ++ /* hso_stop_net_device doesn't stop the net queue since ++ * traffic needs to start it again when suspended */ ++ netif_stop_queue(dev2net(network_table[i])->net); ++ hso_stop_net_device(network_table[i]); ++ cancel_work_sync(&network_table[i]->async_put_intf); ++ cancel_work_sync(&network_table[i]->async_get_intf); ++ if (rfk) { ++ rfkill_unregister(rfk); ++ rfkill_destroy(rfk); ++ } ++ hso_free_net_device(network_table[i]); ++ } ++ } ++} ++ ++/* Helper functions */ ++ ++/* Get the endpoint ! */ ++static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf, ++ int type, int dir) ++{ ++ int i; ++ struct usb_host_interface *iface = intf->cur_altsetting; ++ struct usb_endpoint_descriptor *endp; ++ ++ for (i = 0; i < iface->desc.bNumEndpoints; i++) { ++ endp = &iface->endpoint[i].desc; ++ if (((endp->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == dir) && ++ (usb_endpoint_type(endp) == type)) ++ return endp; ++ } ++ ++ return NULL; ++} ++ ++/* Get the byte that describes which ports are enabled */ ++static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports) ++{ ++ int i; ++ struct usb_host_interface *iface = intf->cur_altsetting; ++ ++ if (iface->extralen == 3) { ++ *ports = iface->extra[2]; ++ return 0; ++ } ++ ++ for (i = 0; i < iface->desc.bNumEndpoints; i++) { ++ if (iface->endpoint[i].extralen == 3) { ++ *ports = iface->endpoint[i].extra[2]; ++ return 0; ++ } ++ } ++ ++ return -1; ++} ++ ++/* interrupt urb needs to be submitted, used for serial read of muxed port */ ++static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int, ++ struct usb_device *usb, gfp_t gfp) ++{ ++ int result; ++ ++ usb_fill_int_urb(shared_int->shared_intr_urb, usb, ++ usb_rcvintpipe(usb, ++ shared_int->intr_endp->bEndpointAddress & 0x7F), ++ shared_int->shared_intr_buf, ++ 1, ++ intr_callback, shared_int, ++ shared_int->intr_endp->bInterval); ++ ++ result = usb_submit_urb(shared_int->shared_intr_urb, gfp); ++ if (result) ++ dev_warn(&usb->dev, "%s failed mux_intr_urb %d\n", __func__, ++ result); ++ ++ return result; ++} ++ ++/* operations setup of the serial interface */ ++static const struct tty_operations hso_serial_ops = { ++ .open = hso_serial_open, ++ .close = hso_serial_close, ++ .write = hso_serial_write, ++ .write_room = hso_serial_write_room, ++ .ioctl = hso_serial_ioctl, ++ .set_termios = hso_serial_set_termios, ++ .chars_in_buffer = hso_serial_chars_in_buffer, ++ .tiocmget = hso_serial_tiocmget, ++ .tiocmset = hso_serial_tiocmset, ++ .get_icount = hso_get_count, ++ .unthrottle = hso_unthrottle ++}; ++ ++static struct usb_driver hso_driver = { ++ .name = driver_name, ++ .probe = hso_probe, ++ .disconnect = hso_disconnect, ++ .id_table = hso_ids, ++ .suspend = hso_suspend, ++ .resume = hso_resume, ++ .reset_resume = hso_resume, ++ .supports_autosuspend = 1, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++static int __init hso_init(void) ++{ ++ int i; ++ int result; ++ ++ /* put it in the log */ ++ printk(KERN_INFO "hso: %s\n", version); ++ ++ /* Initialise the serial table semaphore and table */ ++ spin_lock_init(&serial_table_lock); ++ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) ++ serial_table[i] = NULL; ++ ++ /* allocate our driver using the proper amount of supported minors */ ++ tty_drv = alloc_tty_driver(HSO_SERIAL_TTY_MINORS); ++ if (!tty_drv) ++ return -ENOMEM; ++ ++ /* fill in all needed values */ ++ tty_drv->driver_name = driver_name; ++ tty_drv->name = tty_filename; ++ ++ /* if major number is provided as parameter, use that one */ ++ if (tty_major) ++ tty_drv->major = tty_major; ++ ++ tty_drv->minor_start = 0; ++ tty_drv->type = TTY_DRIVER_TYPE_SERIAL; ++ tty_drv->subtype = SERIAL_TYPE_NORMAL; ++ tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; ++ tty_drv->init_termios = tty_std_termios; ++ hso_init_termios(&tty_drv->init_termios); ++ tty_set_operations(tty_drv, &hso_serial_ops); ++ ++ /* register the tty driver */ ++ result = tty_register_driver(tty_drv); ++ if (result) { ++ printk(KERN_ERR "%s - tty_register_driver failed(%d)\n", ++ __func__, result); ++ goto err_free_tty; ++ } ++ ++ /* register this module as an usb driver */ ++ result = usb_register(&hso_driver); ++ if (result) { ++ printk(KERN_ERR "Could not register hso driver? error: %d\n", ++ result); ++ goto err_unreg_tty; ++ } ++ ++ /* done */ ++ return 0; ++err_unreg_tty: ++ tty_unregister_driver(tty_drv); ++err_free_tty: ++ put_tty_driver(tty_drv); ++ return result; ++} ++ ++static void __exit hso_exit(void) ++{ ++ printk(KERN_INFO "hso: unloaded\n"); ++ ++ tty_unregister_driver(tty_drv); ++ put_tty_driver(tty_drv); ++ /* deregister the usb driver */ ++ usb_deregister(&hso_driver); ++} ++ ++/* Module definitions */ ++module_init(hso_init); ++module_exit(hso_exit); ++ ++MODULE_AUTHOR(MOD_AUTHOR); ++MODULE_DESCRIPTION(MOD_DESCRIPTION); ++MODULE_LICENSE(MOD_LICENSE); ++ ++/* change the debug level (eg: insmod hso.ko debug=0x04) */ ++MODULE_PARM_DESC(debug, "Level of debug [0x01 | 0x02 | 0x04 | 0x08 | 0x10]"); ++module_param(debug, int, S_IRUGO | S_IWUSR); ++ ++/* set the major tty number (eg: insmod hso.ko tty_major=245) */ ++MODULE_PARM_DESC(tty_major, "Set the major tty number"); ++module_param(tty_major, int, S_IRUGO | S_IWUSR); ++ ++/* disable network interface (eg: insmod hso.ko disable_net=1) */ ++MODULE_PARM_DESC(disable_net, "Disable the network interface"); ++module_param(disable_net, int, S_IRUGO | S_IWUSR); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/huawei_cdc_ncm.c backports-3.18.1-1/drivers/net/usb/huawei_cdc_ncm.c +--- backports-3.18.1-1.org/drivers/net/usb/huawei_cdc_ncm.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/huawei_cdc_ncm.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,221 @@ ++/* huawei_cdc_ncm.c - handles Huawei devices using the CDC NCM protocol as ++ * transport layer. ++ * Copyright (C) 2013 Enrico Mioso mrkiko.rs@gmail.com ++ * ++ * ++ * ABSTRACT: ++ * This driver handles devices resembling the CDC NCM standard, but ++ * encapsulating another protocol inside it. An example are some Huawei 3G ++ * devices, exposing an embedded AT channel where you can set up the NCM ++ * connection. ++ * This code has been heavily inspired by the cdc_mbim.c driver, which is ++ * Copyright (c) 2012 Smith Micro Software, Inc. ++ * Copyright (c) 2012 Bjørn Mork bjorn@mork.no ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ */ ++ ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/ethtool.h> ++#include <linux/if_vlan.h> ++#include <linux/ip.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/usb/cdc.h> ++#include <linux/usb/usbnet.h> ++#include <linux/usb/cdc-wdm.h> ++#include <linux/usb/cdc_ncm.h> ++ ++/* Driver data */ ++struct huawei_cdc_ncm_state { ++ struct cdc_ncm_ctx *ctx; ++ atomic_t pmcount; ++ struct usb_driver *subdriver; ++ struct usb_interface *control; ++ struct usb_interface *data; ++}; ++ ++static int huawei_cdc_ncm_manage_power(struct usbnet *usbnet_dev, int on) ++{ ++ struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->data; ++ int rv; ++ ++ if ((on && atomic_add_return(1, &drvstate->pmcount) == 1) || ++ (!on && atomic_dec_and_test(&drvstate->pmcount))) { ++ rv = usb_autopm_get_interface(usbnet_dev->intf); ++ usbnet_dev->intf->needs_remote_wakeup = on; ++ if (!rv) ++ usb_autopm_put_interface(usbnet_dev->intf); ++ } ++ return 0; ++} ++ ++static int huawei_cdc_ncm_wdm_manage_power(struct usb_interface *intf, ++ int status) ++{ ++ struct usbnet *usbnet_dev = usb_get_intfdata(intf); ++ ++ /* can be called while disconnecting */ ++ if (!usbnet_dev) ++ return 0; ++ ++ return huawei_cdc_ncm_manage_power(usbnet_dev, status); ++} ++ ++ ++static int huawei_cdc_ncm_bind(struct usbnet *usbnet_dev, ++ struct usb_interface *intf) ++{ ++ struct cdc_ncm_ctx *ctx; ++ struct usb_driver *subdriver = ERR_PTR(-ENODEV); ++ int ret = -ENODEV; ++ struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->data; ++ ++ /* altsetting should always be 1 for NCM devices - so we hard-coded ++ * it here ++ */ ++ ret = cdc_ncm_bind_common(usbnet_dev, intf, 1); ++ if (ret) ++ goto err; ++ ++ ctx = drvstate->ctx; ++ ++ if (usbnet_dev->status) ++ /* The wMaxCommand buffer must be big enough to hold ++ * any message from the modem. Experience has shown ++ * that some replies are more than 256 bytes long ++ */ ++ subdriver = usb_cdc_wdm_register(ctx->control, ++ &usbnet_dev->status->desc, ++ 1024, /* wMaxCommand */ ++ huawei_cdc_ncm_wdm_manage_power); ++ if (IS_ERR(subdriver)) { ++ ret = PTR_ERR(subdriver); ++ cdc_ncm_unbind(usbnet_dev, intf); ++ goto err; ++ } ++ ++ /* Prevent usbnet from using the status descriptor */ ++ usbnet_dev->status = NULL; ++ ++ drvstate->subdriver = subdriver; ++ ++err: ++ return ret; ++} ++ ++static void huawei_cdc_ncm_unbind(struct usbnet *usbnet_dev, ++ struct usb_interface *intf) ++{ ++ struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->data; ++ struct cdc_ncm_ctx *ctx = drvstate->ctx; ++ ++ if (drvstate->subdriver && drvstate->subdriver->disconnect) ++ drvstate->subdriver->disconnect(ctx->control); ++ drvstate->subdriver = NULL; ++ ++ cdc_ncm_unbind(usbnet_dev, intf); ++} ++ ++static int huawei_cdc_ncm_suspend(struct usb_interface *intf, ++ pm_message_t message) ++{ ++ int ret = 0; ++ struct usbnet *usbnet_dev = usb_get_intfdata(intf); ++ struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->data; ++ struct cdc_ncm_ctx *ctx = drvstate->ctx; ++ ++ if (ctx == NULL) { ++ ret = -ENODEV; ++ goto error; ++ } ++ ++ ret = usbnet_suspend(intf, message); ++ if (ret < 0) ++ goto error; ++ ++ if (intf == ctx->control && ++ drvstate->subdriver && ++ drvstate->subdriver->suspend) ++ ret = drvstate->subdriver->suspend(intf, message); ++ if (ret < 0) ++ usbnet_resume(intf); ++ ++error: ++ return ret; ++} ++ ++static int huawei_cdc_ncm_resume(struct usb_interface *intf) ++{ ++ int ret = 0; ++ struct usbnet *usbnet_dev = usb_get_intfdata(intf); ++ struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->data; ++ bool callsub; ++ struct cdc_ncm_ctx *ctx = drvstate->ctx; ++ ++ /* should we call subdriver's resume function? */ ++ callsub = ++ (intf == ctx->control && ++ drvstate->subdriver && ++ drvstate->subdriver->resume); ++ ++ if (callsub) ++ ret = drvstate->subdriver->resume(intf); ++ if (ret < 0) ++ goto err; ++ ret = usbnet_resume(intf); ++ if (ret < 0 && callsub) ++ drvstate->subdriver->suspend(intf, PMSG_SUSPEND); ++err: ++ return ret; ++} ++ ++static const struct driver_info huawei_cdc_ncm_info = { ++ .description = "Huawei CDC NCM device", ++ .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN, ++ .bind = huawei_cdc_ncm_bind, ++ .unbind = huawei_cdc_ncm_unbind, ++ .manage_power = huawei_cdc_ncm_manage_power, ++ .rx_fixup = cdc_ncm_rx_fixup, ++ .tx_fixup = cdc_ncm_tx_fixup, ++}; ++ ++static const struct usb_device_id huawei_cdc_ncm_devs[] = { ++ /* Huawei NCM devices disguised as vendor specific */ ++ { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16), ++ .driver_info = (unsigned long)&huawei_cdc_ncm_info, ++ }, ++ { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), ++ .driver_info = (unsigned long)&huawei_cdc_ncm_info, ++ }, ++ { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x76), ++ .driver_info = (unsigned long)&huawei_cdc_ncm_info, ++ }, ++ { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x03, 0x16), ++ .driver_info = (unsigned long)&huawei_cdc_ncm_info, ++ }, ++ ++ /* Terminating entry */ ++ { ++ }, ++}; ++MODULE_DEVICE_TABLE(usb, huawei_cdc_ncm_devs); ++ ++static struct usb_driver huawei_cdc_ncm_driver = { ++ .name = "huawei_cdc_ncm", ++ .id_table = huawei_cdc_ncm_devs, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = huawei_cdc_ncm_suspend, ++ .resume = huawei_cdc_ncm_resume, ++ .reset_resume = huawei_cdc_ncm_resume, ++ .supports_autosuspend = 1, ++ .disable_hub_initiated_lpm = 1, ++}; ++module_usb_driver(huawei_cdc_ncm_driver); ++MODULE_AUTHOR("Enrico Mioso mrkiko.rs@gmail.com"); ++MODULE_DESCRIPTION("USB CDC NCM host driver with encapsulated protocol support"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/int51x1.c backports-3.18.1-1/drivers/net/usb/int51x1.c +--- backports-3.18.1-1.org/drivers/net/usb/int51x1.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/int51x1.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,199 @@ ++/* ++ * Copyright (c) 2009 Peter Holik ++ * ++ * Intellon usb PLC (Powerline Communications) usb net driver ++ * ++ * http://www.tandel.be/downloads/INT51X1_Datasheet.pdf ++ * ++ * Based on the work of Jan 'RedBully' Seiffert ++ */ ++ ++/* ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include <linux/module.h> ++#include <linux/ctype.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/slab.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/usb/usbnet.h> ++ ++#define INT51X1_VENDOR_ID 0x09e1 ++#define INT51X1_PRODUCT_ID 0x5121 ++ ++#define INT51X1_HEADER_SIZE 2 /* 2 byte header */ ++ ++#define PACKET_TYPE_PROMISCUOUS (1 << 0) ++#define PACKET_TYPE_ALL_MULTICAST (1 << 1) /* no filter */ ++#define PACKET_TYPE_DIRECTED (1 << 2) ++#define PACKET_TYPE_BROADCAST (1 << 3) ++#define PACKET_TYPE_MULTICAST (1 << 4) /* filtered */ ++ ++#define SET_ETHERNET_PACKET_FILTER 0x43 ++ ++static int int51x1_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ int len; ++ ++ if (!(pskb_may_pull(skb, INT51X1_HEADER_SIZE))) { ++ netdev_err(dev->net, "unexpected tiny rx frame\n"); ++ return 0; ++ } ++ ++ len = le16_to_cpu(*(__le16 *)&skb->data[skb->len - 2]); ++ ++ skb_trim(skb, len); ++ ++ return 1; ++} ++ ++static struct sk_buff *int51x1_tx_fixup(struct usbnet *dev, ++ struct sk_buff *skb, gfp_t flags) ++{ ++ int pack_len = skb->len; ++ int pack_with_header_len = pack_len + INT51X1_HEADER_SIZE; ++ int headroom = skb_headroom(skb); ++ int tailroom = skb_tailroom(skb); ++ int need_tail = 0; ++ __le16 *len; ++ ++ /* if packet and our header is smaler than 64 pad to 64 (+ ZLP) */ ++ if ((pack_with_header_len) < dev->maxpacket) ++ need_tail = dev->maxpacket - pack_with_header_len + 1; ++ /* ++ * usbnet would send a ZLP if packetlength mod urbsize == 0 for us, ++ * but we need to know ourself, because this would add to the length ++ * we send down to the device... ++ */ ++ else if (!(pack_with_header_len % dev->maxpacket)) ++ need_tail = 1; ++ ++ if (!skb_cloned(skb) && ++ (headroom + tailroom >= need_tail + INT51X1_HEADER_SIZE)) { ++ if (headroom < INT51X1_HEADER_SIZE || tailroom < need_tail) { ++ skb->data = memmove(skb->head + INT51X1_HEADER_SIZE, ++ skb->data, skb->len); ++ skb_set_tail_pointer(skb, skb->len); ++ } ++ } else { ++ struct sk_buff *skb2; ++ ++ skb2 = skb_copy_expand(skb, ++ INT51X1_HEADER_SIZE, ++ need_tail, ++ flags); ++ dev_kfree_skb_any(skb); ++ if (!skb2) ++ return NULL; ++ skb = skb2; ++ } ++ ++ pack_len += need_tail; ++ pack_len &= 0x07ff; ++ ++ len = (__le16 *) __skb_push(skb, INT51X1_HEADER_SIZE); ++ *len = cpu_to_le16(pack_len); ++ ++ if(need_tail) ++ memset(__skb_put(skb, need_tail), 0, need_tail); ++ ++ return skb; ++} ++ ++static void int51x1_set_multicast(struct net_device *netdev) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ u16 filter = PACKET_TYPE_DIRECTED | PACKET_TYPE_BROADCAST; ++ ++ if (netdev->flags & IFF_PROMISC) { ++ /* do not expect to see traffic of other PLCs */ ++ filter |= PACKET_TYPE_PROMISCUOUS; ++ netdev_info(dev->net, "promiscuous mode enabled\n"); ++ } else if (!netdev_mc_empty(netdev) || ++ (netdev->flags & IFF_ALLMULTI)) { ++ filter |= PACKET_TYPE_ALL_MULTICAST; ++ netdev_dbg(dev->net, "receive all multicast enabled\n"); ++ } else { ++ /* ~PROMISCUOUS, ~MULTICAST */ ++ netdev_dbg(dev->net, "receive own packets only\n"); ++ } ++ ++ usbnet_write_cmd_async(dev, SET_ETHERNET_PACKET_FILTER, ++ USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, ++ filter, 0, NULL, 0); ++} ++ ++static const struct net_device_ops int51x1_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = usbnet_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_set_rx_mode = int51x1_set_multicast, ++}; ++ ++static int int51x1_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int status = usbnet_get_ethernet_addr(dev, 3); ++ ++ if (status) ++ return status; ++ ++ dev->net->hard_header_len += INT51X1_HEADER_SIZE; ++ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; ++ dev->net->netdev_ops = &int51x1_netdev_ops; ++ ++ return usbnet_get_endpoints(dev, intf); ++} ++ ++static const struct driver_info int51x1_info = { ++ .description = "Intellon usb powerline adapter", ++ .bind = int51x1_bind, ++ .rx_fixup = int51x1_rx_fixup, ++ .tx_fixup = int51x1_tx_fixup, ++ .in = 1, ++ .out = 2, ++ .flags = FLAG_ETHER, ++}; ++ ++static const struct usb_device_id products[] = { ++ { ++ USB_DEVICE(INT51X1_VENDOR_ID, INT51X1_PRODUCT_ID), ++ .driver_info = (unsigned long) &int51x1_info, ++ }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver int51x1_driver = { ++ .name = "int51x1", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(int51x1_driver); ++ ++MODULE_AUTHOR("Peter Holik"); ++MODULE_DESCRIPTION("Intellon usb powerline adapter"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/ipheth.c backports-3.18.1-1/drivers/net/usb/ipheth.c +--- backports-3.18.1-1.org/drivers/net/usb/ipheth.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/ipheth.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,588 @@ ++/* ++ * ipheth.c - Apple iPhone USB Ethernet driver ++ * ++ * Copyright (c) 2009 Diego Giagio diego@giagio.com ++ * 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. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of GIAGIO.COM nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * Alternatively, provided that this notice is retained in full, this ++ * software may be distributed under the terms of the GNU General ++ * Public License ("GPL") version 2, in which case the provisions of the ++ * GPL apply INSTEAD OF those given above. ++ * ++ * The provided data structures and external interfaces from this code ++ * are not restricted to be used by modules with a GPL compatible license. ++ * ++ * 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 MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * 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 ++ * DAMAGE. ++ * ++ * ++ * Attention: iPhone device must be paired, otherwise it won't respond to our ++ * driver. For more info: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/errno.h> ++#include <linux/slab.h> ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/usb.h> ++#include <linux/workqueue.h> ++ ++#define USB_VENDOR_APPLE 0x05ac ++#define USB_PRODUCT_IPHONE 0x1290 ++#define USB_PRODUCT_IPHONE_3G 0x1292 ++#define USB_PRODUCT_IPHONE_3GS 0x1294 ++#define USB_PRODUCT_IPHONE_4 0x1297 ++#define USB_PRODUCT_IPAD 0x129a ++#define USB_PRODUCT_IPAD_2 0x12a2 ++#define USB_PRODUCT_IPAD_3 0x12a6 ++#define USB_PRODUCT_IPAD_MINI 0x12ab ++#define USB_PRODUCT_IPHONE_4_VZW 0x129c ++#define USB_PRODUCT_IPHONE_4S 0x12a0 ++#define USB_PRODUCT_IPHONE_5 0x12a8 ++ ++#define IPHETH_USBINTF_CLASS 255 ++#define IPHETH_USBINTF_SUBCLASS 253 ++#define IPHETH_USBINTF_PROTO 1 ++ ++#define IPHETH_BUF_SIZE 1516 ++#define IPHETH_IP_ALIGN 2 /* padding at front of URB */ ++#define IPHETH_TX_TIMEOUT (5 * HZ) ++ ++#define IPHETH_INTFNUM 2 ++#define IPHETH_ALT_INTFNUM 1 ++ ++#define IPHETH_CTRL_ENDP 0x00 ++#define IPHETH_CTRL_BUF_SIZE 0x40 ++#define IPHETH_CTRL_TIMEOUT (5 * HZ) ++ ++#define IPHETH_CMD_GET_MACADDR 0x00 ++#define IPHETH_CMD_CARRIER_CHECK 0x45 ++ ++#define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ) ++#define IPHETH_CARRIER_ON 0x04 ++ ++static struct usb_device_id ipheth_table[] = { ++ { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPHONE, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3G, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPAD, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPAD_2, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPAD_3, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPAD_MINI, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { USB_DEVICE_AND_INTERFACE_INFO( ++ USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_5, ++ IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, ++ IPHETH_USBINTF_PROTO) }, ++ { } ++}; ++MODULE_DEVICE_TABLE(usb, ipheth_table); ++ ++struct ipheth_device { ++ struct usb_device *udev; ++ struct usb_interface *intf; ++ struct net_device *net; ++ struct sk_buff *tx_skb; ++ struct urb *tx_urb; ++ struct urb *rx_urb; ++ unsigned char *tx_buf; ++ unsigned char *rx_buf; ++ unsigned char *ctrl_buf; ++ u8 bulk_in; ++ u8 bulk_out; ++ struct delayed_work carrier_work; ++}; ++ ++static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags); ++ ++static int ipheth_alloc_urbs(struct ipheth_device *iphone) ++{ ++ struct urb *tx_urb = NULL; ++ struct urb *rx_urb = NULL; ++ u8 *tx_buf = NULL; ++ u8 *rx_buf = NULL; ++ ++ tx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (tx_urb == NULL) ++ goto error_nomem; ++ ++ rx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (rx_urb == NULL) ++ goto free_tx_urb; ++ ++ tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE, ++ GFP_KERNEL, &tx_urb->transfer_dma); ++ if (tx_buf == NULL) ++ goto free_rx_urb; ++ ++ rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE, ++ GFP_KERNEL, &rx_urb->transfer_dma); ++ if (rx_buf == NULL) ++ goto free_tx_buf; ++ ++ ++ iphone->tx_urb = tx_urb; ++ iphone->rx_urb = rx_urb; ++ iphone->tx_buf = tx_buf; ++ iphone->rx_buf = rx_buf; ++ return 0; ++ ++free_tx_buf: ++ usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, tx_buf, ++ tx_urb->transfer_dma); ++free_rx_urb: ++ usb_free_urb(rx_urb); ++free_tx_urb: ++ usb_free_urb(tx_urb); ++error_nomem: ++ return -ENOMEM; ++} ++ ++static void ipheth_free_urbs(struct ipheth_device *iphone) ++{ ++ usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf, ++ iphone->rx_urb->transfer_dma); ++ usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf, ++ iphone->tx_urb->transfer_dma); ++ usb_free_urb(iphone->rx_urb); ++ usb_free_urb(iphone->tx_urb); ++} ++ ++static void ipheth_kill_urbs(struct ipheth_device *dev) ++{ ++ usb_kill_urb(dev->tx_urb); ++ usb_kill_urb(dev->rx_urb); ++} ++ ++static void ipheth_rcvbulk_callback(struct urb *urb) ++{ ++ struct ipheth_device *dev; ++ struct sk_buff *skb; ++ int status; ++ char *buf; ++ int len; ++ ++ dev = urb->context; ++ if (dev == NULL) ++ return; ++ ++ status = urb->status; ++ switch (status) { ++ case -ENOENT: ++ case -ECONNRESET: ++ case -ESHUTDOWN: ++ return; ++ case 0: ++ break; ++ default: ++ dev_err(&dev->intf->dev, "%s: urb status: %d\n", ++ __func__, status); ++ return; ++ } ++ ++ if (urb->actual_length <= IPHETH_IP_ALIGN) { ++ dev->net->stats.rx_length_errors++; ++ return; ++ } ++ len = urb->actual_length - IPHETH_IP_ALIGN; ++ buf = urb->transfer_buffer + IPHETH_IP_ALIGN; ++ ++ skb = dev_alloc_skb(len); ++ if (!skb) { ++ dev_err(&dev->intf->dev, "%s: dev_alloc_skb: -ENOMEM\n", ++ __func__); ++ dev->net->stats.rx_dropped++; ++ return; ++ } ++ ++ memcpy(skb_put(skb, len), buf, len); ++ skb->dev = dev->net; ++ skb->protocol = eth_type_trans(skb, dev->net); ++ ++ dev->net->stats.rx_packets++; ++ dev->net->stats.rx_bytes += len; ++ ++ netif_rx(skb); ++ ipheth_rx_submit(dev, GFP_ATOMIC); ++} ++ ++static void ipheth_sndbulk_callback(struct urb *urb) ++{ ++ struct ipheth_device *dev; ++ int status = urb->status; ++ ++ dev = urb->context; ++ if (dev == NULL) ++ return; ++ ++ if (status != 0 && ++ status != -ENOENT && ++ status != -ECONNRESET && ++ status != -ESHUTDOWN) ++ dev_err(&dev->intf->dev, "%s: urb status: %d\n", ++ __func__, status); ++ ++ dev_kfree_skb_irq(dev->tx_skb); ++ netif_wake_queue(dev->net); ++} ++ ++static int ipheth_carrier_set(struct ipheth_device *dev) ++{ ++ struct usb_device *udev = dev->udev; ++ int retval; ++ ++ retval = usb_control_msg(udev, ++ usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP), ++ IPHETH_CMD_CARRIER_CHECK, /* request */ ++ 0xc0, /* request type */ ++ 0x00, /* value */ ++ 0x02, /* index */ ++ dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE, ++ IPHETH_CTRL_TIMEOUT); ++ if (retval < 0) { ++ dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n", ++ __func__, retval); ++ return retval; ++ } ++ ++ if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON) ++ netif_carrier_on(dev->net); ++ else ++ netif_carrier_off(dev->net); ++ ++ return 0; ++} ++ ++static void ipheth_carrier_check_work(struct work_struct *work) ++{ ++ struct ipheth_device *dev = container_of(work, struct ipheth_device, ++ carrier_work.work); ++ ++ ipheth_carrier_set(dev); ++ schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT); ++} ++ ++static int ipheth_get_macaddr(struct ipheth_device *dev) ++{ ++ struct usb_device *udev = dev->udev; ++ struct net_device *net = dev->net; ++ int retval; ++ ++ retval = usb_control_msg(udev, ++ usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP), ++ IPHETH_CMD_GET_MACADDR, /* request */ ++ 0xc0, /* request type */ ++ 0x00, /* value */ ++ 0x02, /* index */ ++ dev->ctrl_buf, ++ IPHETH_CTRL_BUF_SIZE, ++ IPHETH_CTRL_TIMEOUT); ++ if (retval < 0) { ++ dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n", ++ __func__, retval); ++ } else if (retval < ETH_ALEN) { ++ dev_err(&dev->intf->dev, ++ "%s: usb_control_msg: short packet: %d bytes\n", ++ __func__, retval); ++ retval = -EINVAL; ++ } else { ++ memcpy(net->dev_addr, dev->ctrl_buf, ETH_ALEN); ++ retval = 0; ++ } ++ ++ return retval; ++} ++ ++static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags) ++{ ++ struct usb_device *udev = dev->udev; ++ int retval; ++ ++ usb_fill_bulk_urb(dev->rx_urb, udev, ++ usb_rcvbulkpipe(udev, dev->bulk_in), ++ dev->rx_buf, IPHETH_BUF_SIZE, ++ ipheth_rcvbulk_callback, ++ dev); ++ dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ retval = usb_submit_urb(dev->rx_urb, mem_flags); ++ if (retval) ++ dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n", ++ __func__, retval); ++ return retval; ++} ++ ++static int ipheth_open(struct net_device *net) ++{ ++ struct ipheth_device *dev = netdev_priv(net); ++ struct usb_device *udev = dev->udev; ++ int retval = 0; ++ ++ usb_set_interface(udev, IPHETH_INTFNUM, IPHETH_ALT_INTFNUM); ++ ++ retval = ipheth_carrier_set(dev); ++ if (retval) ++ return retval; ++ ++ retval = ipheth_rx_submit(dev, GFP_KERNEL); ++ if (retval) ++ return retval; ++ ++ schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT); ++ netif_start_queue(net); ++ return retval; ++} ++ ++static int ipheth_close(struct net_device *net) ++{ ++ struct ipheth_device *dev = netdev_priv(net); ++ ++ cancel_delayed_work_sync(&dev->carrier_work); ++ netif_stop_queue(net); ++ return 0; ++} ++ ++static int ipheth_tx(struct sk_buff *skb, struct net_device *net) ++{ ++ struct ipheth_device *dev = netdev_priv(net); ++ struct usb_device *udev = dev->udev; ++ int retval; ++ ++ /* Paranoid */ ++ if (skb->len > IPHETH_BUF_SIZE) { ++ WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len); ++ dev->net->stats.tx_dropped++; ++ dev_kfree_skb_irq(skb); ++ return NETDEV_TX_OK; ++ } ++ ++ memcpy(dev->tx_buf, skb->data, skb->len); ++ if (skb->len < IPHETH_BUF_SIZE) ++ memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len); ++ ++ usb_fill_bulk_urb(dev->tx_urb, udev, ++ usb_sndbulkpipe(udev, dev->bulk_out), ++ dev->tx_buf, IPHETH_BUF_SIZE, ++ ipheth_sndbulk_callback, ++ dev); ++ dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC); ++ if (retval) { ++ dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n", ++ __func__, retval); ++ dev->net->stats.tx_errors++; ++ dev_kfree_skb_irq(skb); ++ } else { ++ dev->tx_skb = skb; ++ ++ dev->net->stats.tx_packets++; ++ dev->net->stats.tx_bytes += skb->len; ++ netif_stop_queue(net); ++ } ++ ++ return NETDEV_TX_OK; ++} ++ ++static void ipheth_tx_timeout(struct net_device *net) ++{ ++ struct ipheth_device *dev = netdev_priv(net); ++ ++ dev_err(&dev->intf->dev, "%s: TX timeout\n", __func__); ++ dev->net->stats.tx_errors++; ++ usb_unlink_urb(dev->tx_urb); ++} ++ ++static u32 ipheth_ethtool_op_get_link(struct net_device *net) ++{ ++ struct ipheth_device *dev = netdev_priv(net); ++ return netif_carrier_ok(dev->net); ++} ++ ++static const struct ethtool_ops ops = { ++ .get_link = ipheth_ethtool_op_get_link ++}; ++ ++static const struct net_device_ops ipheth_netdev_ops = { ++ .ndo_open = ipheth_open, ++ .ndo_stop = ipheth_close, ++ .ndo_start_xmit = ipheth_tx, ++ .ndo_tx_timeout = ipheth_tx_timeout, ++}; ++ ++static int ipheth_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *udev = interface_to_usbdev(intf); ++ struct usb_host_interface *hintf; ++ struct usb_endpoint_descriptor *endp; ++ struct ipheth_device *dev; ++ struct net_device *netdev; ++ int i; ++ int retval; ++ ++ netdev = alloc_etherdev(sizeof(struct ipheth_device)); ++ if (!netdev) ++ return -ENOMEM; ++ ++ netdev->netdev_ops = &ipheth_netdev_ops; ++ netdev->watchdog_timeo = IPHETH_TX_TIMEOUT; ++ strcpy(netdev->name, "eth%d"); ++ ++ dev = netdev_priv(netdev); ++ dev->udev = udev; ++ dev->net = netdev; ++ dev->intf = intf; ++ ++ /* Set up endpoints */ ++ hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM); ++ if (hintf == NULL) { ++ retval = -ENODEV; ++ dev_err(&intf->dev, "Unable to find alternate settings interface\n"); ++ goto err_endpoints; ++ } ++ ++ for (i = 0; i < hintf->desc.bNumEndpoints; i++) { ++ endp = &hintf->endpoint[i].desc; ++ if (usb_endpoint_is_bulk_in(endp)) ++ dev->bulk_in = endp->bEndpointAddress; ++ else if (usb_endpoint_is_bulk_out(endp)) ++ dev->bulk_out = endp->bEndpointAddress; ++ } ++ if (!(dev->bulk_in && dev->bulk_out)) { ++ retval = -ENODEV; ++ dev_err(&intf->dev, "Unable to find endpoints\n"); ++ goto err_endpoints; ++ } ++ ++ dev->ctrl_buf = kmalloc(IPHETH_CTRL_BUF_SIZE, GFP_KERNEL); ++ if (dev->ctrl_buf == NULL) { ++ retval = -ENOMEM; ++ goto err_alloc_ctrl_buf; ++ } ++ ++ retval = ipheth_get_macaddr(dev); ++ if (retval) ++ goto err_get_macaddr; ++ ++ INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work); ++ ++ retval = ipheth_alloc_urbs(dev); ++ if (retval) { ++ dev_err(&intf->dev, "error allocating urbs: %d\n", retval); ++ goto err_alloc_urbs; ++ } ++ ++ usb_set_intfdata(intf, dev); ++ ++ SET_NETDEV_DEV(netdev, &intf->dev); ++ netdev->ethtool_ops = &ops; ++ ++ retval = register_netdev(netdev); ++ if (retval) { ++ dev_err(&intf->dev, "error registering netdev: %d\n", retval); ++ retval = -EIO; ++ goto err_register_netdev; ++ } ++ ++ dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n"); ++ return 0; ++ ++err_register_netdev: ++ ipheth_free_urbs(dev); ++err_alloc_urbs: ++err_get_macaddr: ++err_alloc_ctrl_buf: ++ kfree(dev->ctrl_buf); ++err_endpoints: ++ free_netdev(netdev); ++ return retval; ++} ++ ++static void ipheth_disconnect(struct usb_interface *intf) ++{ ++ struct ipheth_device *dev; ++ ++ dev = usb_get_intfdata(intf); ++ if (dev != NULL) { ++ unregister_netdev(dev->net); ++ ipheth_kill_urbs(dev); ++ ipheth_free_urbs(dev); ++ kfree(dev->ctrl_buf); ++ free_netdev(dev->net); ++ } ++ usb_set_intfdata(intf, NULL); ++ dev_info(&intf->dev, "Apple iPhone USB Ethernet now disconnected\n"); ++} ++ ++static struct usb_driver ipheth_driver = { ++ .name = "ipheth", ++ .probe = ipheth_probe, ++ .disconnect = ipheth_disconnect, ++ .id_table = ipheth_table, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(ipheth_driver); ++ ++MODULE_AUTHOR("Diego Giagio diego@giagio.com"); ++MODULE_DESCRIPTION("Apple iPhone USB Ethernet driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/kalmia.c backports-3.18.1-1/drivers/net/usb/kalmia.c +--- backports-3.18.1-1.org/drivers/net/usb/kalmia.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/kalmia.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,366 @@ ++/* ++ * USB network interface driver for Samsung Kalmia based LTE USB modem like the ++ * Samsung GT-B3730 and GT-B3710. ++ * ++ * Copyright (C) 2011 Marius Bjoernstad Kotsbak marius@kotsbak.com ++ * ++ * Sponsored by Quicklink Video Distribution Services Ltd. ++ * ++ * Based on the cdc_eem module. ++ * ++ * 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 <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ctype.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/crc32.h> ++#include <linux/usb/cdc.h> ++#include <linux/usb/usbnet.h> ++#include <linux/gfp.h> ++ ++/* ++ * The Samsung Kalmia based LTE USB modems have a CDC ACM port for modem control ++ * handled by the "option" module and an ethernet data port handled by this ++ * module. ++ * ++ * The stick must first be switched into modem mode by usb_modeswitch ++ * or similar tool. Then the modem gets sent two initialization packets by ++ * this module, which gives the MAC address of the device. User space can then ++ * connect the modem using AT commands through the ACM port and then use ++ * DHCP on the network interface exposed by this module. Network packets are ++ * sent to and from the modem in a proprietary format discovered after watching ++ * the behavior of the windows driver for the modem. ++ * ++ * More information about the use of the modem is available in usb_modeswitch ++ * forum and the project page: ++ * ++ * http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=465 ++ * https://github.com/mkotsbak/Samsung-GT-B3730-linux-driver ++ */ ++ ++/* #define DEBUG */ ++/* #define VERBOSE */ ++ ++#define KALMIA_HEADER_LENGTH 6 ++#define KALMIA_ALIGN_SIZE 4 ++#define KALMIA_USB_TIMEOUT 10000 ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int ++kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len, ++ u8 *buffer, u8 expected_len) ++{ ++ int act_len; ++ int status; ++ ++ netdev_dbg(dev->net, "Sending init packet"); ++ ++ status = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 0x02), ++ init_msg, init_msg_len, &act_len, KALMIA_USB_TIMEOUT); ++ if (status != 0) { ++ netdev_err(dev->net, ++ "Error sending init packet. Status %i, length %i\n", ++ status, act_len); ++ return status; ++ } ++ else if (act_len != init_msg_len) { ++ netdev_err(dev->net, ++ "Did not send all of init packet. Bytes sent: %i", ++ act_len); ++ } ++ else { ++ netdev_dbg(dev->net, "Successfully sent init packet."); ++ } ++ ++ status = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, 0x81), ++ buffer, expected_len, &act_len, KALMIA_USB_TIMEOUT); ++ ++ if (status != 0) ++ netdev_err(dev->net, ++ "Error receiving init result. Status %i, length %i\n", ++ status, act_len); ++ else if (act_len != expected_len) ++ netdev_err(dev->net, "Unexpected init result length: %i\n", ++ act_len); ++ ++ return status; ++} ++ ++static int ++kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr) ++{ ++ static const char init_msg_1[] = ++ { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, ++ 0x00, 0x00 }; ++ static const char init_msg_2[] = ++ { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4, ++ 0x00, 0x00 }; ++ static const int buflen = 28; ++ char *usb_buf; ++ int status; ++ ++ usb_buf = kmalloc(buflen, GFP_DMA | GFP_KERNEL); ++ if (!usb_buf) ++ return -ENOMEM; ++ ++ memcpy(usb_buf, init_msg_1, 12); ++ status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_1) ++ / sizeof(init_msg_1[0]), usb_buf, 24); ++ if (status != 0) ++ return status; ++ ++ memcpy(usb_buf, init_msg_2, 12); ++ status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_2) ++ / sizeof(init_msg_2[0]), usb_buf, 28); ++ if (status != 0) ++ return status; ++ ++ memcpy(ethernet_addr, usb_buf + 10, ETH_ALEN); ++ ++ kfree(usb_buf); ++ return status; ++} ++ ++static int ++kalmia_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int status; ++ u8 ethernet_addr[ETH_ALEN]; ++ ++ /* Don't bind to AT command interface */ ++ if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) ++ return -EINVAL; ++ ++ dev->in = usb_rcvbulkpipe(dev->udev, 0x81 & USB_ENDPOINT_NUMBER_MASK); ++ dev->out = usb_sndbulkpipe(dev->udev, 0x02 & USB_ENDPOINT_NUMBER_MASK); ++ dev->status = NULL; ++ ++ dev->net->hard_header_len += KALMIA_HEADER_LENGTH; ++ dev->hard_mtu = 1400; ++ dev->rx_urb_size = dev->hard_mtu * 10; // Found as optimal after testing ++ ++ status = kalmia_init_and_get_ethernet_addr(dev, ethernet_addr); ++ ++ if (status < 0) { ++ usb_set_intfdata(intf, NULL); ++ usb_driver_release_interface(driver_of(intf), intf); ++ return status; ++ } ++ ++ memcpy(dev->net->dev_addr, ethernet_addr, ETH_ALEN); ++ ++ return status; ++} ++ ++static struct sk_buff * ++kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) ++{ ++ struct sk_buff *skb2 = NULL; ++ u16 content_len; ++ unsigned char *header_start; ++ unsigned char ether_type_1, ether_type_2; ++ u8 remainder, padlen = 0; ++ ++ if (!skb_cloned(skb)) { ++ int headroom = skb_headroom(skb); ++ int tailroom = skb_tailroom(skb); ++ ++ if ((tailroom >= KALMIA_ALIGN_SIZE) && (headroom ++ >= KALMIA_HEADER_LENGTH)) ++ goto done; ++ ++ if ((headroom + tailroom) > (KALMIA_HEADER_LENGTH ++ + KALMIA_ALIGN_SIZE)) { ++ skb->data = memmove(skb->head + KALMIA_HEADER_LENGTH, ++ skb->data, skb->len); ++ skb_set_tail_pointer(skb, skb->len); ++ goto done; ++ } ++ } ++ ++ skb2 = skb_copy_expand(skb, KALMIA_HEADER_LENGTH, ++ KALMIA_ALIGN_SIZE, flags); ++ if (!skb2) ++ return NULL; ++ ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ ++done: ++ header_start = skb_push(skb, KALMIA_HEADER_LENGTH); ++ ether_type_1 = header_start[KALMIA_HEADER_LENGTH + 12]; ++ ether_type_2 = header_start[KALMIA_HEADER_LENGTH + 13]; ++ ++ netdev_dbg(dev->net, "Sending etherType: %02x%02x", ether_type_1, ++ ether_type_2); ++ ++ /* According to empiric data for data packages */ ++ header_start[0] = 0x57; ++ header_start[1] = 0x44; ++ content_len = skb->len - KALMIA_HEADER_LENGTH; ++ ++ put_unaligned_le16(content_len, &header_start[2]); ++ header_start[4] = ether_type_1; ++ header_start[5] = ether_type_2; ++ ++ /* Align to 4 bytes by padding with zeros */ ++ remainder = skb->len % KALMIA_ALIGN_SIZE; ++ if (remainder > 0) { ++ padlen = KALMIA_ALIGN_SIZE - remainder; ++ memset(skb_put(skb, padlen), 0, padlen); ++ } ++ ++ netdev_dbg(dev->net, ++ "Sending package with length %i and padding %i. Header: %6phC.", ++ content_len, padlen, header_start); ++ ++ return skb; ++} ++ ++static int ++kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ /* ++ * Our task here is to strip off framing, leaving skb with one ++ * data frame for the usbnet framework code to process. ++ */ ++ static const u8 HEADER_END_OF_USB_PACKET[] = ++ { 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 }; ++ static const u8 EXPECTED_UNKNOWN_HEADER_1[] = ++ { 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 }; ++ static const u8 EXPECTED_UNKNOWN_HEADER_2[] = ++ { 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 }; ++ int i = 0; ++ ++ /* incomplete header? */ ++ if (skb->len < KALMIA_HEADER_LENGTH) ++ return 0; ++ ++ do { ++ struct sk_buff *skb2 = NULL; ++ u8 *header_start; ++ u16 usb_packet_length, ether_packet_length; ++ int is_last; ++ ++ header_start = skb->data; ++ ++ if (unlikely(header_start[0] != 0x57 || header_start[1] != 0x44)) { ++ if (!memcmp(header_start, EXPECTED_UNKNOWN_HEADER_1, ++ sizeof(EXPECTED_UNKNOWN_HEADER_1)) || !memcmp( ++ header_start, EXPECTED_UNKNOWN_HEADER_2, ++ sizeof(EXPECTED_UNKNOWN_HEADER_2))) { ++ netdev_dbg(dev->net, ++ "Received expected unknown frame header: %6phC. Package length: %i\n", ++ header_start, ++ skb->len - KALMIA_HEADER_LENGTH); ++ } ++ else { ++ netdev_err(dev->net, ++ "Received unknown frame header: %6phC. Package length: %i\n", ++ header_start, ++ skb->len - KALMIA_HEADER_LENGTH); ++ return 0; ++ } ++ } ++ else ++ netdev_dbg(dev->net, ++ "Received header: %6phC. Package length: %i\n", ++ header_start, skb->len - KALMIA_HEADER_LENGTH); ++ ++ /* subtract start header and end header */ ++ usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH); ++ ether_packet_length = get_unaligned_le16(&header_start[2]); ++ skb_pull(skb, KALMIA_HEADER_LENGTH); ++ ++ /* Some small packets misses end marker */ ++ if (usb_packet_length < ether_packet_length) { ++ ether_packet_length = usb_packet_length ++ + KALMIA_HEADER_LENGTH; ++ is_last = true; ++ } ++ else { ++ netdev_dbg(dev->net, "Correct package length #%i", i ++ + 1); ++ ++ is_last = (memcmp(skb->data + ether_packet_length, ++ HEADER_END_OF_USB_PACKET, ++ sizeof(HEADER_END_OF_USB_PACKET)) == 0); ++ if (!is_last) { ++ header_start = skb->data + ether_packet_length; ++ netdev_dbg(dev->net, ++ "End header: %6phC. Package length: %i\n", ++ header_start, ++ skb->len - KALMIA_HEADER_LENGTH); ++ } ++ } ++ ++ if (is_last) { ++ skb2 = skb; ++ } ++ else { ++ skb2 = skb_clone(skb, GFP_ATOMIC); ++ if (unlikely(!skb2)) ++ return 0; ++ } ++ ++ skb_trim(skb2, ether_packet_length); ++ ++ if (is_last) { ++ return 1; ++ } ++ else { ++ usbnet_skb_return(dev, skb2); ++ skb_pull(skb, ether_packet_length); ++ } ++ ++ i++; ++ } ++ while (skb->len); ++ ++ return 1; ++} ++ ++static const struct driver_info kalmia_info = { ++ .description = "Samsung Kalmia LTE USB dongle", ++ .flags = FLAG_WWAN, ++ .bind = kalmia_bind, ++ .rx_fixup = kalmia_rx_fixup, ++ .tx_fixup = kalmia_tx_fixup ++}; ++ ++/*-------------------------------------------------------------------------*/ ++ ++static const struct usb_device_id products[] = { ++ /* The unswitched USB ID, to get the module auto loaded: */ ++ { USB_DEVICE(0x04e8, 0x689a) }, ++ /* The stick swithed into modem (by e.g. usb_modeswitch): */ ++ { USB_DEVICE(0x04e8, 0x6889), ++ .driver_info = (unsigned long) &kalmia_info, }, ++ { /* EMPTY == end of list */} }; ++MODULE_DEVICE_TABLE( usb, products); ++ ++static struct usb_driver kalmia_driver = { ++ .name = "kalmia", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(kalmia_driver); ++ ++MODULE_AUTHOR("Marius Bjoernstad Kotsbak marius@kotsbak.com"); ++MODULE_DESCRIPTION("Samsung Kalmia USB network driver"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/kaweth.c backports-3.18.1-1/drivers/net/usb/kaweth.c +--- backports-3.18.1-1.org/drivers/net/usb/kaweth.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/kaweth.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,1331 @@ ++/**************************************************************** ++ * ++ * kaweth.c - driver for KL5KUSB101 based USB->Ethernet ++ * ++ * (c) 2000 Interlan Communications ++ * (c) 2000 Stephane Alnet ++ * (C) 2001 Brad Hards ++ * (C) 2002 Oliver Neukum ++ * ++ * Original author: The Zapman zapman@interlan.net ++ * Inspired by, and much credit goes to Michael Rothwell ++ * rothwell@interlan.net for the test equipment, help, and patience ++ * Based off of (and with thanks to) Petko Manolov's pegaus.c driver. ++ * Also many thanks to Joel Silverman and Ed Surprenant at Kawasaki ++ * for providing the firmware and driver resources. ++ * ++ * 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 this program; if not, see http://www.gnu.org/licenses/. ++ * ++ ****************************************************************/ ++ ++/* TODO: ++ * Develop test procedures for USB net interfaces ++ * Run test procedures ++ * Fix bugs from previous two steps ++ * Snoop other OSs for any tricks we're not doing ++ * Reduce arbitrary timeouts ++ * Smart multicast support ++ * Temporary MAC change support ++ * Tunable SOFs parameter - ioctl()? ++ * Ethernet stats collection ++ * Code formatting improvements ++ */ ++ ++#include <linux/module.h> ++#include <linux/slab.h> ++#include <linux/string.h> ++#include <linux/delay.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/usb.h> ++#include <linux/types.h> ++#include <linux/ethtool.h> ++#include <linux/dma-mapping.h> ++#include <linux/wait.h> ++#include <linux/firmware.h> ++#include <asm/uaccess.h> ++#include <asm/byteorder.h> ++ ++#undef DEBUG ++ ++#define KAWETH_MTU 1514 ++#define KAWETH_BUF_SIZE 1664 ++#define KAWETH_TX_TIMEOUT (5 * HZ) ++#define KAWETH_SCRATCH_SIZE 32 ++#define KAWETH_FIRMWARE_BUF_SIZE 4096 ++#define KAWETH_CONTROL_TIMEOUT (30000) ++ ++#define KAWETH_STATUS_BROKEN 0x0000001 ++#define KAWETH_STATUS_CLOSING 0x0000002 ++#define KAWETH_STATUS_SUSPENDING 0x0000004 ++ ++#define KAWETH_STATUS_BLOCKED (KAWETH_STATUS_CLOSING | KAWETH_STATUS_SUSPENDING) ++ ++#define KAWETH_PACKET_FILTER_PROMISCUOUS 0x01 ++#define KAWETH_PACKET_FILTER_ALL_MULTICAST 0x02 ++#define KAWETH_PACKET_FILTER_DIRECTED 0x04 ++#define KAWETH_PACKET_FILTER_BROADCAST 0x08 ++#define KAWETH_PACKET_FILTER_MULTICAST 0x10 ++ ++/* Table 7 */ ++#define KAWETH_COMMAND_GET_ETHERNET_DESC 0x00 ++#define KAWETH_COMMAND_MULTICAST_FILTERS 0x01 ++#define KAWETH_COMMAND_SET_PACKET_FILTER 0x02 ++#define KAWETH_COMMAND_STATISTICS 0x03 ++#define KAWETH_COMMAND_SET_TEMP_MAC 0x06 ++#define KAWETH_COMMAND_GET_TEMP_MAC 0x07 ++#define KAWETH_COMMAND_SET_URB_SIZE 0x08 ++#define KAWETH_COMMAND_SET_SOFS_WAIT 0x09 ++#define KAWETH_COMMAND_SCAN 0xFF ++ ++#define KAWETH_SOFS_TO_WAIT 0x05 ++ ++#define INTBUFFERSIZE 4 ++ ++#define STATE_OFFSET 0 ++#define STATE_MASK 0x40 ++#define STATE_SHIFT 5 ++ ++#define IS_BLOCKED(s) (s & KAWETH_STATUS_BLOCKED) ++ ++ ++MODULE_AUTHOR("Michael Zappe zapman@interlan.net, Stephane Alnet stephane@u-picardie.fr, Brad Hards bhards@bigpond.net.au and Oliver Neukum oliver@neukum.org"); ++MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver"); ++MODULE_LICENSE("GPL"); ++MODULE_FIRMWARE("kaweth/new_code.bin"); ++MODULE_FIRMWARE("kaweth/new_code_fix.bin"); ++MODULE_FIRMWARE("kaweth/trigger_code.bin"); ++MODULE_FIRMWARE("kaweth/trigger_code_fix.bin"); ++ ++static const char driver_name[] = "kaweth"; ++ ++static int kaweth_probe( ++ struct usb_interface *intf, ++ const struct usb_device_id *id /* from id_table */ ++ ); ++static void kaweth_disconnect(struct usb_interface *intf); ++static int kaweth_internal_control_msg(struct usb_device *usb_dev, ++ unsigned int pipe, ++ struct usb_ctrlrequest *cmd, void *data, ++ int len, int timeout); ++static int kaweth_suspend(struct usb_interface *intf, pm_message_t message); ++static int kaweth_resume(struct usb_interface *intf); ++ ++/**************************************************************** ++ * usb_device_id ++ ****************************************************************/ ++static struct usb_device_id usb_klsi_table[] = { ++ { USB_DEVICE(0x03e8, 0x0008) }, /* AOX Endpoints USB Ethernet */ ++ { USB_DEVICE(0x04bb, 0x0901) }, /* I-O DATA USB-ET/T */ ++ { USB_DEVICE(0x0506, 0x03e8) }, /* 3Com 3C19250 */ ++ { USB_DEVICE(0x0506, 0x11f8) }, /* 3Com 3C460 */ ++ { USB_DEVICE(0x0557, 0x2002) }, /* ATEN USB Ethernet */ ++ { USB_DEVICE(0x0557, 0x4000) }, /* D-Link DSB-650C */ ++ { USB_DEVICE(0x0565, 0x0002) }, /* Peracom Enet */ ++ { USB_DEVICE(0x0565, 0x0003) }, /* Optus@Home UEP1045A */ ++ { USB_DEVICE(0x0565, 0x0005) }, /* Peracom Enet2 */ ++ { USB_DEVICE(0x05e9, 0x0008) }, /* KLSI KL5KUSB101B */ ++ { USB_DEVICE(0x05e9, 0x0009) }, /* KLSI KL5KUSB101B (Board change) */ ++ { USB_DEVICE(0x066b, 0x2202) }, /* Linksys USB10T */ ++ { USB_DEVICE(0x06e1, 0x0008) }, /* ADS USB-10BT */ ++ { USB_DEVICE(0x06e1, 0x0009) }, /* ADS USB-10BT */ ++ { USB_DEVICE(0x0707, 0x0100) }, /* SMC 2202USB */ ++ { USB_DEVICE(0x07aa, 0x0001) }, /* Correga K.K. */ ++ { USB_DEVICE(0x07b8, 0x4000) }, /* D-Link DU-E10 */ ++ { USB_DEVICE(0x07c9, 0xb010) }, /* Allied Telesyn AT-USB10 USB Ethernet Adapter */ ++ { USB_DEVICE(0x0846, 0x1001) }, /* NetGear EA-101 */ ++ { USB_DEVICE(0x0846, 0x1002) }, /* NetGear EA-101 */ ++ { USB_DEVICE(0x085a, 0x0008) }, /* PortGear Ethernet Adapter */ ++ { USB_DEVICE(0x085a, 0x0009) }, /* PortGear Ethernet Adapter */ ++ { USB_DEVICE(0x087d, 0x5704) }, /* Jaton USB Ethernet Device Adapter */ ++ { USB_DEVICE(0x0951, 0x0008) }, /* Kingston Technology USB Ethernet Adapter */ ++ { USB_DEVICE(0x095a, 0x3003) }, /* Portsmith Express Ethernet Adapter */ ++ { USB_DEVICE(0x10bd, 0x1427) }, /* ASANTE USB To Ethernet Adapter */ ++ { USB_DEVICE(0x1342, 0x0204) }, /* Mobility USB-Ethernet Adapter */ ++ { USB_DEVICE(0x13d2, 0x0400) }, /* Shark Pocket Adapter */ ++ { USB_DEVICE(0x1485, 0x0001) }, /* Silicom U2E */ ++ { USB_DEVICE(0x1485, 0x0002) }, /* Psion Dacom Gold Port Ethernet */ ++ { USB_DEVICE(0x1645, 0x0005) }, /* Entrega E45 */ ++ { USB_DEVICE(0x1645, 0x0008) }, /* Entrega USB Ethernet Adapter */ ++ { USB_DEVICE(0x1645, 0x8005) }, /* PortGear Ethernet Adapter */ ++ { USB_DEVICE(0x1668, 0x0323) }, /* Actiontec USB Ethernet */ ++ { USB_DEVICE(0x2001, 0x4000) }, /* D-link DSB-650C */ ++ {} /* Null terminator */ ++}; ++ ++MODULE_DEVICE_TABLE (usb, usb_klsi_table); ++ ++/**************************************************************** ++ * kaweth_driver ++ ****************************************************************/ ++static struct usb_driver kaweth_driver = { ++ .name = driver_name, ++ .probe = kaweth_probe, ++ .disconnect = kaweth_disconnect, ++ .suspend = kaweth_suspend, ++ .resume = kaweth_resume, ++ .id_table = usb_klsi_table, ++ .supports_autosuspend = 1, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++typedef __u8 eth_addr_t[6]; ++ ++/**************************************************************** ++ * usb_eth_dev ++ ****************************************************************/ ++struct usb_eth_dev { ++ char *name; ++ __u16 vendor; ++ __u16 device; ++ void *pdata; ++}; ++ ++/**************************************************************** ++ * kaweth_ethernet_configuration ++ * Refer Table 8 ++ ****************************************************************/ ++struct kaweth_ethernet_configuration ++{ ++ __u8 size; ++ __u8 reserved1; ++ __u8 reserved2; ++ eth_addr_t hw_addr; ++ __u32 statistics_mask; ++ __le16 segment_size; ++ __u16 max_multicast_filters; ++ __u8 reserved3; ++} __packed; ++ ++/**************************************************************** ++ * kaweth_device ++ ****************************************************************/ ++struct kaweth_device ++{ ++ spinlock_t device_lock; ++ ++ __u32 status; ++ int end; ++ int suspend_lowmem_rx; ++ int suspend_lowmem_ctrl; ++ int linkstate; ++ int opened; ++ struct delayed_work lowmem_work; ++ ++ struct usb_device *dev; ++ struct usb_interface *intf; ++ struct net_device *net; ++ wait_queue_head_t term_wait; ++ ++ struct urb *rx_urb; ++ struct urb *tx_urb; ++ struct urb *irq_urb; ++ ++ dma_addr_t intbufferhandle; ++ __u8 *intbuffer; ++ dma_addr_t rxbufferhandle; ++ __u8 *rx_buf; ++ ++ ++ struct sk_buff *tx_skb; ++ ++ __u8 *firmware_buf; ++ __u8 scratch[KAWETH_SCRATCH_SIZE]; ++ __u16 packet_filter_bitmap; ++ ++ struct kaweth_ethernet_configuration configuration; ++ ++ struct net_device_stats stats; ++}; ++ ++/**************************************************************** ++ * kaweth_control ++ ****************************************************************/ ++static int kaweth_control(struct kaweth_device *kaweth, ++ unsigned int pipe, ++ __u8 request, ++ __u8 requesttype, ++ __u16 value, ++ __u16 index, ++ void *data, ++ __u16 size, ++ int timeout) ++{ ++ struct usb_ctrlrequest *dr; ++ int retval; ++ ++ netdev_dbg(kaweth->net, "kaweth_control()\n"); ++ ++ if(in_interrupt()) { ++ netdev_dbg(kaweth->net, "in_interrupt()\n"); ++ return -EBUSY; ++ } ++ ++ dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); ++ if (!dr) ++ return -ENOMEM; ++ ++ dr->bRequestType = requesttype; ++ dr->bRequest = request; ++ dr->wValue = cpu_to_le16(value); ++ dr->wIndex = cpu_to_le16(index); ++ dr->wLength = cpu_to_le16(size); ++ ++ retval = kaweth_internal_control_msg(kaweth->dev, ++ pipe, ++ dr, ++ data, ++ size, ++ timeout); ++ ++ kfree(dr); ++ return retval; ++} ++ ++/**************************************************************** ++ * kaweth_read_configuration ++ ****************************************************************/ ++static int kaweth_read_configuration(struct kaweth_device *kaweth) ++{ ++ int retval; ++ ++ netdev_dbg(kaweth->net, "Reading kaweth configuration\n"); ++ ++ retval = kaweth_control(kaweth, ++ usb_rcvctrlpipe(kaweth->dev, 0), ++ KAWETH_COMMAND_GET_ETHERNET_DESC, ++ USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE, ++ 0, ++ 0, ++ (void *)&kaweth->configuration, ++ sizeof(kaweth->configuration), ++ KAWETH_CONTROL_TIMEOUT); ++ ++ return retval; ++} ++ ++/**************************************************************** ++ * kaweth_set_urb_size ++ ****************************************************************/ ++static int kaweth_set_urb_size(struct kaweth_device *kaweth, __u16 urb_size) ++{ ++ int retval; ++ ++ netdev_dbg(kaweth->net, "Setting URB size to %d\n", (unsigned)urb_size); ++ ++ retval = kaweth_control(kaweth, ++ usb_sndctrlpipe(kaweth->dev, 0), ++ KAWETH_COMMAND_SET_URB_SIZE, ++ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, ++ urb_size, ++ 0, ++ (void *)&kaweth->scratch, ++ 0, ++ KAWETH_CONTROL_TIMEOUT); ++ ++ return retval; ++} ++ ++/**************************************************************** ++ * kaweth_set_sofs_wait ++ ****************************************************************/ ++static int kaweth_set_sofs_wait(struct kaweth_device *kaweth, __u16 sofs_wait) ++{ ++ int retval; ++ ++ netdev_dbg(kaweth->net, "Set SOFS wait to %d\n", (unsigned)sofs_wait); ++ ++ retval = kaweth_control(kaweth, ++ usb_sndctrlpipe(kaweth->dev, 0), ++ KAWETH_COMMAND_SET_SOFS_WAIT, ++ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, ++ sofs_wait, ++ 0, ++ (void *)&kaweth->scratch, ++ 0, ++ KAWETH_CONTROL_TIMEOUT); ++ ++ return retval; ++} ++ ++/**************************************************************** ++ * kaweth_set_receive_filter ++ ****************************************************************/ ++static int kaweth_set_receive_filter(struct kaweth_device *kaweth, ++ __u16 receive_filter) ++{ ++ int retval; ++ ++ netdev_dbg(kaweth->net, "Set receive filter to %d\n", ++ (unsigned)receive_filter); ++ ++ retval = kaweth_control(kaweth, ++ usb_sndctrlpipe(kaweth->dev, 0), ++ KAWETH_COMMAND_SET_PACKET_FILTER, ++ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, ++ receive_filter, ++ 0, ++ (void *)&kaweth->scratch, ++ 0, ++ KAWETH_CONTROL_TIMEOUT); ++ ++ return retval; ++} ++ ++/**************************************************************** ++ * kaweth_download_firmware ++ ****************************************************************/ ++static int kaweth_download_firmware(struct kaweth_device *kaweth, ++ const char *fwname, ++ __u8 interrupt, ++ __u8 type) ++{ ++ const struct firmware *fw; ++ int data_len; ++ int ret; ++ ++ ret = request_firmware(&fw, fwname, &kaweth->dev->dev); ++ if (ret) { ++ dev_err(&kaweth->intf->dev, "Firmware request failed\n"); ++ return ret; ++ } ++ ++ if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) { ++ dev_err(&kaweth->intf->dev, "Firmware too big: %zu\n", ++ fw->size); ++ release_firmware(fw); ++ return -ENOSPC; ++ } ++ data_len = fw->size; ++ memcpy(kaweth->firmware_buf, fw->data, fw->size); ++ ++ release_firmware(fw); ++ ++ kaweth->firmware_buf[2] = (data_len & 0xFF) - 7; ++ kaweth->firmware_buf[3] = data_len >> 8; ++ kaweth->firmware_buf[4] = type; ++ kaweth->firmware_buf[5] = interrupt; ++ ++ netdev_dbg(kaweth->net, "High: %i, Low:%i\n", kaweth->firmware_buf[3], ++ kaweth->firmware_buf[2]); ++ ++ netdev_dbg(kaweth->net, ++ "Downloading firmware at %p to kaweth device at %p\n", ++ kaweth->firmware_buf, kaweth); ++ netdev_dbg(kaweth->net, "Firmware length: %d\n", data_len); ++ ++ return kaweth_control(kaweth, ++ usb_sndctrlpipe(kaweth->dev, 0), ++ KAWETH_COMMAND_SCAN, ++ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, ++ 0, ++ 0, ++ (void *)kaweth->firmware_buf, ++ data_len, ++ KAWETH_CONTROL_TIMEOUT); ++} ++ ++/**************************************************************** ++ * kaweth_trigger_firmware ++ ****************************************************************/ ++static int kaweth_trigger_firmware(struct kaweth_device *kaweth, ++ __u8 interrupt) ++{ ++ kaweth->firmware_buf[0] = 0xB6; ++ kaweth->firmware_buf[1] = 0xC3; ++ kaweth->firmware_buf[2] = 0x01; ++ kaweth->firmware_buf[3] = 0x00; ++ kaweth->firmware_buf[4] = 0x06; ++ kaweth->firmware_buf[5] = interrupt; ++ kaweth->firmware_buf[6] = 0x00; ++ kaweth->firmware_buf[7] = 0x00; ++ ++ netdev_dbg(kaweth->net, "Triggering firmware\n"); ++ ++ return kaweth_control(kaweth, ++ usb_sndctrlpipe(kaweth->dev, 0), ++ KAWETH_COMMAND_SCAN, ++ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, ++ 0, ++ 0, ++ (void *)kaweth->firmware_buf, ++ 8, ++ KAWETH_CONTROL_TIMEOUT); ++} ++ ++/**************************************************************** ++ * kaweth_reset ++ ****************************************************************/ ++static int kaweth_reset(struct kaweth_device *kaweth) ++{ ++ int result; ++ ++ netdev_dbg(kaweth->net, "kaweth_reset(%p)\n", kaweth); ++ result = usb_reset_configuration(kaweth->dev); ++ mdelay(10); ++ ++ netdev_dbg(kaweth->net, "kaweth_reset() returns %d.\n", result); ++ ++ return result; ++} ++ ++static void kaweth_usb_receive(struct urb *); ++static int kaweth_resubmit_rx_urb(struct kaweth_device *, gfp_t); ++ ++/**************************************************************** ++ int_callback ++*****************************************************************/ ++ ++static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, gfp_t mf) ++{ ++ int status; ++ ++ status = usb_submit_urb (kaweth->irq_urb, mf); ++ if (unlikely(status == -ENOMEM)) { ++ kaweth->suspend_lowmem_ctrl = 1; ++ schedule_delayed_work(&kaweth->lowmem_work, HZ/4); ++ } else { ++ kaweth->suspend_lowmem_ctrl = 0; ++ } ++ ++ if (status) ++ dev_err(&kaweth->intf->dev, ++ "can't resubmit intr, %s-%s, status %d\n", ++ kaweth->dev->bus->bus_name, ++ kaweth->dev->devpath, status); ++} ++ ++static void int_callback(struct urb *u) ++{ ++ struct kaweth_device *kaweth = u->context; ++ int act_state; ++ int status = u->status; ++ ++ switch (status) { ++ case 0: /* success */ ++ break; ++ case -ECONNRESET: /* unlink */ ++ case -ENOENT: ++ case -ESHUTDOWN: ++ return; ++ /* -EPIPE: should clear the halt */ ++ default: /* error */ ++ goto resubmit; ++ } ++ ++ /* we check the link state to report changes */ ++ if (kaweth->linkstate != (act_state = ( kaweth->intbuffer[STATE_OFFSET] | STATE_MASK) >> STATE_SHIFT)) { ++ if (act_state) ++ netif_carrier_on(kaweth->net); ++ else ++ netif_carrier_off(kaweth->net); ++ ++ kaweth->linkstate = act_state; ++ } ++resubmit: ++ kaweth_resubmit_int_urb(kaweth, GFP_ATOMIC); ++} ++ ++static void kaweth_resubmit_tl(struct work_struct *work) ++{ ++ struct kaweth_device *kaweth = ++ container_of(work, struct kaweth_device, lowmem_work.work); ++ ++ if (IS_BLOCKED(kaweth->status)) ++ return; ++ ++ if (kaweth->suspend_lowmem_rx) ++ kaweth_resubmit_rx_urb(kaweth, GFP_NOIO); ++ ++ if (kaweth->suspend_lowmem_ctrl) ++ kaweth_resubmit_int_urb(kaweth, GFP_NOIO); ++} ++ ++ ++/**************************************************************** ++ * kaweth_resubmit_rx_urb ++ ****************************************************************/ ++static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth, ++ gfp_t mem_flags) ++{ ++ int result; ++ ++ usb_fill_bulk_urb(kaweth->rx_urb, ++ kaweth->dev, ++ usb_rcvbulkpipe(kaweth->dev, 1), ++ kaweth->rx_buf, ++ KAWETH_BUF_SIZE, ++ kaweth_usb_receive, ++ kaweth); ++ kaweth->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ kaweth->rx_urb->transfer_dma = kaweth->rxbufferhandle; ++ ++ if((result = usb_submit_urb(kaweth->rx_urb, mem_flags))) { ++ if (result == -ENOMEM) { ++ kaweth->suspend_lowmem_rx = 1; ++ schedule_delayed_work(&kaweth->lowmem_work, HZ/4); ++ } ++ dev_err(&kaweth->intf->dev, "resubmitting rx_urb %d failed\n", ++ result); ++ } else { ++ kaweth->suspend_lowmem_rx = 0; ++ } ++ ++ return result; ++} ++ ++static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth); ++ ++/**************************************************************** ++ * kaweth_usb_receive ++ ****************************************************************/ ++static void kaweth_usb_receive(struct urb *urb) ++{ ++ struct device *dev = &urb->dev->dev; ++ struct kaweth_device *kaweth = urb->context; ++ struct net_device *net = kaweth->net; ++ int status = urb->status; ++ ++ int count = urb->actual_length; ++ int count2 = urb->transfer_buffer_length; ++ ++ __u16 pkt_len = le16_to_cpup((__le16 *)kaweth->rx_buf); ++ ++ struct sk_buff *skb; ++ ++ if (unlikely(status == -EPIPE)) { ++ kaweth->stats.rx_errors++; ++ kaweth->end = 1; ++ wake_up(&kaweth->term_wait); ++ dev_dbg(dev, "Status was -EPIPE.\n"); ++ return; ++ } ++ if (unlikely(status == -ECONNRESET || status == -ESHUTDOWN)) { ++ /* we are killed - set a flag and wake the disconnect handler */ ++ kaweth->end = 1; ++ wake_up(&kaweth->term_wait); ++ dev_dbg(dev, "Status was -ECONNRESET or -ESHUTDOWN.\n"); ++ return; ++ } ++ if (unlikely(status == -EPROTO || status == -ETIME || ++ status == -EILSEQ)) { ++ kaweth->stats.rx_errors++; ++ dev_dbg(dev, "Status was -EPROTO, -ETIME, or -EILSEQ.\n"); ++ return; ++ } ++ if (unlikely(status == -EOVERFLOW)) { ++ kaweth->stats.rx_errors++; ++ dev_dbg(dev, "Status was -EOVERFLOW.\n"); ++ } ++ spin_lock(&kaweth->device_lock); ++ if (IS_BLOCKED(kaweth->status)) { ++ spin_unlock(&kaweth->device_lock); ++ return; ++ } ++ spin_unlock(&kaweth->device_lock); ++ ++ if(status && status != -EREMOTEIO && count != 1) { ++ dev_err(&kaweth->intf->dev, ++ "%s RX status: %d count: %d packet_len: %d\n", ++ net->name, status, count, (int)pkt_len); ++ kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); ++ return; ++ } ++ ++ if(kaweth->net && (count > 2)) { ++ if(pkt_len > (count - 2)) { ++ dev_err(&kaweth->intf->dev, ++ "Packet length too long for USB frame (pkt_len: %x, count: %x)\n", ++ pkt_len, count); ++ dev_err(&kaweth->intf->dev, "Packet len & 2047: %x\n", ++ pkt_len & 2047); ++ dev_err(&kaweth->intf->dev, "Count 2: %x\n", count2); ++ kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); ++ return; ++ } ++ ++ if(!(skb = dev_alloc_skb(pkt_len+2))) { ++ kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); ++ return; ++ } ++ ++ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ ++ ++ skb_copy_to_linear_data(skb, kaweth->rx_buf + 2, pkt_len); ++ ++ skb_put(skb, pkt_len); ++ ++ skb->protocol = eth_type_trans(skb, net); ++ ++ netif_rx(skb); ++ ++ kaweth->stats.rx_packets++; ++ kaweth->stats.rx_bytes += pkt_len; ++ } ++ ++ kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); ++} ++ ++/**************************************************************** ++ * kaweth_open ++ ****************************************************************/ ++static int kaweth_open(struct net_device *net) ++{ ++ struct kaweth_device *kaweth = netdev_priv(net); ++ int res; ++ ++ netdev_dbg(kaweth->net, "Opening network device.\n"); ++ ++ res = usb_autopm_get_interface(kaweth->intf); ++ if (res) { ++ dev_err(&kaweth->intf->dev, "Interface cannot be resumed.\n"); ++ return -EIO; ++ } ++ res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL); ++ if (res) ++ goto err_out; ++ ++ usb_fill_int_urb( ++ kaweth->irq_urb, ++ kaweth->dev, ++ usb_rcvintpipe(kaweth->dev, 3), ++ kaweth->intbuffer, ++ INTBUFFERSIZE, ++ int_callback, ++ kaweth, ++ 250); /* overriding the descriptor */ ++ kaweth->irq_urb->transfer_dma = kaweth->intbufferhandle; ++ kaweth->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL); ++ if (res) { ++ usb_kill_urb(kaweth->rx_urb); ++ goto err_out; ++ } ++ kaweth->opened = 1; ++ ++ netif_start_queue(net); ++ ++ kaweth_async_set_rx_mode(kaweth); ++ return 0; ++ ++err_out: ++ usb_autopm_put_interface(kaweth->intf); ++ return -EIO; ++} ++ ++/**************************************************************** ++ * kaweth_kill_urbs ++ ****************************************************************/ ++static void kaweth_kill_urbs(struct kaweth_device *kaweth) ++{ ++ usb_kill_urb(kaweth->irq_urb); ++ usb_kill_urb(kaweth->rx_urb); ++ usb_kill_urb(kaweth->tx_urb); ++ ++ cancel_delayed_work_sync(&kaweth->lowmem_work); ++ ++ /* a scheduled work may have resubmitted, ++ we hit them again */ ++ usb_kill_urb(kaweth->irq_urb); ++ usb_kill_urb(kaweth->rx_urb); ++} ++ ++/**************************************************************** ++ * kaweth_close ++ ****************************************************************/ ++static int kaweth_close(struct net_device *net) ++{ ++ struct kaweth_device *kaweth = netdev_priv(net); ++ ++ netif_stop_queue(net); ++ kaweth->opened = 0; ++ ++ kaweth->status |= KAWETH_STATUS_CLOSING; ++ ++ kaweth_kill_urbs(kaweth); ++ ++ kaweth->status &= ~KAWETH_STATUS_CLOSING; ++ ++ usb_autopm_put_interface(kaweth->intf); ++ ++ return 0; ++} ++ ++static u32 kaweth_get_link(struct net_device *dev) ++{ ++ struct kaweth_device *kaweth = netdev_priv(dev); ++ ++ return kaweth->linkstate; ++} ++ ++static const struct ethtool_ops ops = { ++ .get_link = kaweth_get_link ++}; ++ ++/**************************************************************** ++ * kaweth_usb_transmit_complete ++ ****************************************************************/ ++static void kaweth_usb_transmit_complete(struct urb *urb) ++{ ++ struct kaweth_device *kaweth = urb->context; ++ struct sk_buff *skb = kaweth->tx_skb; ++ int status = urb->status; ++ ++ if (unlikely(status != 0)) ++ if (status != -ENOENT) ++ dev_dbg(&urb->dev->dev, "%s: TX status %d.\n", ++ kaweth->net->name, status); ++ ++ netif_wake_queue(kaweth->net); ++ dev_kfree_skb_irq(skb); ++} ++ ++/**************************************************************** ++ * kaweth_start_xmit ++ ****************************************************************/ ++static netdev_tx_t kaweth_start_xmit(struct sk_buff *skb, ++ struct net_device *net) ++{ ++ struct kaweth_device *kaweth = netdev_priv(net); ++ __le16 *private_header; ++ ++ int res; ++ ++ spin_lock_irq(&kaweth->device_lock); ++ ++ kaweth_async_set_rx_mode(kaweth); ++ netif_stop_queue(net); ++ if (IS_BLOCKED(kaweth->status)) { ++ goto skip; ++ } ++ ++ /* We now decide whether we can put our special header into the sk_buff */ ++ if (skb_cloned(skb) || skb_headroom(skb) < 2) { ++ /* no such luck - we make our own */ ++ struct sk_buff *copied_skb; ++ copied_skb = skb_copy_expand(skb, 2, 0, GFP_ATOMIC); ++ dev_kfree_skb_irq(skb); ++ skb = copied_skb; ++ if (!copied_skb) { ++ kaweth->stats.tx_errors++; ++ netif_start_queue(net); ++ spin_unlock_irq(&kaweth->device_lock); ++ return NETDEV_TX_OK; ++ } ++ } ++ ++ private_header = (__le16 *)__skb_push(skb, 2); ++ *private_header = cpu_to_le16(skb->len-2); ++ kaweth->tx_skb = skb; ++ ++ usb_fill_bulk_urb(kaweth->tx_urb, ++ kaweth->dev, ++ usb_sndbulkpipe(kaweth->dev, 2), ++ private_header, ++ skb->len, ++ kaweth_usb_transmit_complete, ++ kaweth); ++ kaweth->end = 0; ++ ++ if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC))) ++ { ++ dev_warn(&net->dev, "kaweth failed tx_urb %d\n", res); ++skip: ++ kaweth->stats.tx_errors++; ++ ++ netif_start_queue(net); ++ dev_kfree_skb_irq(skb); ++ } ++ else ++ { ++ kaweth->stats.tx_packets++; ++ kaweth->stats.tx_bytes += skb->len; ++ } ++ ++ spin_unlock_irq(&kaweth->device_lock); ++ ++ return NETDEV_TX_OK; ++} ++ ++/**************************************************************** ++ * kaweth_set_rx_mode ++ ****************************************************************/ ++static void kaweth_set_rx_mode(struct net_device *net) ++{ ++ struct kaweth_device *kaweth = netdev_priv(net); ++ ++ __u16 packet_filter_bitmap = KAWETH_PACKET_FILTER_DIRECTED | ++ KAWETH_PACKET_FILTER_BROADCAST | ++ KAWETH_PACKET_FILTER_MULTICAST; ++ ++ netdev_dbg(net, "Setting Rx mode to %d\n", packet_filter_bitmap); ++ ++ netif_stop_queue(net); ++ ++ if (net->flags & IFF_PROMISC) { ++ packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS; ++ } ++ else if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) { ++ packet_filter_bitmap |= KAWETH_PACKET_FILTER_ALL_MULTICAST; ++ } ++ ++ kaweth->packet_filter_bitmap = packet_filter_bitmap; ++ netif_wake_queue(net); ++} ++ ++/**************************************************************** ++ * kaweth_async_set_rx_mode ++ ****************************************************************/ ++static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth) ++{ ++ int result; ++ __u16 packet_filter_bitmap = kaweth->packet_filter_bitmap; ++ ++ kaweth->packet_filter_bitmap = 0; ++ if (packet_filter_bitmap == 0) ++ return; ++ ++ if (in_interrupt()) ++ return; ++ ++ result = kaweth_control(kaweth, ++ usb_sndctrlpipe(kaweth->dev, 0), ++ KAWETH_COMMAND_SET_PACKET_FILTER, ++ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, ++ packet_filter_bitmap, ++ 0, ++ (void *)&kaweth->scratch, ++ 0, ++ KAWETH_CONTROL_TIMEOUT); ++ ++ if(result < 0) { ++ dev_err(&kaweth->intf->dev, "Failed to set Rx mode: %d\n", ++ result); ++ } ++ else { ++ netdev_dbg(kaweth->net, "Set Rx mode to %d\n", ++ packet_filter_bitmap); ++ } ++} ++ ++/**************************************************************** ++ * kaweth_netdev_stats ++ ****************************************************************/ ++static struct net_device_stats *kaweth_netdev_stats(struct net_device *dev) ++{ ++ struct kaweth_device *kaweth = netdev_priv(dev); ++ return &kaweth->stats; ++} ++ ++/**************************************************************** ++ * kaweth_tx_timeout ++ ****************************************************************/ ++static void kaweth_tx_timeout(struct net_device *net) ++{ ++ struct kaweth_device *kaweth = netdev_priv(net); ++ ++ dev_warn(&net->dev, "%s: Tx timed out. Resetting.\n", net->name); ++ kaweth->stats.tx_errors++; ++ net->trans_start = jiffies; ++ ++ usb_unlink_urb(kaweth->tx_urb); ++} ++ ++/**************************************************************** ++ * kaweth_suspend ++ ****************************************************************/ ++static int kaweth_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct kaweth_device *kaweth = usb_get_intfdata(intf); ++ unsigned long flags; ++ ++ dev_dbg(&intf->dev, "Suspending device\n"); ++ spin_lock_irqsave(&kaweth->device_lock, flags); ++ kaweth->status |= KAWETH_STATUS_SUSPENDING; ++ spin_unlock_irqrestore(&kaweth->device_lock, flags); ++ ++ kaweth_kill_urbs(kaweth); ++ return 0; ++} ++ ++/**************************************************************** ++ * kaweth_resume ++ ****************************************************************/ ++static int kaweth_resume(struct usb_interface *intf) ++{ ++ struct kaweth_device *kaweth = usb_get_intfdata(intf); ++ unsigned long flags; ++ ++ dev_dbg(&intf->dev, "Resuming device\n"); ++ spin_lock_irqsave(&kaweth->device_lock, flags); ++ kaweth->status &= ~KAWETH_STATUS_SUSPENDING; ++ spin_unlock_irqrestore(&kaweth->device_lock, flags); ++ ++ if (!kaweth->opened) ++ return 0; ++ kaweth_resubmit_rx_urb(kaweth, GFP_NOIO); ++ kaweth_resubmit_int_urb(kaweth, GFP_NOIO); ++ ++ return 0; ++} ++ ++/**************************************************************** ++ * kaweth_probe ++ ****************************************************************/ ++ ++ ++static const struct net_device_ops kaweth_netdev_ops = { ++ .ndo_open = kaweth_open, ++ .ndo_stop = kaweth_close, ++ .ndo_start_xmit = kaweth_start_xmit, ++ .ndo_tx_timeout = kaweth_tx_timeout, ++ .ndo_set_rx_mode = kaweth_set_rx_mode, ++ .ndo_get_stats = kaweth_netdev_stats, ++ .ndo_change_mtu = eth_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++}; ++ ++static int kaweth_probe( ++ struct usb_interface *intf, ++ const struct usb_device_id *id /* from id_table */ ++ ) ++{ ++ struct device *dev = &intf->dev; ++ struct usb_device *udev = interface_to_usbdev(intf); ++ struct kaweth_device *kaweth; ++ struct net_device *netdev; ++ const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; ++ int result = 0; ++ ++ dev_dbg(dev, ++ "Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x\n", ++ udev->devnum, le16_to_cpu(udev->descriptor.idVendor), ++ le16_to_cpu(udev->descriptor.idProduct), ++ le16_to_cpu(udev->descriptor.bcdDevice)); ++ ++ dev_dbg(dev, "Device at %p\n", udev); ++ ++ dev_dbg(dev, "Descriptor length: %x type: %x\n", ++ (int)udev->descriptor.bLength, ++ (int)udev->descriptor.bDescriptorType); ++ ++ netdev = alloc_etherdev(sizeof(*kaweth)); ++ if (!netdev) ++ return -ENOMEM; ++ ++ kaweth = netdev_priv(netdev); ++ kaweth->dev = udev; ++ kaweth->net = netdev; ++ ++ spin_lock_init(&kaweth->device_lock); ++ init_waitqueue_head(&kaweth->term_wait); ++ ++ dev_dbg(dev, "Resetting.\n"); ++ ++ kaweth_reset(kaweth); ++ ++ /* ++ * If high byte of bcdDevice is nonzero, firmware is already ++ * downloaded. Don't try to do it again, or we'll hang the device. ++ */ ++ ++ if (le16_to_cpu(udev->descriptor.bcdDevice) >> 8) { ++ dev_info(dev, "Firmware present in device.\n"); ++ } else { ++ /* Download the firmware */ ++ dev_info(dev, "Downloading firmware...\n"); ++ kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL); ++ if ((result = kaweth_download_firmware(kaweth, ++ "kaweth/new_code.bin", ++ 100, ++ 2)) < 0) { ++ dev_err(dev, "Error downloading firmware (%d)\n", ++ result); ++ goto err_fw; ++ } ++ ++ if ((result = kaweth_download_firmware(kaweth, ++ "kaweth/new_code_fix.bin", ++ 100, ++ 3)) < 0) { ++ dev_err(dev, "Error downloading firmware fix (%d)\n", ++ result); ++ goto err_fw; ++ } ++ ++ if ((result = kaweth_download_firmware(kaweth, ++ "kaweth/trigger_code.bin", ++ 126, ++ 2)) < 0) { ++ dev_err(dev, "Error downloading trigger code (%d)\n", ++ result); ++ goto err_fw; ++ ++ } ++ ++ if ((result = kaweth_download_firmware(kaweth, ++ "kaweth/trigger_code_fix.bin", ++ 126, ++ 3)) < 0) { ++ dev_err(dev, "Error downloading trigger code fix (%d)\n", result); ++ goto err_fw; ++ } ++ ++ ++ if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) { ++ dev_err(dev, "Error triggering firmware (%d)\n", result); ++ goto err_fw; ++ } ++ ++ /* Device will now disappear for a moment... */ ++ dev_info(dev, "Firmware loaded. I'll be back...\n"); ++err_fw: ++ free_page((unsigned long)kaweth->firmware_buf); ++ free_netdev(netdev); ++ return -EIO; ++ } ++ ++ result = kaweth_read_configuration(kaweth); ++ ++ if(result < 0) { ++ dev_err(dev, "Error reading configuration (%d), no net device created\n", result); ++ goto err_free_netdev; ++ } ++ ++ dev_info(dev, "Statistics collection: %x\n", kaweth->configuration.statistics_mask); ++ dev_info(dev, "Multicast filter limit: %x\n", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1)); ++ dev_info(dev, "MTU: %d\n", le16_to_cpu(kaweth->configuration.segment_size)); ++ dev_info(dev, "Read MAC address %pM\n", kaweth->configuration.hw_addr); ++ ++ if(!memcmp(&kaweth->configuration.hw_addr, ++ &bcast_addr, ++ sizeof(bcast_addr))) { ++ dev_err(dev, "Firmware not functioning properly, no net device created\n"); ++ goto err_free_netdev; ++ } ++ ++ if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) { ++ dev_dbg(dev, "Error setting URB size\n"); ++ goto err_free_netdev; ++ } ++ ++ if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) { ++ dev_err(dev, "Error setting SOFS wait\n"); ++ goto err_free_netdev; ++ } ++ ++ result = kaweth_set_receive_filter(kaweth, ++ KAWETH_PACKET_FILTER_DIRECTED | ++ KAWETH_PACKET_FILTER_BROADCAST | ++ KAWETH_PACKET_FILTER_MULTICAST); ++ ++ if(result < 0) { ++ dev_err(dev, "Error setting receive filter\n"); ++ goto err_free_netdev; ++ } ++ ++ dev_dbg(dev, "Initializing net device.\n"); ++ ++ kaweth->intf = intf; ++ ++ kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!kaweth->tx_urb) ++ goto err_free_netdev; ++ kaweth->rx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!kaweth->rx_urb) ++ goto err_only_tx; ++ kaweth->irq_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!kaweth->irq_urb) ++ goto err_tx_and_rx; ++ ++ kaweth->intbuffer = usb_alloc_coherent( kaweth->dev, ++ INTBUFFERSIZE, ++ GFP_KERNEL, ++ &kaweth->intbufferhandle); ++ if (!kaweth->intbuffer) ++ goto err_tx_and_rx_and_irq; ++ kaweth->rx_buf = usb_alloc_coherent( kaweth->dev, ++ KAWETH_BUF_SIZE, ++ GFP_KERNEL, ++ &kaweth->rxbufferhandle); ++ if (!kaweth->rx_buf) ++ goto err_all_but_rxbuf; ++ ++ memcpy(netdev->broadcast, &bcast_addr, sizeof(bcast_addr)); ++ memcpy(netdev->dev_addr, &kaweth->configuration.hw_addr, ++ sizeof(kaweth->configuration.hw_addr)); ++ ++ netdev->netdev_ops = &kaweth_netdev_ops; ++ netdev->watchdog_timeo = KAWETH_TX_TIMEOUT; ++ netdev->mtu = le16_to_cpu(kaweth->configuration.segment_size); ++ netdev->ethtool_ops = &ops; ++ ++ /* kaweth is zeroed as part of alloc_netdev */ ++ INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl); ++ usb_set_intfdata(intf, kaweth); ++ ++#if 0 ++// dma_supported() is deeply broken on almost all architectures ++ if (dma_supported (dev, 0xffffffffffffffffULL)) ++ kaweth->net->features |= NETIF_F_HIGHDMA; ++#endif ++ ++ SET_NETDEV_DEV(netdev, dev); ++ if (register_netdev(netdev) != 0) { ++ dev_err(dev, "Error registering netdev.\n"); ++ goto err_intfdata; ++ } ++ ++ dev_info(dev, "kaweth interface created at %s\n", ++ kaweth->net->name); ++ ++ dev_dbg(dev, "Kaweth probe returning.\n"); ++ ++ return 0; ++ ++err_intfdata: ++ usb_set_intfdata(intf, NULL); ++ usb_free_coherent(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle); ++err_all_but_rxbuf: ++ usb_free_coherent(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle); ++err_tx_and_rx_and_irq: ++ usb_free_urb(kaweth->irq_urb); ++err_tx_and_rx: ++ usb_free_urb(kaweth->rx_urb); ++err_only_tx: ++ usb_free_urb(kaweth->tx_urb); ++err_free_netdev: ++ free_netdev(netdev); ++ ++ return -EIO; ++} ++ ++/**************************************************************** ++ * kaweth_disconnect ++ ****************************************************************/ ++static void kaweth_disconnect(struct usb_interface *intf) ++{ ++ struct kaweth_device *kaweth = usb_get_intfdata(intf); ++ struct net_device *netdev; ++ ++ dev_info(&intf->dev, "Unregistering\n"); ++ ++ usb_set_intfdata(intf, NULL); ++ if (!kaweth) { ++ dev_warn(&intf->dev, "unregistering non-existent device\n"); ++ return; ++ } ++ netdev = kaweth->net; ++ ++ netdev_dbg(kaweth->net, "Unregistering net device\n"); ++ unregister_netdev(netdev); ++ ++ usb_free_urb(kaweth->rx_urb); ++ usb_free_urb(kaweth->tx_urb); ++ usb_free_urb(kaweth->irq_urb); ++ ++ usb_free_coherent(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle); ++ usb_free_coherent(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle); ++ ++ free_netdev(netdev); ++} ++ ++ ++// FIXME this completion stuff is a modified clone of ++// an OLD version of some stuff in usb.c ... ++struct usb_api_data { ++ wait_queue_head_t wqh; ++ int done; ++}; ++ ++/*-------------------------------------------------------------------* ++ * completion handler for compatibility wrappers (sync control/bulk) * ++ *-------------------------------------------------------------------*/ ++static void usb_api_blocking_completion(struct urb *urb) ++{ ++ struct usb_api_data *awd = (struct usb_api_data *)urb->context; ++ ++ awd->done=1; ++ wake_up(&awd->wqh); ++} ++ ++/*-------------------------------------------------------------------* ++ * COMPATIBILITY STUFF * ++ *-------------------------------------------------------------------*/ ++ ++// Starts urb and waits for completion or timeout ++static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length) ++{ ++ struct usb_api_data awd; ++ int status; ++ ++ init_waitqueue_head(&awd.wqh); ++ awd.done = 0; ++ ++ urb->context = &awd; ++ status = usb_submit_urb(urb, GFP_NOIO); ++ if (status) { ++ // something went wrong ++ usb_free_urb(urb); ++ return status; ++ } ++ ++ if (!wait_event_timeout(awd.wqh, awd.done, timeout)) { ++ // timeout ++ dev_warn(&urb->dev->dev, "usb_control/bulk_msg: timeout\n"); ++ usb_kill_urb(urb); // remove urb safely ++ status = -ETIMEDOUT; ++ } ++ else { ++ status = urb->status; ++ } ++ ++ if (actual_length) { ++ *actual_length = urb->actual_length; ++ } ++ ++ usb_free_urb(urb); ++ return status; ++} ++ ++/*-------------------------------------------------------------------*/ ++// returns status (negative) or length (positive) ++static int kaweth_internal_control_msg(struct usb_device *usb_dev, ++ unsigned int pipe, ++ struct usb_ctrlrequest *cmd, void *data, ++ int len, int timeout) ++{ ++ struct urb *urb; ++ int retv; ++ int length = 0; /* shut up GCC */ ++ ++ urb = usb_alloc_urb(0, GFP_ATOMIC); ++ if (!urb) ++ return -ENOMEM; ++ ++ usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char*)cmd, data, ++ len, usb_api_blocking_completion, NULL); ++ ++ retv = usb_start_wait_urb(urb, timeout, &length); ++ if (retv < 0) { ++ return retv; ++ } ++ else { ++ return length; ++ } ++} ++ ++module_usb_driver(kaweth_driver); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/Kconfig backports-3.18.1-1/drivers/net/usb/Kconfig +--- backports-3.18.1-1.org/drivers/net/usb/Kconfig 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/Kconfig 2015-01-03 15:19:02.310281530 +0100 +@@ -13,7 +13,6 @@ + if USB_NET_DRIVERS + + config USB_CATC +- depends on n + tristate "USB CATC NetMate-based Ethernet device support" + depends on m + depends on CRC32 +@@ -34,7 +33,6 @@ + module will be called catc. + + config USB_KAWETH +- depends on n + tristate "USB KLSI KL5USB101-based ethernet device support" + depends on m + ---help--- +@@ -75,7 +73,6 @@ + module will be called kaweth. + + config USB_PEGASUS +- depends on n + tristate "USB Pegasus/Pegasus-II based ethernet device support" + depends on m + select BACKPORT_MII +@@ -92,7 +89,6 @@ + module will be called pegasus. + + config USB_RTL8150 +- depends on n + tristate "USB RTL8150 based ethernet device support" + depends on m + select BACKPORT_MII +@@ -105,7 +101,6 @@ + module will be called rtl8150. + + config USB_RTL8152 +- depends on n + tristate "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters" + depends on m + select BACKPORT_MII +@@ -153,7 +148,6 @@ + module will be called usbnet. + + config USB_NET_AX8817X +- depends on n + tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters" + depends on m + depends on USB_USBNET +@@ -183,7 +177,6 @@ + what other networking devices you have in use. + + config USB_NET_AX88179_178A +- depends on n + tristate "ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet" + depends on m + depends on USB_USBNET +@@ -232,7 +225,6 @@ + name is used instead. + + config USB_NET_CDC_EEM +- depends on n + tristate "CDC EEM support" + depends on m + depends on USB_USBNET +@@ -268,7 +260,6 @@ + * Ericsson F5521gw Mobile Broadband Module + + config USB_NET_HUAWEI_CDC_NCM +- depends on n + tristate "Huawei NCM embedded AT channel support" + depends on m + depends on USB_USBNET +@@ -304,7 +295,6 @@ + module will be called cdc_mbim. + + config USB_NET_DM9601 +- depends on n + tristate "Davicom DM96xx based USB 10/100 ethernet devices" + depends on m + depends on USB_USBNET +@@ -314,7 +304,6 @@ + based USB 10/100 Ethernet adapters. + + config USB_NET_SR9700 +- depends on n + tristate "CoreChip-sz SR9700 based USB 1.1 10/100 ethernet devices" + depends on m + depends on USB_USBNET +@@ -324,7 +313,6 @@ + 10/100 Ethernet adapters. + + config USB_NET_SR9800 +- depends on n + tristate "CoreChip-sz SR9800 based USB 2.0 10/100 ethernet devices" + depends on m + depends on USB_USBNET +@@ -341,7 +329,6 @@ + module will be called sr9800. + + config USB_NET_SMSC75XX +- depends on n + tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" + depends on m + depends on USB_USBNET +@@ -353,7 +340,6 @@ + Gigabit Ethernet adapters. + + config USB_NET_SMSC95XX +- depends on n + tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices" + depends on m + depends on USB_USBNET +@@ -365,7 +351,6 @@ + 10/100 Ethernet adapters. + + config USB_NET_GL620A +- depends on n + tristate "GeneSys GL620USB-A based cables" + depends on m + depends on USB_USBNET +@@ -376,7 +361,6 @@ + Note that the half-duplex "GL620USB" is not supported. + + config USB_NET_NET1080 +- depends on n + tristate "NetChip 1080 based cables (Laplink, ...)" + depends on m + default y +@@ -387,7 +371,6 @@ + optionally with LEDs that indicate traffic + + config USB_NET_PLUSB +- depends on n + tristate "Prolific PL-2301/2302/25A1 based cables" + depends on m + # if the handshake/init/reset problems, from original 'plusb', +@@ -398,7 +381,6 @@ + with one of these chips. + + config USB_NET_MCS7830 +- depends on n + tristate "MosChip MCS7830 based Ethernet adapters" + depends on m + depends on USB_USBNET +@@ -424,7 +406,6 @@ + (and for) Microsoft; it isn't an "Open" ecosystem or market. + + config USB_NET_CDC_SUBSET +- depends on n + tristate "Simple USB Network Links (CDC Ethernet subset)" + depends on m + depends on USB_USBNET +@@ -496,7 +477,6 @@ + with one of these chips. + + config USB_NET_ZAURUS +- depends on n + tristate "Sharp Zaurus (stock ROMs) and compatible" + depends on m + depends on USB_USBNET +@@ -516,7 +496,6 @@ + some cases CDC MDLM) protocol, not "g_ether". + + config USB_NET_CX82310_ETH +- depends on n + tristate "Conexant CX82310 USB ethernet port" + depends on m + depends on USB_USBNET +@@ -526,7 +505,6 @@ + it will not work with ADSL modems (use cxacru driver instead). + + config USB_NET_KALMIA +- depends on n + tristate "Samsung Kalmia based LTE USB modem" + depends on m + depends on USB_USBNET +@@ -561,7 +539,6 @@ + module will be called qmi_wwan. + + config USB_HSO +- depends on n + tristate "Option USB High Speed Mobile Devices" + depends on m + depends on USB && RFKILL && TTY +@@ -574,7 +551,6 @@ + module will be called hso. + + config USB_NET_INT51X1 +- depends on n + tristate "Intellon PLC based usb adapter" + depends on m + depends on USB_USBNET +@@ -584,7 +560,6 @@ + INT51x1/INT5200 chip, like the "devolo dLan duo". + + config USB_CDC_PHONET +- depends on n + tristate "CDC Phonet support" + depends on m + depends on PHONET +@@ -594,7 +569,6 @@ + "PC suite" USB profile. + + config USB_IPHETH +- depends on n + tristate "Apple iPhone USB Ethernet driver" + depends on m + default n +@@ -618,11 +592,10 @@ + module will be called sierra_net. + + config USB_VL600 +- depends on n + tristate "LG VL600 modem dongle" + depends on m + depends on USB_NET_CDCETHER && TTY +- select USB_ACM ++# depends on USB_ACM + help + Select this if you want to use an LG Electronics 4G/LTE usb modem + called VL600. This driver only handles the ethernet +diff -Naur backports-3.18.1-1.org/drivers/net/usb/lg-vl600.c backports-3.18.1-1/drivers/net/usb/lg-vl600.c +--- backports-3.18.1-1.org/drivers/net/usb/lg-vl600.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/lg-vl600.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,353 @@ ++/* ++ * Ethernet interface part of the LG VL600 LTE modem (4G dongle) ++ * ++ * Copyright (C) 2011 Intel Corporation ++ * Author: Andrzej Zaborowski balrogg@gmail.com ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/usb/cdc.h> ++#include <linux/usb/usbnet.h> ++#include <linux/if_ether.h> ++#include <linux/if_arp.h> ++#include <linux/inetdevice.h> ++#include <linux/module.h> ++ ++/* ++ * The device has a CDC ACM port for modem control (it claims to be ++ * CDC ACM anyway) and a CDC Ethernet port for actual network data. ++ * It will however ignore data on both ports that is not encapsulated ++ * in a specific way, any data returned is also encapsulated the same ++ * way. The headers don't seem to follow any popular standard. ++ * ++ * This driver adds and strips these headers from the ethernet frames ++ * sent/received from the CDC Ethernet port. The proprietary header ++ * replaces the standard ethernet header in a packet so only actual ++ * ethernet frames are allowed. The headers allow some form of ++ * multiplexing by using non standard values of the .h_proto field. ++ * Windows/Mac drivers do send a couple of such frames to the device ++ * during initialisation, with protocol set to 0x0906 or 0x0b06 and (what ++ * seems to be) a flag in the .dummy_flags. This doesn't seem necessary ++ * for modem operation but can possibly be used for GPS or other funcitons. ++ */ ++ ++struct vl600_frame_hdr { ++ __le32 len; ++ __le32 serial; ++ __le32 pkt_cnt; ++ __le32 dummy_flags; ++ __le32 dummy; ++ __le32 magic; ++} __attribute__((packed)); ++ ++struct vl600_pkt_hdr { ++ __le32 dummy[2]; ++ __le32 len; ++ __be16 h_proto; ++} __attribute__((packed)); ++ ++struct vl600_state { ++ struct sk_buff *current_rx_buf; ++}; ++ ++static int vl600_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int ret; ++ struct vl600_state *s = kzalloc(sizeof(struct vl600_state), GFP_KERNEL); ++ ++ if (!s) ++ return -ENOMEM; ++ ++ ret = usbnet_cdc_bind(dev, intf); ++ if (ret) { ++ kfree(s); ++ return ret; ++ } ++ ++ dev->driver_priv = s; ++ ++ /* ARP packets don't go through, but they're also of no use. The ++ * subnet has only two hosts anyway: us and the gateway / DHCP ++ * server (probably simulated by modem firmware or network operator) ++ * whose address changes everytime we connect to the intarwebz and ++ * who doesn't bother answering ARP requests either. So hardware ++ * addresses have no meaning, the destination and the source of every ++ * packet depend only on whether it is on the IN or OUT endpoint. */ ++ dev->net->flags |= IFF_NOARP; ++ /* IPv6 NDP relies on multicast. Enable it by default. */ ++ dev->net->flags |= IFF_MULTICAST; ++ ++ return ret; ++} ++ ++static void vl600_unbind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ struct vl600_state *s = dev->driver_priv; ++ ++ if (s->current_rx_buf) ++ dev_kfree_skb(s->current_rx_buf); ++ ++ kfree(s); ++ ++ return usbnet_cdc_unbind(dev, intf); ++} ++ ++static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ struct vl600_frame_hdr *frame; ++ struct vl600_pkt_hdr *packet; ++ struct ethhdr *ethhdr; ++ int packet_len, count; ++ struct sk_buff *buf = skb; ++ struct sk_buff *clone; ++ struct vl600_state *s = dev->driver_priv; ++ ++ /* Frame lengths are generally 4B multiplies but every couple of ++ * hours there's an odd number of bytes sized yet correct frame, ++ * so don't require this. */ ++ ++ /* Allow a packet (or multiple packets batched together) to be ++ * split across many frames. We don't allow a new batch to ++ * begin in the same frame another one is ending however, and no ++ * leading or trailing pad bytes. */ ++ if (s->current_rx_buf) { ++ frame = (struct vl600_frame_hdr *) s->current_rx_buf->data; ++ if (skb->len + s->current_rx_buf->len > ++ le32_to_cpup(&frame->len)) { ++ netif_err(dev, ifup, dev->net, "Fragment too long\n"); ++ dev->net->stats.rx_length_errors++; ++ goto error; ++ } ++ ++ buf = s->current_rx_buf; ++ memcpy(skb_put(buf, skb->len), skb->data, skb->len); ++ } else if (skb->len < 4) { ++ netif_err(dev, ifup, dev->net, "Frame too short\n"); ++ dev->net->stats.rx_length_errors++; ++ goto error; ++ } ++ ++ frame = (struct vl600_frame_hdr *) buf->data; ++ /* Yes, check that frame->magic == 0x53544448 (or 0x44544d48), ++ * otherwise we may run out of memory w/a bad packet */ ++ if (ntohl(frame->magic) != 0x53544448 && ++ ntohl(frame->magic) != 0x44544d48) ++ goto error; ++ ++ if (buf->len < sizeof(*frame) || ++ buf->len != le32_to_cpup(&frame->len)) { ++ /* Save this fragment for later assembly */ ++ if (s->current_rx_buf) ++ return 0; ++ ++ s->current_rx_buf = skb_copy_expand(skb, 0, ++ le32_to_cpup(&frame->len), GFP_ATOMIC); ++ if (!s->current_rx_buf) { ++ netif_err(dev, ifup, dev->net, "Reserving %i bytes " ++ "for packet assembly failed.\n", ++ le32_to_cpup(&frame->len)); ++ dev->net->stats.rx_errors++; ++ } ++ ++ return 0; ++ } ++ ++ count = le32_to_cpup(&frame->pkt_cnt); ++ ++ skb_pull(buf, sizeof(*frame)); ++ ++ while (count--) { ++ if (buf->len < sizeof(*packet)) { ++ netif_err(dev, ifup, dev->net, "Packet too short\n"); ++ goto error; ++ } ++ ++ packet = (struct vl600_pkt_hdr *) buf->data; ++ packet_len = sizeof(*packet) + le32_to_cpup(&packet->len); ++ if (packet_len > buf->len) { ++ netif_err(dev, ifup, dev->net, ++ "Bad packet length stored in header\n"); ++ goto error; ++ } ++ ++ /* Packet header is same size as the ethernet header ++ * (sizeof(*packet) == sizeof(*ethhdr)), additionally ++ * the h_proto field is in the same place so we just leave it ++ * alone and fill in the remaining fields. ++ */ ++ ethhdr = (struct ethhdr *) skb->data; ++ if (be16_to_cpup(ðhdr->h_proto) == ETH_P_ARP && ++ buf->len > 0x26) { ++ /* Copy the addresses from packet contents */ ++ memcpy(ethhdr->h_source, ++ &buf->data[sizeof(*ethhdr) + 0x8], ++ ETH_ALEN); ++ memcpy(ethhdr->h_dest, ++ &buf->data[sizeof(*ethhdr) + 0x12], ++ ETH_ALEN); ++ } else { ++ memset(ethhdr->h_source, 0, ETH_ALEN); ++ memcpy(ethhdr->h_dest, dev->net->dev_addr, ETH_ALEN); ++ ++ /* Inbound IPv6 packets have an IPv4 ethertype (0x800) ++ * for some reason. Peek at the L3 header to check ++ * for IPv6 packets, and set the ethertype to IPv6 ++ * (0x86dd) so Linux can understand it. ++ */ ++ if ((buf->data[sizeof(*ethhdr)] & 0xf0) == 0x60) ++ ethhdr->h_proto = htons(ETH_P_IPV6); ++ } ++ ++ if (count) { ++ /* Not the last packet in this batch */ ++ clone = skb_clone(buf, GFP_ATOMIC); ++ if (!clone) ++ goto error; ++ ++ skb_trim(clone, packet_len); ++ usbnet_skb_return(dev, clone); ++ ++ skb_pull(buf, (packet_len + 3) & ~3); ++ } else { ++ skb_trim(buf, packet_len); ++ ++ if (s->current_rx_buf) { ++ usbnet_skb_return(dev, buf); ++ s->current_rx_buf = NULL; ++ return 0; ++ } ++ ++ return 1; ++ } ++ } ++ ++error: ++ if (s->current_rx_buf) { ++ dev_kfree_skb_any(s->current_rx_buf); ++ s->current_rx_buf = NULL; ++ } ++ dev->net->stats.rx_errors++; ++ return 0; ++} ++ ++static struct sk_buff *vl600_tx_fixup(struct usbnet *dev, ++ struct sk_buff *skb, gfp_t flags) ++{ ++ struct sk_buff *ret; ++ struct vl600_frame_hdr *frame; ++ struct vl600_pkt_hdr *packet; ++ static uint32_t serial = 1; ++ int orig_len = skb->len - sizeof(struct ethhdr); ++ int full_len = (skb->len + sizeof(struct vl600_frame_hdr) + 3) & ~3; ++ ++ frame = (struct vl600_frame_hdr *) skb->data; ++ if (skb->len > sizeof(*frame) && skb->len == le32_to_cpup(&frame->len)) ++ return skb; /* Already encapsulated? */ ++ ++ if (skb->len < sizeof(struct ethhdr)) ++ /* Drop, device can only deal with ethernet packets */ ++ return NULL; ++ ++ if (!skb_cloned(skb)) { ++ int headroom = skb_headroom(skb); ++ int tailroom = skb_tailroom(skb); ++ ++ if (tailroom >= full_len - skb->len - sizeof(*frame) && ++ headroom >= sizeof(*frame)) ++ /* There's enough head and tail room */ ++ goto encapsulate; ++ ++ if (headroom + tailroom + skb->len >= full_len) { ++ /* There's enough total room, just readjust */ ++ skb->data = memmove(skb->head + sizeof(*frame), ++ skb->data, skb->len); ++ skb_set_tail_pointer(skb, skb->len); ++ goto encapsulate; ++ } ++ } ++ ++ /* Alloc a new skb with the required size */ ++ ret = skb_copy_expand(skb, sizeof(struct vl600_frame_hdr), full_len - ++ skb->len - sizeof(struct vl600_frame_hdr), flags); ++ dev_kfree_skb_any(skb); ++ if (!ret) ++ return ret; ++ skb = ret; ++ ++encapsulate: ++ /* Packet header is same size as ethernet packet header ++ * (sizeof(*packet) == sizeof(struct ethhdr)), additionally the ++ * h_proto field is in the same place so we just leave it alone and ++ * overwrite the remaining fields. ++ */ ++ packet = (struct vl600_pkt_hdr *) skb->data; ++ /* The VL600 wants IPv6 packets to have an IPv4 ethertype ++ * Since this modem only supports IPv4 and IPv6, just set all ++ * frames to 0x0800 (ETH_P_IP) ++ */ ++ packet->h_proto = htons(ETH_P_IP); ++ memset(&packet->dummy, 0, sizeof(packet->dummy)); ++ packet->len = cpu_to_le32(orig_len); ++ ++ frame = (struct vl600_frame_hdr *) skb_push(skb, sizeof(*frame)); ++ memset(frame, 0, sizeof(*frame)); ++ frame->len = cpu_to_le32(full_len); ++ frame->serial = cpu_to_le32(serial++); ++ frame->pkt_cnt = cpu_to_le32(1); ++ ++ if (skb->len < full_len) /* Pad */ ++ skb_put(skb, full_len - skb->len); ++ ++ return skb; ++} ++ ++static const struct driver_info vl600_info = { ++ .description = "LG VL600 modem", ++ .flags = FLAG_RX_ASSEMBLE | FLAG_WWAN, ++ .bind = vl600_bind, ++ .unbind = vl600_unbind, ++ .status = usbnet_cdc_status, ++ .rx_fixup = vl600_rx_fixup, ++ .tx_fixup = vl600_tx_fixup, ++}; ++ ++static const struct usb_device_id products[] = { ++ { ++ USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), ++ .driver_info = (unsigned long) &vl600_info, ++ }, ++ {}, /* End */ ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver lg_vl600_driver = { ++ .name = "lg-vl600", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(lg_vl600_driver); ++ ++MODULE_AUTHOR("Anrzej Zaborowski"); ++MODULE_DESCRIPTION("LG-VL600 modem's ethernet link"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/Makefile backports-3.18.1-1/drivers/net/usb/Makefile +--- backports-3.18.1-1.org/drivers/net/usb/Makefile 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/Makefile 2015-01-03 13:49:51.269970813 +0100 +@@ -1,39 +1,35 @@ +-# +-# Makefile for USB Network drivers +-# +-# +-#obj-$(CPTCFG_USB_CATC) += catc.o +-#obj-$(CPTCFG_USB_KAWETH) += kaweth.o +-#obj-$(CPTCFG_USB_PEGASUS) += pegasus.o +-#obj-$(CPTCFG_USB_RTL8150) += rtl8150.o +-#obj-$(CPTCFG_USB_RTL8152) += r8152.o +-#obj-$(CPTCFG_USB_HSO) += hso.o +-#obj-$(CPTCFG_USB_NET_AX8817X) += asix.o +-#obj-$(CPTCFG_USB_NET_AX88179_178A) += ax88179_178a.o ++obj-$(CPTCFG_USB_CATC) += catc.o ++obj-$(CPTCFG_USB_KAWETH) += kaweth.o ++obj-$(CPTCFG_USB_PEGASUS) += pegasus.o ++obj-$(CPTCFG_USB_RTL8150) += rtl8150.o ++obj-$(CPTCFG_USB_RTL8152) += r8152.o ++obj-$(CPTCFG_USB_HSO) += hso.o ++obj-$(CPTCFG_USB_NET_AX8817X) += asix.o ++asix-y := asix_devices.o asix_common.o ax88172a.o ++obj-$(CPTCFG_USB_NET_AX88179_178A) += ax88179_178a.o + obj-$(CPTCFG_USB_NET_CDCETHER) += cdc_ether.o +-#obj-$(CPTCFG_USB_NET_CDC_EEM) += cdc_eem.o +-#obj-$(CPTCFG_USB_NET_DM9601) += dm9601.o +-#obj-$(CPTCFG_USB_NET_SR9700) += sr9700.o +-#obj-$(CPTCFG_USB_NET_SR9800) += sr9800.o +-#obj-$(CPTCFG_USB_NET_SMSC75XX) += smsc75xx.o +-#obj-$(CPTCFG_USB_NET_SMSC95XX) += smsc95xx.o +-#obj-$(CPTCFG_USB_NET_GL620A) += gl620a.o +-#obj-$(CPTCFG_USB_NET_NET1080) += net1080.o +-#obj-$(CPTCFG_USB_NET_PLUSB) += plusb.o ++obj-$(CPTCFG_USB_NET_CDC_EEM) += cdc_eem.o ++obj-$(CPTCFG_USB_NET_DM9601) += dm9601.o ++obj-$(CPTCFG_USB_NET_SR9700) += sr9700.o ++obj-$(CPTCFG_USB_NET_SR9800) += sr9800.o ++obj-$(CPTCFG_USB_NET_SMSC75XX) += smsc75xx.o ++obj-$(CPTCFG_USB_NET_SMSC95XX) += smsc95xx.o ++obj-$(CPTCFG_USB_NET_GL620A) += gl620a.o ++obj-$(CPTCFG_USB_NET_NET1080) += net1080.o ++obj-$(CPTCFG_USB_NET_PLUSB) += plusb.o + obj-$(CPTCFG_USB_NET_RNDIS_HOST) += rndis_host.o +-#obj-$(CPTCFG_USB_NET_CDC_SUBSET) += cdc_subset.o +-#obj-$(CPTCFG_USB_NET_ZAURUS) += zaurus.o +-#obj-$(CPTCFG_USB_NET_MCS7830) += mcs7830.o ++obj-$(CPTCFG_USB_NET_CDC_SUBSET) += cdc_subset.o ++obj-$(CPTCFG_USB_NET_ZAURUS) += zaurus.o ++obj-$(CPTCFG_USB_NET_MCS7830) += mcs7830.o + obj-$(CPTCFG_USB_USBNET) += usbnet.o +-#obj-$(CPTCFG_USB_NET_INT51X1) += int51x1.o +-#obj-$(CPTCFG_USB_CDC_PHONET) += cdc-phonet.o +-#obj-$(CPTCFG_USB_NET_KALMIA) += kalmia.o +-#obj-$(CPTCFG_USB_IPHETH) += ipheth.o ++obj-$(CPTCFG_USB_NET_INT51X1) += int51x1.o ++obj-$(CPTCFG_USB_CDC_PHONET) += cdc-phonet.o ++obj-$(CPTCFG_USB_NET_KALMIA) += kalmia.o ++obj-$(CPTCFG_USB_IPHETH) += ipheth.o + obj-$(CPTCFG_USB_SIERRA_NET) += sierra_net.o +-#obj-$(CPTCFG_USB_NET_CX82310_ETH) += cx82310_eth.o ++obj-$(CPTCFG_USB_NET_CX82310_ETH) += cx82310_eth.o + obj-$(CPTCFG_USB_NET_CDC_NCM) += cdc_ncm.o +-#obj-$(CPTCFG_USB_NET_HUAWEI_CDC_NCM) += huawei_cdc_ncm.o +-#obj-$(CPTCFG_USB_VL600) += lg-vl600.o ++obj-$(CPTCFG_USB_NET_HUAWEI_CDC_NCM) += huawei_cdc_ncm.o ++obj-$(CPTCFG_USB_VL600) += lg-vl600.o + obj-$(CPTCFG_USB_NET_QMI_WWAN) += qmi_wwan.o + obj-$(CPTCFG_USB_NET_CDC_MBIM) += cdc_mbim.o +- +diff -Naur backports-3.18.1-1.org/drivers/net/usb/mcs7830.c backports-3.18.1-1/drivers/net/usb/mcs7830.c +--- backports-3.18.1-1.org/drivers/net/usb/mcs7830.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/mcs7830.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,643 @@ ++/* ++ * MOSCHIP MCS7830 based (7730/7830/7832) USB 2.0 Ethernet Devices ++ * ++ * based on usbnet.c, asix.c and the vendor provided mcs7830 driver ++ * ++ * Copyright (C) 2010 Andreas Mohr andi@lisas.de ++ * Copyright (C) 2006 Arnd Bergmann arnd@arndb.de ++ * Copyright (C) 2003-2005 David Hollis dhollis@davehollis.com ++ * Copyright (C) 2005 Phil Chang pchang23@sbcglobal.net ++ * Copyright (c) 2002-2003 TiVo Inc. ++ * ++ * Definitions gathered from MOSCHIP, Data Sheet_7830DA.pdf (thanks!). ++ * ++ * 2010-12-19: add 7832 USB PID ("functionality same as MCS7830"), ++ * per active notification by manufacturer ++ * ++ * TODO: ++ * - support HIF_REG_CONFIG_SLEEPMODE/HIF_REG_CONFIG_TXENABLE (via autopm?) ++ * - implement ethtool_ops get_pauseparam/set_pauseparam ++ * via HIF_REG_PAUSE_THRESHOLD (>= revision C only!) ++ * - implement get_eeprom/[set_eeprom] ++ * - switch PHY on/off on ifup/ifdown (perhaps in usbnet.c, via MII) ++ * - mcs7830_get_regs() handling is weird: for rev 2 we return 32 regs, ++ * can access only ~ 24, remaining user buffer is uninitialized garbage ++ * - anything else? ++ * ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include <linux/crc32.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/mii.h> ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/slab.h> ++#include <linux/usb.h> ++#include <linux/usb/usbnet.h> ++ ++/* requests */ ++#define MCS7830_RD_BMREQ (USB_DIR_IN | USB_TYPE_VENDOR | \ ++ USB_RECIP_DEVICE) ++#define MCS7830_WR_BMREQ (USB_DIR_OUT | USB_TYPE_VENDOR | \ ++ USB_RECIP_DEVICE) ++#define MCS7830_RD_BREQ 0x0E ++#define MCS7830_WR_BREQ 0x0D ++ ++#define MCS7830_CTRL_TIMEOUT 1000 ++#define MCS7830_MAX_MCAST 64 ++ ++#define MCS7830_VENDOR_ID 0x9710 ++#define MCS7832_PRODUCT_ID 0x7832 ++#define MCS7830_PRODUCT_ID 0x7830 ++#define MCS7730_PRODUCT_ID 0x7730 ++ ++#define SITECOM_VENDOR_ID 0x0DF6 ++#define LN_030_PRODUCT_ID 0x0021 ++ ++#define MCS7830_MII_ADVERTISE (ADVERTISE_PAUSE_CAP | ADVERTISE_100FULL | \ ++ ADVERTISE_100HALF | ADVERTISE_10FULL | \ ++ ADVERTISE_10HALF | ADVERTISE_CSMA) ++ ++/* HIF_REG_XX corresponding index value */ ++enum { ++ HIF_REG_MULTICAST_HASH = 0x00, ++ HIF_REG_PACKET_GAP1 = 0x08, ++ HIF_REG_PACKET_GAP2 = 0x09, ++ HIF_REG_PHY_DATA = 0x0a, ++ HIF_REG_PHY_CMD1 = 0x0c, ++ HIF_REG_PHY_CMD1_READ = 0x40, ++ HIF_REG_PHY_CMD1_WRITE = 0x20, ++ HIF_REG_PHY_CMD1_PHYADDR = 0x01, ++ HIF_REG_PHY_CMD2 = 0x0d, ++ HIF_REG_PHY_CMD2_PEND_FLAG_BIT = 0x80, ++ HIF_REG_PHY_CMD2_READY_FLAG_BIT = 0x40, ++ HIF_REG_CONFIG = 0x0e, ++ /* hmm, spec sez: "R/W", "Except bit 3" (likely TXENABLE). */ ++ HIF_REG_CONFIG_CFG = 0x80, ++ HIF_REG_CONFIG_SPEED100 = 0x40, ++ HIF_REG_CONFIG_FULLDUPLEX_ENABLE = 0x20, ++ HIF_REG_CONFIG_RXENABLE = 0x10, ++ HIF_REG_CONFIG_TXENABLE = 0x08, ++ HIF_REG_CONFIG_SLEEPMODE = 0x04, ++ HIF_REG_CONFIG_ALLMULTICAST = 0x02, ++ HIF_REG_CONFIG_PROMISCUOUS = 0x01, ++ HIF_REG_ETHERNET_ADDR = 0x0f, ++ HIF_REG_FRAME_DROP_COUNTER = 0x15, /* 0..ff; reset: 0 */ ++ HIF_REG_PAUSE_THRESHOLD = 0x16, ++ HIF_REG_PAUSE_THRESHOLD_DEFAULT = 0, ++}; ++ ++/* Trailing status byte in Ethernet Rx frame */ ++enum { ++ MCS7830_RX_SHORT_FRAME = 0x01, /* < 64 bytes */ ++ MCS7830_RX_LENGTH_ERROR = 0x02, /* framelen != Ethernet length field */ ++ MCS7830_RX_ALIGNMENT_ERROR = 0x04, /* non-even number of nibbles */ ++ MCS7830_RX_CRC_ERROR = 0x08, ++ MCS7830_RX_LARGE_FRAME = 0x10, /* > 1518 bytes */ ++ MCS7830_RX_FRAME_CORRECT = 0x20, /* frame is correct */ ++ /* [7:6] reserved */ ++}; ++ ++struct mcs7830_data { ++ u8 multi_filter[8]; ++ u8 config; ++}; ++ ++static const char driver_name[] = "MOSCHIP usb-ethernet driver"; ++ ++static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data) ++{ ++ return usbnet_read_cmd(dev, MCS7830_RD_BREQ, MCS7830_RD_BMREQ, ++ 0x0000, index, data, size); ++} ++ ++static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, const void *data) ++{ ++ return usbnet_write_cmd(dev, MCS7830_WR_BREQ, MCS7830_WR_BMREQ, ++ 0x0000, index, data, size); ++} ++ ++static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void *data) ++{ ++ usbnet_write_cmd_async(dev, MCS7830_WR_BREQ, MCS7830_WR_BMREQ, ++ 0x0000, index, data, size); ++} ++ ++static int mcs7830_hif_get_mac_address(struct usbnet *dev, unsigned char *addr) ++{ ++ int ret = mcs7830_get_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, addr); ++ if (ret < 0) ++ return ret; ++ return 0; ++} ++ ++static int mcs7830_hif_set_mac_address(struct usbnet *dev, unsigned char *addr) ++{ ++ int ret = mcs7830_set_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, addr); ++ ++ if (ret < 0) ++ return ret; ++ return 0; ++} ++ ++static int mcs7830_set_mac_address(struct net_device *netdev, void *p) ++{ ++ int ret; ++ struct usbnet *dev = netdev_priv(netdev); ++ struct sockaddr *addr = p; ++ ++ if (netif_running(netdev)) ++ return -EBUSY; ++ ++ if (!is_valid_ether_addr(addr->sa_data)) ++ return -EADDRNOTAVAIL; ++ ++ ret = mcs7830_hif_set_mac_address(dev, addr->sa_data); ++ ++ if (ret < 0) ++ return ret; ++ ++ /* it worked --> adopt it on netdev side */ ++ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); ++ ++ return 0; ++} ++ ++static int mcs7830_read_phy(struct usbnet *dev, u8 index) ++{ ++ int ret; ++ int i; ++ __le16 val; ++ ++ u8 cmd[2] = { ++ HIF_REG_PHY_CMD1_READ | HIF_REG_PHY_CMD1_PHYADDR, ++ HIF_REG_PHY_CMD2_PEND_FLAG_BIT | index, ++ }; ++ ++ mutex_lock(&dev->phy_mutex); ++ /* write the MII command */ ++ ret = mcs7830_set_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); ++ if (ret < 0) ++ goto out; ++ ++ /* wait for the data to become valid, should be within < 1ms */ ++ for (i = 0; i < 10; i++) { ++ ret = mcs7830_get_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); ++ if ((ret < 0) || (cmd[1] & HIF_REG_PHY_CMD2_READY_FLAG_BIT)) ++ break; ++ ret = -EIO; ++ msleep(1); ++ } ++ if (ret < 0) ++ goto out; ++ ++ /* read actual register contents */ ++ ret = mcs7830_get_reg(dev, HIF_REG_PHY_DATA, 2, &val); ++ if (ret < 0) ++ goto out; ++ ret = le16_to_cpu(val); ++ dev_dbg(&dev->udev->dev, "read PHY reg %02x: %04x (%d tries)\n", ++ index, val, i); ++out: ++ mutex_unlock(&dev->phy_mutex); ++ return ret; ++} ++ ++static int mcs7830_write_phy(struct usbnet *dev, u8 index, u16 val) ++{ ++ int ret; ++ int i; ++ __le16 le_val; ++ ++ u8 cmd[2] = { ++ HIF_REG_PHY_CMD1_WRITE | HIF_REG_PHY_CMD1_PHYADDR, ++ HIF_REG_PHY_CMD2_PEND_FLAG_BIT | (index & 0x1F), ++ }; ++ ++ mutex_lock(&dev->phy_mutex); ++ ++ /* write the new register contents */ ++ le_val = cpu_to_le16(val); ++ ret = mcs7830_set_reg(dev, HIF_REG_PHY_DATA, 2, &le_val); ++ if (ret < 0) ++ goto out; ++ ++ /* write the MII command */ ++ ret = mcs7830_set_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); ++ if (ret < 0) ++ goto out; ++ ++ /* wait for the command to be accepted by the PHY */ ++ for (i = 0; i < 10; i++) { ++ ret = mcs7830_get_reg(dev, HIF_REG_PHY_CMD1, 2, cmd); ++ if ((ret < 0) || (cmd[1] & HIF_REG_PHY_CMD2_READY_FLAG_BIT)) ++ break; ++ ret = -EIO; ++ msleep(1); ++ } ++ if (ret < 0) ++ goto out; ++ ++ ret = 0; ++ dev_dbg(&dev->udev->dev, "write PHY reg %02x: %04x (%d tries)\n", ++ index, val, i); ++out: ++ mutex_unlock(&dev->phy_mutex); ++ return ret; ++} ++ ++/* ++ * This algorithm comes from the original mcs7830 version 1.4 driver, ++ * not sure if it is needed. ++ */ ++static int mcs7830_set_autoneg(struct usbnet *dev, int ptrUserPhyMode) ++{ ++ int ret; ++ /* Enable all media types */ ++ ret = mcs7830_write_phy(dev, MII_ADVERTISE, MCS7830_MII_ADVERTISE); ++ ++ /* First reset BMCR */ ++ if (!ret) ++ ret = mcs7830_write_phy(dev, MII_BMCR, 0x0000); ++ /* Enable Auto Neg */ ++ if (!ret) ++ ret = mcs7830_write_phy(dev, MII_BMCR, BMCR_ANENABLE); ++ /* Restart Auto Neg (Keep the Enable Auto Neg Bit Set) */ ++ if (!ret) ++ ret = mcs7830_write_phy(dev, MII_BMCR, ++ BMCR_ANENABLE | BMCR_ANRESTART ); ++ return ret; ++} ++ ++ ++/* ++ * if we can read register 22, the chip revision is C or higher ++ */ ++static int mcs7830_get_rev(struct usbnet *dev) ++{ ++ u8 dummy[2]; ++ int ret; ++ ret = mcs7830_get_reg(dev, HIF_REG_FRAME_DROP_COUNTER, 2, dummy); ++ if (ret > 0) ++ return 2; /* Rev C or later */ ++ return 1; /* earlier revision */ ++} ++ ++/* ++ * On rev. C we need to set the pause threshold ++ */ ++static void mcs7830_rev_C_fixup(struct usbnet *dev) ++{ ++ u8 pause_threshold = HIF_REG_PAUSE_THRESHOLD_DEFAULT; ++ int retry; ++ ++ for (retry = 0; retry < 2; retry++) { ++ if (mcs7830_get_rev(dev) == 2) { ++ dev_info(&dev->udev->dev, "applying rev.C fixup\n"); ++ mcs7830_set_reg(dev, HIF_REG_PAUSE_THRESHOLD, ++ 1, &pause_threshold); ++ } ++ msleep(1); ++ } ++} ++ ++static int mcs7830_mdio_read(struct net_device *netdev, int phy_id, ++ int location) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ return mcs7830_read_phy(dev, location); ++} ++ ++static void mcs7830_mdio_write(struct net_device *netdev, int phy_id, ++ int location, int val) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ mcs7830_write_phy(dev, location, val); ++} ++ ++static int mcs7830_ioctl(struct net_device *net, struct ifreq *rq, int cmd) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); ++} ++ ++static inline struct mcs7830_data *mcs7830_get_data(struct usbnet *dev) ++{ ++ return (struct mcs7830_data *)&dev->data; ++} ++ ++static void mcs7830_hif_update_multicast_hash(struct usbnet *dev) ++{ ++ struct mcs7830_data *data = mcs7830_get_data(dev); ++ mcs7830_set_reg_async(dev, HIF_REG_MULTICAST_HASH, ++ sizeof data->multi_filter, ++ data->multi_filter); ++} ++ ++static void mcs7830_hif_update_config(struct usbnet *dev) ++{ ++ /* implementation specific to data->config ++ (argument needs to be heap-based anyway - USB DMA!) */ ++ struct mcs7830_data *data = mcs7830_get_data(dev); ++ mcs7830_set_reg_async(dev, HIF_REG_CONFIG, 1, &data->config); ++} ++ ++static void mcs7830_data_set_multicast(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct mcs7830_data *data = mcs7830_get_data(dev); ++ ++ memset(data->multi_filter, 0, sizeof data->multi_filter); ++ ++ data->config = HIF_REG_CONFIG_TXENABLE; ++ ++ /* this should not be needed, but it doesn't work otherwise */ ++ data->config |= HIF_REG_CONFIG_ALLMULTICAST; ++ ++ if (net->flags & IFF_PROMISC) { ++ data->config |= HIF_REG_CONFIG_PROMISCUOUS; ++ } else if (net->flags & IFF_ALLMULTI || ++ netdev_mc_count(net) > MCS7830_MAX_MCAST) { ++ data->config |= HIF_REG_CONFIG_ALLMULTICAST; ++ } else if (netdev_mc_empty(net)) { ++ /* just broadcast and directed */ ++ } else { ++ /* We use the 20 byte dev->data ++ * for our 8 byte filter buffer ++ * to avoid allocating memory that ++ * is tricky to free later */ ++ struct netdev_hw_addr *ha; ++ u32 crc_bits; ++ ++ /* Build the multicast hash filter. */ ++ netdev_for_each_mc_addr(ha, net) { ++ crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; ++ data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7); ++ } ++ } ++} ++ ++static int mcs7830_apply_base_config(struct usbnet *dev) ++{ ++ int ret; ++ ++ /* re-configure known MAC (suspend case etc.) */ ++ ret = mcs7830_hif_set_mac_address(dev, dev->net->dev_addr); ++ if (ret) { ++ dev_info(&dev->udev->dev, "Cannot set MAC address\n"); ++ goto out; ++ } ++ ++ /* Set up PHY */ ++ ret = mcs7830_set_autoneg(dev, 0); ++ if (ret) { ++ dev_info(&dev->udev->dev, "Cannot set autoneg\n"); ++ goto out; ++ } ++ ++ mcs7830_hif_update_multicast_hash(dev); ++ mcs7830_hif_update_config(dev); ++ ++ mcs7830_rev_C_fixup(dev); ++ ret = 0; ++out: ++ return ret; ++} ++ ++/* credits go to asix_set_multicast */ ++static void mcs7830_set_multicast(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ mcs7830_data_set_multicast(net); ++ ++ mcs7830_hif_update_multicast_hash(dev); ++ mcs7830_hif_update_config(dev); ++} ++ ++static int mcs7830_get_regs_len(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ switch (mcs7830_get_rev(dev)) { ++ case 1: ++ return 21; ++ case 2: ++ return 32; ++ } ++ return 0; ++} ++ ++static void mcs7830_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *drvinfo) ++{ ++ usbnet_get_drvinfo(net, drvinfo); ++ drvinfo->regdump_len = mcs7830_get_regs_len(net); ++} ++ ++static void mcs7830_get_regs(struct net_device *net, struct ethtool_regs *regs, void *data) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ regs->version = mcs7830_get_rev(dev); ++ mcs7830_get_reg(dev, 0, regs->len, data); ++} ++ ++static const struct ethtool_ops mcs7830_ethtool_ops = { ++ .get_drvinfo = mcs7830_get_drvinfo, ++ .get_regs_len = mcs7830_get_regs_len, ++ .get_regs = mcs7830_get_regs, ++ ++ /* common usbnet calls */ ++ .get_link = usbnet_get_link, ++ .get_msglevel = usbnet_get_msglevel, ++ .set_msglevel = usbnet_set_msglevel, ++ .get_settings = usbnet_get_settings, ++ .set_settings = usbnet_set_settings, ++ .nway_reset = usbnet_nway_reset, ++}; ++ ++static const struct net_device_ops mcs7830_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = usbnet_change_mtu, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = mcs7830_ioctl, ++ .ndo_set_rx_mode = mcs7830_set_multicast, ++ .ndo_set_mac_address = mcs7830_set_mac_address, ++}; ++ ++static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev) ++{ ++ struct net_device *net = dev->net; ++ int ret; ++ int retry; ++ ++ /* Initial startup: Gather MAC address setting from EEPROM */ ++ ret = -EINVAL; ++ for (retry = 0; retry < 5 && ret; retry++) ++ ret = mcs7830_hif_get_mac_address(dev, net->dev_addr); ++ if (ret) { ++ dev_warn(&dev->udev->dev, "Cannot read MAC address\n"); ++ goto out; ++ } ++ ++ mcs7830_data_set_multicast(net); ++ ++ ret = mcs7830_apply_base_config(dev); ++ if (ret) ++ goto out; ++ ++ net->ethtool_ops = &mcs7830_ethtool_ops; ++ net->netdev_ops = &mcs7830_netdev_ops; ++ ++ /* reserve space for the status byte on rx */ ++ dev->rx_urb_size = ETH_FRAME_LEN + 1; ++ ++ dev->mii.mdio_read = mcs7830_mdio_read; ++ dev->mii.mdio_write = mcs7830_mdio_write; ++ dev->mii.dev = net; ++ dev->mii.phy_id_mask = 0x3f; ++ dev->mii.reg_num_mask = 0x1f; ++ dev->mii.phy_id = *((u8 *) net->dev_addr + 1); ++ ++ ret = usbnet_get_endpoints(dev, udev); ++out: ++ return ret; ++} ++ ++/* The chip always appends a status byte that we need to strip */ ++static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ u8 status; ++ ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) { ++ dev_err(&dev->udev->dev, "unexpected tiny rx frame\n"); ++ return 0; ++ } ++ ++ skb_trim(skb, skb->len - 1); ++ status = skb->data[skb->len]; ++ ++ if (status != MCS7830_RX_FRAME_CORRECT) { ++ dev_dbg(&dev->udev->dev, "rx fixup status %x\n", status); ++ ++ /* hmm, perhaps usbnet.c already sees a globally visible ++ frame error and increments rx_errors on its own already? */ ++ dev->net->stats.rx_errors++; ++ ++ if (status & (MCS7830_RX_SHORT_FRAME ++ |MCS7830_RX_LENGTH_ERROR ++ |MCS7830_RX_LARGE_FRAME)) ++ dev->net->stats.rx_length_errors++; ++ if (status & MCS7830_RX_ALIGNMENT_ERROR) ++ dev->net->stats.rx_frame_errors++; ++ if (status & MCS7830_RX_CRC_ERROR) ++ dev->net->stats.rx_crc_errors++; ++ } ++ ++ return skb->len > 0; ++} ++ ++static void mcs7830_status(struct usbnet *dev, struct urb *urb) ++{ ++ u8 *buf = urb->transfer_buffer; ++ bool link, link_changed; ++ ++ if (urb->actual_length < 16) ++ return; ++ ++ link = !(buf[1] == 0x20); ++ link_changed = netif_carrier_ok(dev->net) != link; ++ if (link_changed) { ++ usbnet_link_change(dev, link, 0); ++ netdev_dbg(dev->net, "Link Status is: %d\n", link); ++ } ++} ++ ++static const struct driver_info moschip_info = { ++ .description = "MOSCHIP 7830/7832/7730 usb-NET adapter", ++ .bind = mcs7830_bind, ++ .rx_fixup = mcs7830_rx_fixup, ++ .flags = FLAG_ETHER | FLAG_LINK_INTR, ++ .status = mcs7830_status, ++ .in = 1, ++ .out = 2, ++}; ++ ++static const struct driver_info sitecom_info = { ++ .description = "Sitecom LN-30 usb-NET adapter", ++ .bind = mcs7830_bind, ++ .rx_fixup = mcs7830_rx_fixup, ++ .flags = FLAG_ETHER | FLAG_LINK_INTR, ++ .status = mcs7830_status, ++ .in = 1, ++ .out = 2, ++}; ++ ++static const struct usb_device_id products[] = { ++ { ++ USB_DEVICE(MCS7830_VENDOR_ID, MCS7832_PRODUCT_ID), ++ .driver_info = (unsigned long) &moschip_info, ++ }, ++ { ++ USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID), ++ .driver_info = (unsigned long) &moschip_info, ++ }, ++ { ++ USB_DEVICE(MCS7830_VENDOR_ID, MCS7730_PRODUCT_ID), ++ .driver_info = (unsigned long) &moschip_info, ++ }, ++ { ++ USB_DEVICE(SITECOM_VENDOR_ID, LN_030_PRODUCT_ID), ++ .driver_info = (unsigned long) &sitecom_info, ++ }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static int mcs7830_reset_resume (struct usb_interface *intf) ++{ ++ /* YES, this function is successful enough that ethtool -d ++ does show same output pre-/post-suspend */ ++ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ ++ mcs7830_apply_base_config(dev); ++ ++ usbnet_resume(intf); ++ ++ return 0; ++} ++ ++static struct usb_driver mcs7830_driver = { ++ .name = driver_name, ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .reset_resume = mcs7830_reset_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(mcs7830_driver); ++ ++MODULE_DESCRIPTION("USB to network adapter MCS7830)"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/net1080.c backports-3.18.1-1/drivers/net/usb/net1080.c +--- backports-3.18.1-1.org/drivers/net/usb/net1080.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/net1080.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,544 @@ ++/* ++ * Net1080 based USB host-to-host cables ++ * Copyright (C) 2000-2005 by David Brownell ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++// #define DEBUG // error path messages, extra info ++// #define VERBOSE // more; success messages ++ ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/usb/usbnet.h> ++#include <linux/slab.h> ++ ++#include <asm/unaligned.h> ++ ++ ++/* ++ * Netchip 1080 driver ... http://www.netchip.com ++ * (Sept 2004: End-of-life announcement has been sent.) ++ * Used in (some) LapLink cables ++ */ ++ ++#define frame_errors data[1] ++ ++/* ++ * NetChip framing of ethernet packets, supporting additional error ++ * checks for links that may drop bulk packets from inside messages. ++ * Odd USB length == always short read for last usb packet. ++ * - nc_header ++ * - Ethernet header (14 bytes) ++ * - payload ++ * - (optional padding byte, if needed so length becomes odd) ++ * - nc_trailer ++ * ++ * This framing is to be avoided for non-NetChip devices. ++ */ ++ ++struct nc_header { // packed: ++ __le16 hdr_len; // sizeof nc_header (LE, all) ++ __le16 packet_len; // payload size (including ethhdr) ++ __le16 packet_id; // detects dropped packets ++#define MIN_HEADER 6 ++ ++ // all else is optional, and must start with: ++ // __le16 vendorId; // from usb-if ++ // __le16 productId; ++} __packed; ++ ++#define PAD_BYTE ((unsigned char)0xAC) ++ ++struct nc_trailer { ++ __le16 packet_id; ++} __packed; ++ ++// packets may use FLAG_FRAMING_NC and optional pad ++#define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \ ++ + sizeof (struct ethhdr) \ ++ + (mtu) \ ++ + 1 \ ++ + sizeof (struct nc_trailer)) ++ ++#define MIN_FRAMED FRAMED_SIZE(0) ++ ++/* packets _could_ be up to 64KB... */ ++#define NC_MAX_PACKET 32767 ++ ++ ++/* ++ * Zero means no timeout; else, how long a 64 byte bulk packet may be queued ++ * before the hardware drops it. If that's done, the driver will need to ++ * frame network packets to guard against the dropped USB packets. The win32 ++ * driver sets this for both sides of the link. ++ */ ++#define NC_READ_TTL_MS ((u8)255) // ms ++ ++/* ++ * We ignore most registers and EEPROM contents. ++ */ ++#define REG_USBCTL ((u8)0x04) ++#define REG_TTL ((u8)0x10) ++#define REG_STATUS ((u8)0x11) ++ ++/* ++ * Vendor specific requests to read/write data ++ */ ++#define REQUEST_REGISTER ((u8)0x10) ++#define REQUEST_EEPROM ((u8)0x11) ++ ++static int ++nc_vendor_read(struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr) ++{ ++ int status = usbnet_read_cmd(dev, req, ++ USB_DIR_IN | USB_TYPE_VENDOR | ++ USB_RECIP_DEVICE, ++ 0, regnum, retval_ptr, ++ sizeof *retval_ptr); ++ if (status > 0) ++ status = 0; ++ if (!status) ++ le16_to_cpus(retval_ptr); ++ return status; ++} ++ ++static inline int ++nc_register_read(struct usbnet *dev, u8 regnum, u16 *retval_ptr) ++{ ++ return nc_vendor_read(dev, REQUEST_REGISTER, regnum, retval_ptr); ++} ++ ++// no retval ... can become async, usable in_interrupt() ++static void ++nc_vendor_write(struct usbnet *dev, u8 req, u8 regnum, u16 value) ++{ ++ usbnet_write_cmd(dev, req, ++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ value, regnum, NULL, 0); ++} ++ ++static inline void ++nc_register_write(struct usbnet *dev, u8 regnum, u16 value) ++{ ++ nc_vendor_write(dev, REQUEST_REGISTER, regnum, value); ++} ++ ++ ++#if 0 ++static void nc_dump_registers(struct usbnet *dev) ++{ ++ u8 reg; ++ u16 *vp = kmalloc(sizeof (u16)); ++ ++ if (!vp) ++ return; ++ ++ netdev_dbg(dev->net, "registers:\n"); ++ for (reg = 0; reg < 0x20; reg++) { ++ int retval; ++ ++ // reading some registers is trouble ++ if (reg >= 0x08 && reg <= 0xf) ++ continue; ++ if (reg >= 0x12 && reg <= 0x1e) ++ continue; ++ ++ retval = nc_register_read(dev, reg, vp); ++ if (retval < 0) ++ netdev_dbg(dev->net, "reg [0x%x] ==> error %d\n", ++ reg, retval); ++ else ++ netdev_dbg(dev->net, "reg [0x%x] = 0x%x\n", reg, *vp); ++ } ++ kfree(vp); ++} ++#endif ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * Control register ++ */ ++ ++#define USBCTL_WRITABLE_MASK 0x1f0f ++// bits 15-13 reserved, r/o ++#define USBCTL_ENABLE_LANG (1 << 12) ++#define USBCTL_ENABLE_MFGR (1 << 11) ++#define USBCTL_ENABLE_PROD (1 << 10) ++#define USBCTL_ENABLE_SERIAL (1 << 9) ++#define USBCTL_ENABLE_DEFAULTS (1 << 8) ++// bits 7-4 reserved, r/o ++#define USBCTL_FLUSH_OTHER (1 << 3) ++#define USBCTL_FLUSH_THIS (1 << 2) ++#define USBCTL_DISCONN_OTHER (1 << 1) ++#define USBCTL_DISCONN_THIS (1 << 0) ++ ++static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl) ++{ ++ netif_dbg(dev, link, dev->net, ++ "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s; this%s%s; other%s%s; r/o 0x%x\n", ++ dev->udev->bus->bus_name, dev->udev->devpath, ++ usbctl, ++ (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "", ++ (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "", ++ (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "", ++ (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "", ++ (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "", ++ ++ (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "", ++ (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "", ++ ++ (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "", ++ (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "", ++ ++ usbctl & ~USBCTL_WRITABLE_MASK); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * Status register ++ */ ++ ++#define STATUS_PORT_A (1 << 15) ++ ++#define STATUS_CONN_OTHER (1 << 14) ++#define STATUS_SUSPEND_OTHER (1 << 13) ++#define STATUS_MAILBOX_OTHER (1 << 12) ++#define STATUS_PACKETS_OTHER(n) (((n) >> 8) & 0x03) ++ ++#define STATUS_CONN_THIS (1 << 6) ++#define STATUS_SUSPEND_THIS (1 << 5) ++#define STATUS_MAILBOX_THIS (1 << 4) ++#define STATUS_PACKETS_THIS(n) (((n) >> 0) & 0x03) ++ ++#define STATUS_UNSPEC_MASK 0x0c8c ++#define STATUS_NOISE_MASK ((u16)~(0x0303|STATUS_UNSPEC_MASK)) ++ ++ ++static inline void nc_dump_status(struct usbnet *dev, u16 status) ++{ ++ netif_dbg(dev, link, dev->net, ++ "net1080 %s-%s status 0x%x: this (%c) PKT=%d%s%s%s; other PKT=%d%s%s%s; unspec 0x%x\n", ++ dev->udev->bus->bus_name, dev->udev->devpath, ++ status, ++ ++ // XXX the packet counts don't seem right ++ // (1 at reset, not 0); maybe UNSPEC too ++ ++ (status & STATUS_PORT_A) ? 'A' : 'B', ++ STATUS_PACKETS_THIS(status), ++ (status & STATUS_CONN_THIS) ? " CON" : "", ++ (status & STATUS_SUSPEND_THIS) ? " SUS" : "", ++ (status & STATUS_MAILBOX_THIS) ? " MBOX" : "", ++ ++ STATUS_PACKETS_OTHER(status), ++ (status & STATUS_CONN_OTHER) ? " CON" : "", ++ (status & STATUS_SUSPEND_OTHER) ? " SUS" : "", ++ (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "", ++ ++ status & STATUS_UNSPEC_MASK); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * TTL register ++ */ ++ ++#define TTL_THIS(ttl) (0x00ff & ttl) ++#define TTL_OTHER(ttl) (0x00ff & (ttl >> 8)) ++#define MK_TTL(this,other) ((u16)(((other)<<8)|(0x00ff&(this)))) ++ ++static inline void nc_dump_ttl(struct usbnet *dev, u16 ttl) ++{ ++ netif_dbg(dev, link, dev->net, "net1080 %s-%s ttl 0x%x this = %d, other = %d\n", ++ dev->udev->bus->bus_name, dev->udev->devpath, ++ ttl, TTL_THIS(ttl), TTL_OTHER(ttl)); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int net1080_reset(struct usbnet *dev) ++{ ++ u16 usbctl, status, ttl; ++ u16 vp; ++ int retval; ++ ++ // nc_dump_registers(dev); ++ ++ if ((retval = nc_register_read(dev, REG_STATUS, &vp)) < 0) { ++ netdev_dbg(dev->net, "can't read %s-%s status: %d\n", ++ dev->udev->bus->bus_name, dev->udev->devpath, retval); ++ goto done; ++ } ++ status = vp; ++ nc_dump_status(dev, status); ++ ++ if ((retval = nc_register_read(dev, REG_USBCTL, &vp)) < 0) { ++ netdev_dbg(dev->net, "can't read USBCTL, %d\n", retval); ++ goto done; ++ } ++ usbctl = vp; ++ nc_dump_usbctl(dev, usbctl); ++ ++ nc_register_write(dev, REG_USBCTL, ++ USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER); ++ ++ if ((retval = nc_register_read(dev, REG_TTL, &vp)) < 0) { ++ netdev_dbg(dev->net, "can't read TTL, %d\n", retval); ++ goto done; ++ } ++ ttl = vp; ++ // nc_dump_ttl(dev, ttl); ++ ++ nc_register_write(dev, REG_TTL, ++ MK_TTL(NC_READ_TTL_MS, TTL_OTHER(ttl)) ); ++ netdev_dbg(dev->net, "assigned TTL, %d ms\n", NC_READ_TTL_MS); ++ ++ netif_info(dev, link, dev->net, "port %c, peer %sconnected\n", ++ (status & STATUS_PORT_A) ? 'A' : 'B', ++ (status & STATUS_CONN_OTHER) ? "" : "dis"); ++ retval = 0; ++ ++done: ++ return retval; ++} ++ ++static int net1080_check_connect(struct usbnet *dev) ++{ ++ int retval; ++ u16 status; ++ u16 vp; ++ ++ retval = nc_register_read(dev, REG_STATUS, &vp); ++ status = vp; ++ if (retval != 0) { ++ netdev_dbg(dev->net, "net1080_check_conn read - %d\n", retval); ++ return retval; ++ } ++ if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER) ++ return -ENOLINK; ++ return 0; ++} ++ ++static void nc_ensure_sync(struct usbnet *dev) ++{ ++ if (++dev->frame_errors <= 5) ++ return; ++ ++ if (usbnet_write_cmd_async(dev, REQUEST_REGISTER, ++ USB_DIR_OUT | USB_TYPE_VENDOR | ++ USB_RECIP_DEVICE, ++ USBCTL_FLUSH_THIS | ++ USBCTL_FLUSH_OTHER, ++ REG_USBCTL, NULL, 0)) ++ return; ++ ++ netif_dbg(dev, rx_err, dev->net, ++ "flush net1080; too many framing errors\n"); ++ dev->frame_errors = 0; ++} ++ ++static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ struct nc_header *header; ++ struct nc_trailer *trailer; ++ u16 hdr_len, packet_len; ++ ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ ++ if (!(skb->len & 0x01)) { ++ netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n", ++ skb->len, dev->net->hard_header_len, dev->hard_mtu, ++ dev->net->mtu); ++ dev->net->stats.rx_frame_errors++; ++ nc_ensure_sync(dev); ++ return 0; ++ } ++ ++ header = (struct nc_header *) skb->data; ++ hdr_len = le16_to_cpup(&header->hdr_len); ++ packet_len = le16_to_cpup(&header->packet_len); ++ if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) { ++ dev->net->stats.rx_frame_errors++; ++ netdev_dbg(dev->net, "packet too big, %d\n", packet_len); ++ nc_ensure_sync(dev); ++ return 0; ++ } else if (hdr_len < MIN_HEADER) { ++ dev->net->stats.rx_frame_errors++; ++ netdev_dbg(dev->net, "header too short, %d\n", hdr_len); ++ nc_ensure_sync(dev); ++ return 0; ++ } else if (hdr_len > MIN_HEADER) { ++ // out of band data for us? ++ netdev_dbg(dev->net, "header OOB, %d bytes\n", hdr_len - MIN_HEADER); ++ nc_ensure_sync(dev); ++ // switch (vendor/product ids) { ... } ++ } ++ skb_pull(skb, hdr_len); ++ ++ trailer = (struct nc_trailer *) ++ (skb->data + skb->len - sizeof *trailer); ++ skb_trim(skb, skb->len - sizeof *trailer); ++ ++ if ((packet_len & 0x01) == 0) { ++ if (skb->data [packet_len] != PAD_BYTE) { ++ dev->net->stats.rx_frame_errors++; ++ netdev_dbg(dev->net, "bad pad\n"); ++ return 0; ++ } ++ skb_trim(skb, skb->len - 1); ++ } ++ if (skb->len != packet_len) { ++ dev->net->stats.rx_frame_errors++; ++ netdev_dbg(dev->net, "bad packet len %d (expected %d)\n", ++ skb->len, packet_len); ++ nc_ensure_sync(dev); ++ return 0; ++ } ++ if (header->packet_id != get_unaligned(&trailer->packet_id)) { ++ dev->net->stats.rx_fifo_errors++; ++ netdev_dbg(dev->net, "(2+ dropped) rx packet_id mismatch 0x%x 0x%x\n", ++ le16_to_cpu(header->packet_id), ++ le16_to_cpu(trailer->packet_id)); ++ return 0; ++ } ++#if 0 ++ netdev_dbg(dev->net, "frame <rx h %d p %d id %d\n", header->hdr_len, ++ header->packet_len, header->packet_id); ++#endif ++ dev->frame_errors = 0; ++ return 1; ++} ++ ++static struct sk_buff * ++net1080_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) ++{ ++ struct sk_buff *skb2; ++ struct nc_header *header = NULL; ++ struct nc_trailer *trailer = NULL; ++ int padlen = sizeof (struct nc_trailer); ++ int len = skb->len; ++ ++ if (!((len + padlen + sizeof (struct nc_header)) & 0x01)) ++ padlen++; ++ if (!skb_cloned(skb)) { ++ int headroom = skb_headroom(skb); ++ int tailroom = skb_tailroom(skb); ++ ++ if (padlen <= tailroom && ++ sizeof(struct nc_header) <= headroom) ++ /* There's enough head and tail room */ ++ goto encapsulate; ++ ++ if ((sizeof (struct nc_header) + padlen) < ++ (headroom + tailroom)) { ++ /* There's enough total room, so just readjust */ ++ skb->data = memmove(skb->head ++ + sizeof (struct nc_header), ++ skb->data, skb->len); ++ skb_set_tail_pointer(skb, len); ++ goto encapsulate; ++ } ++ } ++ ++ /* Create a new skb to use with the correct size */ ++ skb2 = skb_copy_expand(skb, ++ sizeof (struct nc_header), ++ padlen, ++ flags); ++ dev_kfree_skb_any(skb); ++ if (!skb2) ++ return skb2; ++ skb = skb2; ++ ++encapsulate: ++ /* header first */ ++ header = (struct nc_header *) skb_push(skb, sizeof *header); ++ header->hdr_len = cpu_to_le16(sizeof (*header)); ++ header->packet_len = cpu_to_le16(len); ++ header->packet_id = cpu_to_le16((u16)dev->xid++); ++ ++ /* maybe pad; then trailer */ ++ if (!((skb->len + sizeof *trailer) & 0x01)) ++ *skb_put(skb, 1) = PAD_BYTE; ++ trailer = (struct nc_trailer *) skb_put(skb, sizeof *trailer); ++ put_unaligned(header->packet_id, &trailer->packet_id); ++#if 0 ++ netdev_dbg(dev->net, "frame >tx h %d p %d id %d\n", ++ header->hdr_len, header->packet_len, ++ header->packet_id); ++#endif ++ return skb; ++} ++ ++static int net1080_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ unsigned extra = sizeof (struct nc_header) ++ + 1 ++ + sizeof (struct nc_trailer); ++ ++ dev->net->hard_header_len += extra; ++ dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu; ++ dev->hard_mtu = NC_MAX_PACKET; ++ return usbnet_get_endpoints (dev, intf); ++} ++ ++static const struct driver_info net1080_info = { ++ .description = "NetChip TurboCONNECT", ++ .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_NC, ++ .bind = net1080_bind, ++ .reset = net1080_reset, ++ .check_connect = net1080_check_connect, ++ .rx_fixup = net1080_rx_fixup, ++ .tx_fixup = net1080_tx_fixup, ++}; ++ ++static const struct usb_device_id products [] = { ++{ ++ USB_DEVICE(0x0525, 0x1080), // NetChip ref design ++ .driver_info = (unsigned long) &net1080_info, ++}, { ++ USB_DEVICE(0x06D0, 0x0622), // Laplink Gold ++ .driver_info = (unsigned long) &net1080_info, ++}, ++ { }, // END ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver net1080_driver = { ++ .name = "net1080", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(net1080_driver); ++ ++MODULE_AUTHOR("David Brownell"); ++MODULE_DESCRIPTION("NetChip 1080 based USB Host-to-Host Links"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/pegasus.c backports-3.18.1-1/drivers/net/usb/pegasus.c +--- backports-3.18.1-1.org/drivers/net/usb/pegasus.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/pegasus.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,1335 @@ ++/* ++ * Copyright (c) 1999-2013 Petko Manolov (petkan@nucleusys.com) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * ChangeLog: ++ * .... Most of the time spent on reading sources & docs. ++ * v0.2.x First official release for the Linux kernel. ++ * v0.3.0 Beutified and structured, some bugs fixed. ++ * v0.3.x URBifying bulk requests and bugfixing. First relatively ++ * stable release. Still can touch device's registers only ++ * from top-halves. ++ * v0.4.0 Control messages remained unurbified are now URBs. ++ * Now we can touch the HW at any time. ++ * v0.4.9 Control urbs again use process context to wait. Argh... ++ * Some long standing bugs (enable_net_traffic) fixed. ++ * Also nasty trick about resubmiting control urb from ++ * interrupt context used. Please let me know how it ++ * behaves. Pegasus II support added since this version. ++ * TODO: suppressing HCD warnings spewage on disconnect. ++ * v0.4.13 Ethernet address is now set at probe(), not at open() ++ * time as this seems to break dhcpd. ++ * v0.5.0 branch to 2.5.x kernels ++ * v0.5.1 ethtool support added ++ * v0.5.5 rx socket buffers are in a pool and the their allocation ++ * is out of the interrupt routine. ++ * ... ++ * v0.9.3 simplified [get|set]_register(s), async update registers ++ * logic revisited, receive skb_pool removed. ++ */ ++ ++#include <linux/sched.h> ++#include <linux/slab.h> ++#include <linux/init.h> ++#include <linux/delay.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/module.h> ++#include <asm/byteorder.h> ++#include <asm/uaccess.h> ++#include "pegasus.h" ++ ++/* ++ * Version Information ++ */ ++#define DRIVER_VERSION "v0.9.3 (2013/04/25)" ++#define DRIVER_AUTHOR "Petko Manolov petkan@nucleusys.com" ++#define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" ++ ++static const char driver_name[] = "pegasus"; ++ ++#undef PEGASUS_WRITE_EEPROM ++#define BMSR_MEDIA (BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | \ ++ BMSR_100FULL | BMSR_ANEGCAPABLE) ++ ++static bool loopback; ++static bool mii_mode; ++static char *devid; ++ ++static struct usb_eth_dev usb_dev_id[] = { ++#define PEGASUS_DEV(pn, vid, pid, flags) \ ++ {.name = pn, .vendor = vid, .device = pid, .private = flags}, ++#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \ ++ PEGASUS_DEV(pn, vid, pid, flags) ++#include "pegasus.h" ++#undef PEGASUS_DEV ++#undef PEGASUS_DEV_CLASS ++ {NULL, 0, 0, 0}, ++ {NULL, 0, 0, 0} ++}; ++ ++static struct usb_device_id pegasus_ids[] = { ++#define PEGASUS_DEV(pn, vid, pid, flags) \ ++ {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, ++/* ++ * The Belkin F8T012xx1 bluetooth adaptor has the same vendor and product ++ * IDs as the Belkin F5D5050, so we need to teach the pegasus driver to ++ * ignore adaptors belonging to the "Wireless" class 0xE0. For this one ++ * case anyway, seeing as the pegasus is for "Wired" adaptors. ++ */ ++#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \ ++ {.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS), \ ++ .idVendor = vid, .idProduct = pid, .bDeviceClass = dclass}, ++#include "pegasus.h" ++#undef PEGASUS_DEV ++#undef PEGASUS_DEV_CLASS ++ {}, ++ {} ++}; ++ ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE("GPL"); ++module_param(loopback, bool, 0); ++module_param(mii_mode, bool, 0); ++module_param(devid, charp, 0); ++MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)"); ++MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0"); ++MODULE_PARM_DESC(devid, "The format is: 'DEV_name:VendorID:DeviceID:Flags'"); ++ ++/* use ethtool to change the level for any given device */ ++static int msg_level = -1; ++module_param(msg_level, int, 0); ++MODULE_PARM_DESC(msg_level, "Override default message level"); ++ ++MODULE_DEVICE_TABLE(usb, pegasus_ids); ++static const struct net_device_ops pegasus_netdev_ops; ++ ++/*****/ ++ ++static void async_ctrl_callback(struct urb *urb) ++{ ++ struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; ++ int status = urb->status; ++ ++ if (status < 0) ++ dev_dbg(&urb->dev->dev, "%s failed with %d", __func__, status); ++ kfree(req); ++ usb_free_urb(urb); ++} ++ ++static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) ++{ ++ int ret; ++ ++ ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0), ++ PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0, ++ indx, data, size, 1000); ++ if (ret < 0) ++ netif_dbg(pegasus, drv, pegasus->net, ++ "%s returned %d\n", __func__, ret); ++ return ret; ++} ++ ++static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) ++{ ++ int ret; ++ ++ ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), ++ PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0, ++ indx, data, size, 100); ++ if (ret < 0) ++ netif_dbg(pegasus, drv, pegasus->net, ++ "%s returned %d\n", __func__, ret); ++ return ret; ++} ++ ++static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data) ++{ ++ int ret; ++ ++ ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), ++ PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data, ++ indx, &data, 1, 1000); ++ if (ret < 0) ++ netif_dbg(pegasus, drv, pegasus->net, ++ "%s returned %d\n", __func__, ret); ++ return ret; ++} ++ ++static int update_eth_regs_async(pegasus_t *pegasus) ++{ ++ int ret = -ENOMEM; ++ struct urb *async_urb; ++ struct usb_ctrlrequest *req; ++ ++ req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); ++ if (req == NULL) ++ return ret; ++ ++ async_urb = usb_alloc_urb(0, GFP_ATOMIC); ++ if (async_urb == NULL) { ++ kfree(req); ++ return ret; ++ } ++ req->bRequestType = PEGASUS_REQT_WRITE; ++ req->bRequest = PEGASUS_REQ_SET_REGS; ++ req->wValue = cpu_to_le16(0); ++ req->wIndex = cpu_to_le16(EthCtrl0); ++ req->wLength = cpu_to_le16(3); ++ ++ usb_fill_control_urb(async_urb, pegasus->usb, ++ usb_sndctrlpipe(pegasus->usb, 0), (void *)req, ++ pegasus->eth_regs, 3, async_ctrl_callback, req); ++ ++ ret = usb_submit_urb(async_urb, GFP_ATOMIC); ++ if (ret) { ++ if (ret == -ENODEV) ++ netif_device_detach(pegasus->net); ++ netif_err(pegasus, drv, pegasus->net, ++ "%s returned %d\n", __func__, ret); ++ } ++ return ret; ++} ++ ++static int __mii_op(pegasus_t *p, __u8 phy, __u8 indx, __u16 *regd, __u8 cmd) ++{ ++ int i; ++ __u8 data[4] = { phy, 0, 0, indx }; ++ __le16 regdi; ++ int ret = -ETIMEDOUT; ++ ++ if (cmd & PHY_WRITE) { ++ __le16 *t = (__le16 *) & data[1]; ++ *t = cpu_to_le16(*regd); ++ } ++ set_register(p, PhyCtrl, 0); ++ set_registers(p, PhyAddr, sizeof(data), data); ++ set_register(p, PhyCtrl, (indx | cmd)); ++ for (i = 0; i < REG_TIMEOUT; i++) { ++ ret = get_registers(p, PhyCtrl, 1, data); ++ if (ret < 0) ++ goto fail; ++ if (data[0] & PHY_DONE) ++ break; ++ } ++ if (i >= REG_TIMEOUT) ++ goto fail; ++ if (cmd & PHY_READ) { ++ ret = get_registers(p, PhyData, 2, ®di); ++ *regd = le16_to_cpu(regdi); ++ return ret; ++ } ++ return 0; ++fail: ++ netif_dbg(p, drv, p->net, "%s failed\n", __func__); ++ return ret; ++} ++ ++/* Returns non-negative int on success, error on failure */ ++static int read_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd) ++{ ++ return __mii_op(pegasus, phy, indx, regd, PHY_READ); ++} ++ ++/* Returns zero on success, error on failure */ ++static int write_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd) ++{ ++ return __mii_op(pegasus, phy, indx, regd, PHY_WRITE); ++} ++ ++static int mdio_read(struct net_device *dev, int phy_id, int loc) ++{ ++ pegasus_t *pegasus = netdev_priv(dev); ++ u16 res; ++ ++ read_mii_word(pegasus, phy_id, loc, &res); ++ return (int)res; ++} ++ ++static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) ++{ ++ pegasus_t *pegasus = netdev_priv(dev); ++ u16 data = val; ++ ++ write_mii_word(pegasus, phy_id, loc, &data); ++} ++ ++static int read_eprom_word(pegasus_t *pegasus, __u8 index, __u16 *retdata) ++{ ++ int i; ++ __u8 tmp; ++ __le16 retdatai; ++ int ret; ++ ++ set_register(pegasus, EpromCtrl, 0); ++ set_register(pegasus, EpromOffset, index); ++ set_register(pegasus, EpromCtrl, EPROM_READ); ++ ++ for (i = 0; i < REG_TIMEOUT; i++) { ++ ret = get_registers(pegasus, EpromCtrl, 1, &tmp); ++ if (tmp & EPROM_DONE) ++ break; ++ if (ret == -ESHUTDOWN) ++ goto fail; ++ } ++ if (i >= REG_TIMEOUT) ++ goto fail; ++ ++ ret = get_registers(pegasus, EpromData, 2, &retdatai); ++ *retdata = le16_to_cpu(retdatai); ++ return ret; ++ ++fail: ++ netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); ++ return -ETIMEDOUT; ++} ++ ++#ifdef PEGASUS_WRITE_EEPROM ++static inline void enable_eprom_write(pegasus_t *pegasus) ++{ ++ __u8 tmp; ++ ++ get_registers(pegasus, EthCtrl2, 1, &tmp); ++ set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE); ++} ++ ++static inline void disable_eprom_write(pegasus_t *pegasus) ++{ ++ __u8 tmp; ++ ++ get_registers(pegasus, EthCtrl2, 1, &tmp); ++ set_register(pegasus, EpromCtrl, 0); ++ set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE); ++} ++ ++static int write_eprom_word(pegasus_t *pegasus, __u8 index, __u16 data) ++{ ++ int i; ++ __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE }; ++ int ret; ++ __le16 le_data = cpu_to_le16(data); ++ ++ set_registers(pegasus, EpromOffset, 4, d); ++ enable_eprom_write(pegasus); ++ set_register(pegasus, EpromOffset, index); ++ set_registers(pegasus, EpromData, 2, &le_data); ++ set_register(pegasus, EpromCtrl, EPROM_WRITE); ++ ++ for (i = 0; i < REG_TIMEOUT; i++) { ++ ret = get_registers(pegasus, EpromCtrl, 1, &tmp); ++ if (ret == -ESHUTDOWN) ++ goto fail; ++ if (tmp & EPROM_DONE) ++ break; ++ } ++ disable_eprom_write(pegasus); ++ if (i >= REG_TIMEOUT) ++ goto fail; ++ ++ return ret; ++ ++fail: ++ netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); ++ return -ETIMEDOUT; ++} ++#endif /* PEGASUS_WRITE_EEPROM */ ++ ++static inline void get_node_id(pegasus_t *pegasus, __u8 *id) ++{ ++ int i; ++ __u16 w16; ++ ++ for (i = 0; i < 3; i++) { ++ read_eprom_word(pegasus, i, &w16); ++ ((__le16 *) id)[i] = cpu_to_le16(w16); ++ } ++} ++ ++static void set_ethernet_addr(pegasus_t *pegasus) ++{ ++ __u8 node_id[6]; ++ ++ if (pegasus->features & PEGASUS_II) { ++ get_registers(pegasus, 0x10, sizeof(node_id), node_id); ++ } else { ++ get_node_id(pegasus, node_id); ++ set_registers(pegasus, EthID, sizeof(node_id), node_id); ++ } ++ memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id)); ++} ++ ++static inline int reset_mac(pegasus_t *pegasus) ++{ ++ __u8 data = 0x8; ++ int i; ++ ++ set_register(pegasus, EthCtrl1, data); ++ for (i = 0; i < REG_TIMEOUT; i++) { ++ get_registers(pegasus, EthCtrl1, 1, &data); ++ if (~data & 0x08) { ++ if (loopback) ++ break; ++ if (mii_mode && (pegasus->features & HAS_HOME_PNA)) ++ set_register(pegasus, Gpio1, 0x34); ++ else ++ set_register(pegasus, Gpio1, 0x26); ++ set_register(pegasus, Gpio0, pegasus->features); ++ set_register(pegasus, Gpio0, DEFAULT_GPIO_SET); ++ break; ++ } ++ } ++ if (i == REG_TIMEOUT) ++ return -ETIMEDOUT; ++ ++ if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || ++ usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { ++ set_register(pegasus, Gpio0, 0x24); ++ set_register(pegasus, Gpio0, 0x26); ++ } ++ if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { ++ __u16 auxmode; ++ read_mii_word(pegasus, 3, 0x1b, &auxmode); ++ auxmode |= 4; ++ write_mii_word(pegasus, 3, 0x1b, &auxmode); ++ } ++ ++ return 0; ++} ++ ++static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) ++{ ++ __u16 linkpart; ++ __u8 data[4]; ++ pegasus_t *pegasus = netdev_priv(dev); ++ int ret; ++ ++ read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart); ++ data[0] = 0xc9; ++ data[1] = 0; ++ if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL)) ++ data[1] |= 0x20; /* set full duplex */ ++ if (linkpart & (ADVERTISE_100FULL | ADVERTISE_100HALF)) ++ data[1] |= 0x10; /* set 100 Mbps */ ++ if (mii_mode) ++ data[1] = 0; ++ data[2] = loopback ? 0x09 : 0x01; ++ ++ memcpy(pegasus->eth_regs, data, sizeof(data)); ++ ret = set_registers(pegasus, EthCtrl0, 3, data); ++ ++ if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || ++ usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS2 || ++ usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { ++ u16 auxmode; ++ read_mii_word(pegasus, 0, 0x1b, &auxmode); ++ auxmode |= 4; ++ write_mii_word(pegasus, 0, 0x1b, &auxmode); ++ } ++ ++ return ret; ++} ++ ++static void read_bulk_callback(struct urb *urb) ++{ ++ pegasus_t *pegasus = urb->context; ++ struct net_device *net; ++ int rx_status, count = urb->actual_length; ++ int status = urb->status; ++ u8 *buf = urb->transfer_buffer; ++ __u16 pkt_len; ++ ++ if (!pegasus) ++ return; ++ ++ net = pegasus->net; ++ if (!netif_device_present(net) || !netif_running(net)) ++ return; ++ ++ switch (status) { ++ case 0: ++ break; ++ case -ETIME: ++ netif_dbg(pegasus, rx_err, net, "reset MAC\n"); ++ pegasus->flags &= ~PEGASUS_RX_BUSY; ++ break; ++ case -EPIPE: /* stall, or disconnect from TT */ ++ /* FIXME schedule work to clear the halt */ ++ netif_warn(pegasus, rx_err, net, "no rx stall recovery\n"); ++ return; ++ case -ENOENT: ++ case -ECONNRESET: ++ case -ESHUTDOWN: ++ netif_dbg(pegasus, ifdown, net, "rx unlink, %d\n", status); ++ return; ++ default: ++ netif_dbg(pegasus, rx_err, net, "RX status %d\n", status); ++ goto goon; ++ } ++ ++ if (!count || count < 4) ++ goto goon; ++ ++ rx_status = buf[count - 2]; ++ if (rx_status & 0x1e) { ++ netif_dbg(pegasus, rx_err, net, ++ "RX packet error %x\n", rx_status); ++ pegasus->stats.rx_errors++; ++ if (rx_status & 0x06) /* long or runt */ ++ pegasus->stats.rx_length_errors++; ++ if (rx_status & 0x08) ++ pegasus->stats.rx_crc_errors++; ++ if (rx_status & 0x10) /* extra bits */ ++ pegasus->stats.rx_frame_errors++; ++ goto goon; ++ } ++ if (pegasus->chip == 0x8513) { ++ pkt_len = le32_to_cpu(*(__le32 *)urb->transfer_buffer); ++ pkt_len &= 0x0fff; ++ pegasus->rx_skb->data += 2; ++ } else { ++ pkt_len = buf[count - 3] << 8; ++ pkt_len += buf[count - 4]; ++ pkt_len &= 0xfff; ++ pkt_len -= 8; ++ } ++ ++ /* ++ * If the packet is unreasonably long, quietly drop it rather than ++ * kernel panicing by calling skb_put. ++ */ ++ if (pkt_len > PEGASUS_MTU) ++ goto goon; ++ ++ /* ++ * at this point we are sure pegasus->rx_skb != NULL ++ * so we go ahead and pass up the packet. ++ */ ++ skb_put(pegasus->rx_skb, pkt_len); ++ pegasus->rx_skb->protocol = eth_type_trans(pegasus->rx_skb, net); ++ netif_rx(pegasus->rx_skb); ++ pegasus->stats.rx_packets++; ++ pegasus->stats.rx_bytes += pkt_len; ++ ++ if (pegasus->flags & PEGASUS_UNPLUG) ++ return; ++ ++ pegasus->rx_skb = __netdev_alloc_skb_ip_align(pegasus->net, PEGASUS_MTU, ++ GFP_ATOMIC); ++ ++ if (pegasus->rx_skb == NULL) ++ goto tl_sched; ++goon: ++ usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, ++ usb_rcvbulkpipe(pegasus->usb, 1), ++ pegasus->rx_skb->data, PEGASUS_MTU + 8, ++ read_bulk_callback, pegasus); ++ rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); ++ if (rx_status == -ENODEV) ++ netif_device_detach(pegasus->net); ++ else if (rx_status) { ++ pegasus->flags |= PEGASUS_RX_URB_FAIL; ++ goto tl_sched; ++ } else { ++ pegasus->flags &= ~PEGASUS_RX_URB_FAIL; ++ } ++ ++ return; ++ ++tl_sched: ++ tasklet_schedule(&pegasus->rx_tl); ++} ++ ++static void rx_fixup(unsigned long data) ++{ ++ pegasus_t *pegasus; ++ int status; ++ ++ pegasus = (pegasus_t *) data; ++ if (pegasus->flags & PEGASUS_UNPLUG) ++ return; ++ ++ if (pegasus->flags & PEGASUS_RX_URB_FAIL) ++ if (pegasus->rx_skb) ++ goto try_again; ++ if (pegasus->rx_skb == NULL) ++ pegasus->rx_skb = __netdev_alloc_skb_ip_align(pegasus->net, ++ PEGASUS_MTU, ++ GFP_ATOMIC); ++ if (pegasus->rx_skb == NULL) { ++ netif_warn(pegasus, rx_err, pegasus->net, "low on memory\n"); ++ tasklet_schedule(&pegasus->rx_tl); ++ return; ++ } ++ usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, ++ usb_rcvbulkpipe(pegasus->usb, 1), ++ pegasus->rx_skb->data, PEGASUS_MTU + 8, ++ read_bulk_callback, pegasus); ++try_again: ++ status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); ++ if (status == -ENODEV) ++ netif_device_detach(pegasus->net); ++ else if (status) { ++ pegasus->flags |= PEGASUS_RX_URB_FAIL; ++ tasklet_schedule(&pegasus->rx_tl); ++ } else { ++ pegasus->flags &= ~PEGASUS_RX_URB_FAIL; ++ } ++} ++ ++static void write_bulk_callback(struct urb *urb) ++{ ++ pegasus_t *pegasus = urb->context; ++ struct net_device *net; ++ int status = urb->status; ++ ++ if (!pegasus) ++ return; ++ ++ net = pegasus->net; ++ ++ if (!netif_device_present(net) || !netif_running(net)) ++ return; ++ ++ switch (status) { ++ case -EPIPE: ++ /* FIXME schedule_work() to clear the tx halt */ ++ netif_stop_queue(net); ++ netif_warn(pegasus, tx_err, net, "no tx stall recovery\n"); ++ return; ++ case -ENOENT: ++ case -ECONNRESET: ++ case -ESHUTDOWN: ++ netif_dbg(pegasus, ifdown, net, "tx unlink, %d\n", status); ++ return; ++ default: ++ netif_info(pegasus, tx_err, net, "TX status %d\n", status); ++ /* FALL THROUGH */ ++ case 0: ++ break; ++ } ++ ++ net->trans_start = jiffies; /* prevent tx timeout */ ++ netif_wake_queue(net); ++} ++ ++static void intr_callback(struct urb *urb) ++{ ++ pegasus_t *pegasus = urb->context; ++ struct net_device *net; ++ int res, status = urb->status; ++ ++ if (!pegasus) ++ return; ++ net = pegasus->net; ++ ++ switch (status) { ++ case 0: ++ break; ++ case -ECONNRESET: /* unlink */ ++ case -ENOENT: ++ case -ESHUTDOWN: ++ return; ++ default: ++ /* some Pegasus-I products report LOTS of data ++ * toggle errors... avoid log spamming ++ */ ++ netif_dbg(pegasus, timer, net, "intr status %d\n", status); ++ } ++ ++ if (urb->actual_length >= 6) { ++ u8 *d = urb->transfer_buffer; ++ ++ /* byte 0 == tx_status1, reg 2B */ ++ if (d[0] & (TX_UNDERRUN|EXCESSIVE_COL ++ |LATE_COL|JABBER_TIMEOUT)) { ++ pegasus->stats.tx_errors++; ++ if (d[0] & TX_UNDERRUN) ++ pegasus->stats.tx_fifo_errors++; ++ if (d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT)) ++ pegasus->stats.tx_aborted_errors++; ++ if (d[0] & LATE_COL) ++ pegasus->stats.tx_window_errors++; ++ } ++ ++ /* d[5].LINK_STATUS lies on some adapters. ++ * d[0].NO_CARRIER kicks in only with failed TX. ++ * ... so monitoring with MII may be safest. ++ */ ++ ++ /* bytes 3-4 == rx_lostpkt, reg 2E/2F */ ++ pegasus->stats.rx_missed_errors += ((d[3] & 0x7f) << 8) | d[4]; ++ } ++ ++ res = usb_submit_urb(urb, GFP_ATOMIC); ++ if (res == -ENODEV) ++ netif_device_detach(pegasus->net); ++ if (res) ++ netif_err(pegasus, timer, net, ++ "can't resubmit interrupt urb, %d\n", res); ++} ++ ++static void pegasus_tx_timeout(struct net_device *net) ++{ ++ pegasus_t *pegasus = netdev_priv(net); ++ netif_warn(pegasus, timer, net, "tx timeout\n"); ++ usb_unlink_urb(pegasus->tx_urb); ++ pegasus->stats.tx_errors++; ++} ++ ++static netdev_tx_t pegasus_start_xmit(struct sk_buff *skb, ++ struct net_device *net) ++{ ++ pegasus_t *pegasus = netdev_priv(net); ++ int count = ((skb->len + 2) & 0x3f) ? skb->len + 2 : skb->len + 3; ++ int res; ++ __u16 l16 = skb->len; ++ ++ netif_stop_queue(net); ++ ++ ((__le16 *) pegasus->tx_buff)[0] = cpu_to_le16(l16); ++ skb_copy_from_linear_data(skb, pegasus->tx_buff + 2, skb->len); ++ usb_fill_bulk_urb(pegasus->tx_urb, pegasus->usb, ++ usb_sndbulkpipe(pegasus->usb, 2), ++ pegasus->tx_buff, count, ++ write_bulk_callback, pegasus); ++ if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) { ++ netif_warn(pegasus, tx_err, net, "fail tx, %d\n", res); ++ switch (res) { ++ case -EPIPE: /* stall, or disconnect from TT */ ++ /* cleanup should already have been scheduled */ ++ break; ++ case -ENODEV: /* disconnect() upcoming */ ++ case -EPERM: ++ netif_device_detach(pegasus->net); ++ break; ++ default: ++ pegasus->stats.tx_errors++; ++ netif_start_queue(net); ++ } ++ } else { ++ pegasus->stats.tx_packets++; ++ pegasus->stats.tx_bytes += skb->len; ++ } ++ dev_kfree_skb(skb); ++ ++ return NETDEV_TX_OK; ++} ++ ++static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev) ++{ ++ return &((pegasus_t *) netdev_priv(dev))->stats; ++} ++ ++static inline void disable_net_traffic(pegasus_t *pegasus) ++{ ++ __le16 tmp = cpu_to_le16(0); ++ ++ set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp); ++} ++ ++static inline void get_interrupt_interval(pegasus_t *pegasus) ++{ ++ u16 data; ++ u8 interval; ++ ++ read_eprom_word(pegasus, 4, &data); ++ interval = data >> 8; ++ if (pegasus->usb->speed != USB_SPEED_HIGH) { ++ if (interval < 0x80) { ++ netif_info(pegasus, timer, pegasus->net, ++ "intr interval changed from %ums to %ums\n", ++ interval, 0x80); ++ interval = 0x80; ++ data = (data & 0x00FF) | ((u16)interval << 8); ++#ifdef PEGASUS_WRITE_EEPROM ++ write_eprom_word(pegasus, 4, data); ++#endif ++ } ++ } ++ pegasus->intr_interval = interval; ++} ++ ++static void set_carrier(struct net_device *net) ++{ ++ pegasus_t *pegasus = netdev_priv(net); ++ u16 tmp; ++ ++ if (read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp)) ++ return; ++ ++ if (tmp & BMSR_LSTATUS) ++ netif_carrier_on(net); ++ else ++ netif_carrier_off(net); ++} ++ ++static void free_all_urbs(pegasus_t *pegasus) ++{ ++ usb_free_urb(pegasus->intr_urb); ++ usb_free_urb(pegasus->tx_urb); ++ usb_free_urb(pegasus->rx_urb); ++} ++ ++static void unlink_all_urbs(pegasus_t *pegasus) ++{ ++ usb_kill_urb(pegasus->intr_urb); ++ usb_kill_urb(pegasus->tx_urb); ++ usb_kill_urb(pegasus->rx_urb); ++} ++ ++static int alloc_urbs(pegasus_t *pegasus) ++{ ++ int res = -ENOMEM; ++ ++ pegasus->rx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!pegasus->rx_urb) { ++ return res; ++ } ++ pegasus->tx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!pegasus->tx_urb) { ++ usb_free_urb(pegasus->rx_urb); ++ return res; ++ } ++ pegasus->intr_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!pegasus->intr_urb) { ++ usb_free_urb(pegasus->tx_urb); ++ usb_free_urb(pegasus->rx_urb); ++ return res; ++ } ++ ++ return 0; ++} ++ ++static int pegasus_open(struct net_device *net) ++{ ++ pegasus_t *pegasus = netdev_priv(net); ++ int res=-ENOMEM; ++ ++ if (pegasus->rx_skb == NULL) ++ pegasus->rx_skb = __netdev_alloc_skb_ip_align(pegasus->net, ++ PEGASUS_MTU, ++ GFP_KERNEL); ++ if (!pegasus->rx_skb) ++ goto exit; ++ ++ res = set_registers(pegasus, EthID, 6, net->dev_addr); ++ ++ usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, ++ usb_rcvbulkpipe(pegasus->usb, 1), ++ pegasus->rx_skb->data, PEGASUS_MTU + 8, ++ read_bulk_callback, pegasus); ++ if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { ++ if (res == -ENODEV) ++ netif_device_detach(pegasus->net); ++ netif_dbg(pegasus, ifup, net, "failed rx_urb, %d\n", res); ++ goto exit; ++ } ++ ++ usb_fill_int_urb(pegasus->intr_urb, pegasus->usb, ++ usb_rcvintpipe(pegasus->usb, 3), ++ pegasus->intr_buff, sizeof(pegasus->intr_buff), ++ intr_callback, pegasus, pegasus->intr_interval); ++ if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) { ++ if (res == -ENODEV) ++ netif_device_detach(pegasus->net); ++ netif_dbg(pegasus, ifup, net, "failed intr_urb, %d\n", res); ++ usb_kill_urb(pegasus->rx_urb); ++ goto exit; ++ } ++ res = enable_net_traffic(net, pegasus->usb); ++ if (res < 0) { ++ netif_dbg(pegasus, ifup, net, ++ "can't enable_net_traffic() - %d\n", res); ++ res = -EIO; ++ usb_kill_urb(pegasus->rx_urb); ++ usb_kill_urb(pegasus->intr_urb); ++ goto exit; ++ } ++ set_carrier(net); ++ netif_start_queue(net); ++ netif_dbg(pegasus, ifup, net, "open\n"); ++ res = 0; ++exit: ++ return res; ++} ++ ++static int pegasus_close(struct net_device *net) ++{ ++ pegasus_t *pegasus = netdev_priv(net); ++ ++ netif_stop_queue(net); ++ if (!(pegasus->flags & PEGASUS_UNPLUG)) ++ disable_net_traffic(pegasus); ++ tasklet_kill(&pegasus->rx_tl); ++ unlink_all_urbs(pegasus); ++ ++ return 0; ++} ++ ++static void pegasus_get_drvinfo(struct net_device *dev, ++ struct ethtool_drvinfo *info) ++{ ++ pegasus_t *pegasus = netdev_priv(dev); ++ ++ strlcpy(info->driver, driver_name, sizeof(info->driver)); ++ strlcpy(info->version, DRIVER_VERSION, sizeof(info->version)); ++ usb_make_path(pegasus->usb, info->bus_info, sizeof(info->bus_info)); ++} ++ ++/* also handles three patterns of some kind in hardware */ ++#define WOL_SUPPORTED (WAKE_MAGIC|WAKE_PHY) ++ ++static void ++pegasus_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ++{ ++ pegasus_t *pegasus = netdev_priv(dev); ++ ++ wol->supported = WAKE_MAGIC | WAKE_PHY; ++ wol->wolopts = pegasus->wolopts; ++} ++ ++static int ++pegasus_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ++{ ++ pegasus_t *pegasus = netdev_priv(dev); ++ u8 reg78 = 0x04; ++ int ret; ++ ++ if (wol->wolopts & ~WOL_SUPPORTED) ++ return -EINVAL; ++ ++ if (wol->wolopts & WAKE_MAGIC) ++ reg78 |= 0x80; ++ if (wol->wolopts & WAKE_PHY) ++ reg78 |= 0x40; ++ /* FIXME this 0x10 bit still needs to get set in the chip... */ ++ if (wol->wolopts) ++ pegasus->eth_regs[0] |= 0x10; ++ else ++ pegasus->eth_regs[0] &= ~0x10; ++ pegasus->wolopts = wol->wolopts; ++ ++ ret = set_register(pegasus, WakeupControl, reg78); ++ if (!ret) ++ ret = device_set_wakeup_enable(&pegasus->usb->dev, ++ wol->wolopts); ++ return ret; ++} ++ ++static inline void pegasus_reset_wol(struct net_device *dev) ++{ ++ struct ethtool_wolinfo wol; ++ ++ memset(&wol, 0, sizeof wol); ++ (void) pegasus_set_wol(dev, &wol); ++} ++ ++static int ++pegasus_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ++{ ++ pegasus_t *pegasus; ++ ++ pegasus = netdev_priv(dev); ++ mii_ethtool_gset(&pegasus->mii, ecmd); ++ return 0; ++} ++ ++static int ++pegasus_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ++{ ++ pegasus_t *pegasus = netdev_priv(dev); ++ return mii_ethtool_sset(&pegasus->mii, ecmd); ++} ++ ++static int pegasus_nway_reset(struct net_device *dev) ++{ ++ pegasus_t *pegasus = netdev_priv(dev); ++ return mii_nway_restart(&pegasus->mii); ++} ++ ++static u32 pegasus_get_link(struct net_device *dev) ++{ ++ pegasus_t *pegasus = netdev_priv(dev); ++ return mii_link_ok(&pegasus->mii); ++} ++ ++static u32 pegasus_get_msglevel(struct net_device *dev) ++{ ++ pegasus_t *pegasus = netdev_priv(dev); ++ return pegasus->msg_enable; ++} ++ ++static void pegasus_set_msglevel(struct net_device *dev, u32 v) ++{ ++ pegasus_t *pegasus = netdev_priv(dev); ++ pegasus->msg_enable = v; ++} ++ ++static const struct ethtool_ops ops = { ++ .get_drvinfo = pegasus_get_drvinfo, ++ .get_settings = pegasus_get_settings, ++ .set_settings = pegasus_set_settings, ++ .nway_reset = pegasus_nway_reset, ++ .get_link = pegasus_get_link, ++ .get_msglevel = pegasus_get_msglevel, ++ .set_msglevel = pegasus_set_msglevel, ++ .get_wol = pegasus_get_wol, ++ .set_wol = pegasus_set_wol, ++}; ++ ++static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd) ++{ ++ __u16 *data = (__u16 *) &rq->ifr_ifru; ++ pegasus_t *pegasus = netdev_priv(net); ++ int res; ++ ++ switch (cmd) { ++ case SIOCDEVPRIVATE: ++ data[0] = pegasus->phy; ++ case SIOCDEVPRIVATE + 1: ++ read_mii_word(pegasus, data[0], data[1] & 0x1f, &data[3]); ++ res = 0; ++ break; ++ case SIOCDEVPRIVATE + 2: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ write_mii_word(pegasus, pegasus->phy, data[1] & 0x1f, &data[2]); ++ res = 0; ++ break; ++ default: ++ res = -EOPNOTSUPP; ++ } ++ return res; ++} ++ ++static void pegasus_set_multicast(struct net_device *net) ++{ ++ pegasus_t *pegasus = netdev_priv(net); ++ ++ if (net->flags & IFF_PROMISC) { ++ pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS; ++ netif_info(pegasus, link, net, "Promiscuous mode enabled\n"); ++ } else if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) { ++ pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST; ++ pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS; ++ netif_dbg(pegasus, link, net, "set allmulti\n"); ++ } else { ++ pegasus->eth_regs[EthCtrl0] &= ~RX_MULTICAST; ++ pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS; ++ } ++ update_eth_regs_async(pegasus); ++} ++ ++static __u8 mii_phy_probe(pegasus_t *pegasus) ++{ ++ int i; ++ __u16 tmp; ++ ++ for (i = 0; i < 32; i++) { ++ read_mii_word(pegasus, i, MII_BMSR, &tmp); ++ if (tmp == 0 || tmp == 0xffff || (tmp & BMSR_MEDIA) == 0) ++ continue; ++ else ++ return i; ++ } ++ ++ return 0xff; ++} ++ ++static inline void setup_pegasus_II(pegasus_t *pegasus) ++{ ++ __u8 data = 0xa5; ++ ++ set_register(pegasus, Reg1d, 0); ++ set_register(pegasus, Reg7b, 1); ++ mdelay(100); ++ if ((pegasus->features & HAS_HOME_PNA) && mii_mode) ++ set_register(pegasus, Reg7b, 0); ++ else ++ set_register(pegasus, Reg7b, 2); ++ ++ set_register(pegasus, 0x83, data); ++ get_registers(pegasus, 0x83, 1, &data); ++ ++ if (data == 0xa5) ++ pegasus->chip = 0x8513; ++ else ++ pegasus->chip = 0; ++ ++ set_register(pegasus, 0x80, 0xc0); ++ set_register(pegasus, 0x83, 0xff); ++ set_register(pegasus, 0x84, 0x01); ++ ++ if (pegasus->features & HAS_HOME_PNA && mii_mode) ++ set_register(pegasus, Reg81, 6); ++ else ++ set_register(pegasus, Reg81, 2); ++} ++ ++ ++static int pegasus_count; ++static struct workqueue_struct *pegasus_workqueue; ++#define CARRIER_CHECK_DELAY (2 * HZ) ++ ++static void check_carrier(struct work_struct *work) ++{ ++ pegasus_t *pegasus = container_of(work, pegasus_t, carrier_check.work); ++ set_carrier(pegasus->net); ++ if (!(pegasus->flags & PEGASUS_UNPLUG)) { ++ queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, ++ CARRIER_CHECK_DELAY); ++ } ++} ++ ++static int pegasus_blacklisted(struct usb_device *udev) ++{ ++ struct usb_device_descriptor *udd = &udev->descriptor; ++ ++ /* Special quirk to keep the driver from handling the Belkin Bluetooth ++ * dongle which happens to have the same ID. ++ */ ++ if ((udd->idVendor == cpu_to_le16(VENDOR_BELKIN)) && ++ (udd->idProduct == cpu_to_le16(0x0121)) && ++ (udd->bDeviceClass == USB_CLASS_WIRELESS_CONTROLLER) && ++ (udd->bDeviceProtocol == 1)) ++ return 1; ++ ++ return 0; ++} ++ ++/* we rely on probe() and remove() being serialized so we ++ * don't need extra locking on pegasus_count. ++ */ ++static void pegasus_dec_workqueue(void) ++{ ++ pegasus_count--; ++ if (pegasus_count == 0) { ++ destroy_workqueue(pegasus_workqueue); ++ pegasus_workqueue = NULL; ++ } ++} ++ ++static int pegasus_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *dev = interface_to_usbdev(intf); ++ struct net_device *net; ++ pegasus_t *pegasus; ++ int dev_index = id - pegasus_ids; ++ int res = -ENOMEM; ++ ++ if (pegasus_blacklisted(dev)) ++ return -ENODEV; ++ ++ if (pegasus_count == 0) { ++ pegasus_workqueue = create_singlethread_workqueue("pegasus"); ++ if (!pegasus_workqueue) ++ return -ENOMEM; ++ } ++ pegasus_count++; ++ ++ net = alloc_etherdev(sizeof(struct pegasus)); ++ if (!net) ++ goto out; ++ ++ pegasus = netdev_priv(net); ++ pegasus->dev_index = dev_index; ++ ++ res = alloc_urbs(pegasus); ++ if (res < 0) { ++ dev_err(&intf->dev, "can't allocate %s\n", "urbs"); ++ goto out1; ++ } ++ ++ tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus); ++ ++ INIT_DELAYED_WORK(&pegasus->carrier_check, check_carrier); ++ ++ pegasus->intf = intf; ++ pegasus->usb = dev; ++ pegasus->net = net; ++ ++ ++ net->watchdog_timeo = PEGASUS_TX_TIMEOUT; ++ net->netdev_ops = &pegasus_netdev_ops; ++ net->ethtool_ops = &ops; ++ pegasus->mii.dev = net; ++ pegasus->mii.mdio_read = mdio_read; ++ pegasus->mii.mdio_write = mdio_write; ++ pegasus->mii.phy_id_mask = 0x1f; ++ pegasus->mii.reg_num_mask = 0x1f; ++ pegasus->msg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV ++ | NETIF_MSG_PROBE | NETIF_MSG_LINK); ++ ++ pegasus->features = usb_dev_id[dev_index].private; ++ get_interrupt_interval(pegasus); ++ if (reset_mac(pegasus)) { ++ dev_err(&intf->dev, "can't reset MAC\n"); ++ res = -EIO; ++ goto out2; ++ } ++ set_ethernet_addr(pegasus); ++ if (pegasus->features & PEGASUS_II) { ++ dev_info(&intf->dev, "setup Pegasus II specific registers\n"); ++ setup_pegasus_II(pegasus); ++ } ++ pegasus->phy = mii_phy_probe(pegasus); ++ if (pegasus->phy == 0xff) { ++ dev_warn(&intf->dev, "can't locate MII phy, using default\n"); ++ pegasus->phy = 1; ++ } ++ pegasus->mii.phy_id = pegasus->phy; ++ usb_set_intfdata(intf, pegasus); ++ SET_NETDEV_DEV(net, &intf->dev); ++ pegasus_reset_wol(net); ++ res = register_netdev(net); ++ if (res) ++ goto out3; ++ queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, ++ CARRIER_CHECK_DELAY); ++ dev_info(&intf->dev, "%s, %s, %pM\n", net->name, ++ usb_dev_id[dev_index].name, net->dev_addr); ++ return 0; ++ ++out3: ++ usb_set_intfdata(intf, NULL); ++out2: ++ free_all_urbs(pegasus); ++out1: ++ free_netdev(net); ++out: ++ pegasus_dec_workqueue(); ++ return res; ++} ++ ++static void pegasus_disconnect(struct usb_interface *intf) ++{ ++ struct pegasus *pegasus = usb_get_intfdata(intf); ++ ++ usb_set_intfdata(intf, NULL); ++ if (!pegasus) { ++ dev_dbg(&intf->dev, "unregistering non-bound device?\n"); ++ return; ++ } ++ ++ pegasus->flags |= PEGASUS_UNPLUG; ++ cancel_delayed_work(&pegasus->carrier_check); ++ unregister_netdev(pegasus->net); ++ unlink_all_urbs(pegasus); ++ free_all_urbs(pegasus); ++ if (pegasus->rx_skb != NULL) { ++ dev_kfree_skb(pegasus->rx_skb); ++ pegasus->rx_skb = NULL; ++ } ++ free_netdev(pegasus->net); ++ pegasus_dec_workqueue(); ++} ++ ++static int pegasus_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct pegasus *pegasus = usb_get_intfdata(intf); ++ ++ netif_device_detach(pegasus->net); ++ cancel_delayed_work(&pegasus->carrier_check); ++ if (netif_running(pegasus->net)) { ++ usb_kill_urb(pegasus->rx_urb); ++ usb_kill_urb(pegasus->intr_urb); ++ } ++ return 0; ++} ++ ++static int pegasus_resume(struct usb_interface *intf) ++{ ++ struct pegasus *pegasus = usb_get_intfdata(intf); ++ ++ netif_device_attach(pegasus->net); ++ if (netif_running(pegasus->net)) { ++ pegasus->rx_urb->status = 0; ++ pegasus->rx_urb->actual_length = 0; ++ read_bulk_callback(pegasus->rx_urb); ++ ++ pegasus->intr_urb->status = 0; ++ pegasus->intr_urb->actual_length = 0; ++ intr_callback(pegasus->intr_urb); ++ } ++ queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, ++ CARRIER_CHECK_DELAY); ++ return 0; ++} ++ ++static const struct net_device_ops pegasus_netdev_ops = { ++ .ndo_open = pegasus_open, ++ .ndo_stop = pegasus_close, ++ .ndo_do_ioctl = pegasus_ioctl, ++ .ndo_start_xmit = pegasus_start_xmit, ++ .ndo_set_rx_mode = pegasus_set_multicast, ++ .ndo_get_stats = pegasus_netdev_stats, ++ .ndo_tx_timeout = pegasus_tx_timeout, ++ .ndo_change_mtu = eth_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++}; ++ ++static struct usb_driver pegasus_driver = { ++ .name = driver_name, ++ .probe = pegasus_probe, ++ .disconnect = pegasus_disconnect, ++ .id_table = pegasus_ids, ++ .suspend = pegasus_suspend, ++ .resume = pegasus_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++static void __init parse_id(char *id) ++{ ++ unsigned int vendor_id = 0, device_id = 0, flags = 0, i = 0; ++ char *token, *name = NULL; ++ ++ if ((token = strsep(&id, ":")) != NULL) ++ name = token; ++ /* name now points to a null terminated string*/ ++ if ((token = strsep(&id, ":")) != NULL) ++ vendor_id = simple_strtoul(token, NULL, 16); ++ if ((token = strsep(&id, ":")) != NULL) ++ device_id = simple_strtoul(token, NULL, 16); ++ flags = simple_strtoul(id, NULL, 16); ++ pr_info("%s: new device %s, vendor ID 0x%04x, device ID 0x%04x, flags: 0x%x\n", ++ driver_name, name, vendor_id, device_id, flags); ++ ++ if (vendor_id > 0x10000 || vendor_id == 0) ++ return; ++ if (device_id > 0x10000 || device_id == 0) ++ return; ++ ++ for (i = 0; usb_dev_id[i].name; i++); ++ usb_dev_id[i].name = name; ++ usb_dev_id[i].vendor = vendor_id; ++ usb_dev_id[i].device = device_id; ++ usb_dev_id[i].private = flags; ++ pegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE; ++ pegasus_ids[i].idVendor = vendor_id; ++ pegasus_ids[i].idProduct = device_id; ++} ++ ++static int __init pegasus_init(void) ++{ ++ pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION); ++ if (devid) ++ parse_id(devid); ++ return usb_register(&pegasus_driver); ++} ++ ++static void __exit pegasus_exit(void) ++{ ++ usb_deregister(&pegasus_driver); ++} ++ ++module_init(pegasus_init); ++module_exit(pegasus_exit); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/pegasus.h backports-3.18.1-1/drivers/net/usb/pegasus.h +--- backports-3.18.1-1.org/drivers/net/usb/pegasus.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/pegasus.h 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,308 @@ ++/* ++ * Copyright (c) 1999-2013 Petko Manolov (petkan@nucleusys.com) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++ ++#ifndef PEGASUS_DEV ++ ++#define PEGASUS_II 0x80000000 ++#define HAS_HOME_PNA 0x40000000 ++ ++#define PEGASUS_MTU 1536 ++ ++#define EPROM_WRITE 0x01 ++#define EPROM_READ 0x02 ++#define EPROM_DONE 0x04 ++#define EPROM_WR_ENABLE 0x10 ++#define EPROM_LOAD 0x20 ++ ++#define PHY_DONE 0x80 ++#define PHY_READ 0x40 ++#define PHY_WRITE 0x20 ++#define DEFAULT_GPIO_RESET 0x24 ++#define DEFAULT_GPIO_SET 0x26 ++ ++#define PEGASUS_PRESENT 0x00000001 ++#define PEGASUS_TX_BUSY 0x00000004 ++#define PEGASUS_RX_BUSY 0x00000008 ++#define CTRL_URB_RUNNING 0x00000010 ++#define CTRL_URB_SLEEP 0x00000020 ++#define PEGASUS_UNPLUG 0x00000040 ++#define PEGASUS_RX_URB_FAIL 0x00000080 ++ ++#define RX_MULTICAST 2 ++#define RX_PROMISCUOUS 4 ++ ++#define REG_TIMEOUT (HZ) ++#define PEGASUS_TX_TIMEOUT (HZ*10) ++ ++#define TX_UNDERRUN 0x80 ++#define EXCESSIVE_COL 0x40 ++#define LATE_COL 0x20 ++#define NO_CARRIER 0x10 ++#define LOSS_CARRIER 0x08 ++#define JABBER_TIMEOUT 0x04 ++ ++#define LINK_STATUS 0x01 ++ ++#define PEGASUS_REQT_READ 0xc0 ++#define PEGASUS_REQT_WRITE 0x40 ++#define PEGASUS_REQ_GET_REGS 0xf0 ++#define PEGASUS_REQ_SET_REGS 0xf1 ++#define PEGASUS_REQ_SET_REG PEGASUS_REQ_SET_REGS ++ ++enum pegasus_registers { ++ EthCtrl0 = 0, ++ EthCtrl1 = 1, ++ EthCtrl2 = 2, ++ EthID = 0x10, ++ Reg1d = 0x1d, ++ EpromOffset = 0x20, ++ EpromData = 0x21, /* 0x21 low, 0x22 high byte */ ++ EpromCtrl = 0x23, ++ PhyAddr = 0x25, ++ PhyData = 0x26, /* 0x26 low, 0x27 high byte */ ++ PhyCtrl = 0x28, ++ UsbStst = 0x2a, ++ EthTxStat0 = 0x2b, ++ EthTxStat1 = 0x2c, ++ EthRxStat = 0x2d, ++ WakeupControl = 0x78, ++ Reg7b = 0x7b, ++ Gpio0 = 0x7e, ++ Gpio1 = 0x7f, ++ Reg81 = 0x81, ++}; ++ ++ ++typedef struct pegasus { ++ struct usb_device *usb; ++ struct usb_interface *intf; ++ struct net_device *net; ++ struct net_device_stats stats; ++ struct mii_if_info mii; ++ unsigned flags; ++ unsigned features; ++ u32 msg_enable; ++ u32 wolopts; ++ int dev_index; ++ int intr_interval; ++ struct tasklet_struct rx_tl; ++ struct delayed_work carrier_check; ++ struct urb *rx_urb, *tx_urb, *intr_urb; ++ struct sk_buff *rx_skb; ++ int chip; ++ unsigned char intr_buff[8]; ++ __u8 tx_buff[PEGASUS_MTU]; ++ __u8 eth_regs[4]; ++ __u8 phy; ++ __u8 gpio_res; ++} pegasus_t; ++ ++ ++struct usb_eth_dev { ++ char *name; ++ __u16 vendor; ++ __u16 device; ++ __u32 private; /* LSB is gpio reset value */ ++}; ++ ++#define VENDOR_3COM 0x0506 ++#define VENDOR_ABOCOM 0x07b8 ++#define VENDOR_ACCTON 0x083a ++#define VENDOR_ADMTEK 0x07a6 ++#define VENDOR_AEILAB 0x3334 ++#define VENDOR_ALLIEDTEL 0x07c9 ++#define VENDOR_ATEN 0x0557 ++#define VENDOR_BELKIN 0x050d ++#define VENDOR_BILLIONTON 0x08dd ++#define VENDOR_COMPAQ 0x049f ++#define VENDOR_COREGA 0x07aa ++#define VENDOR_DLINK 0x2001 ++#define VENDOR_ELCON 0x0db7 ++#define VENDOR_ELECOM 0x056e ++#define VENDOR_ELSA 0x05cc ++#define VENDOR_GIGABYTE 0x1044 ++#define VENDOR_HAWKING 0x0e66 ++#define VENDOR_HP 0x03f0 ++#define VENDOR_IODATA 0x04bb ++#define VENDOR_KINGSTON 0x0951 ++#define VENDOR_LANEED 0x056e ++#define VENDOR_LINKSYS 0x066b ++#define VENDOR_LINKSYS2 0x077b ++#define VENDOR_MELCO 0x0411 ++#define VENDOR_MICROSOFT 0x045e ++#define VENDOR_MOBILITY 0x1342 ++#define VENDOR_NETGEAR 0x0846 ++#define VENDOR_OCT 0x0b39 ++#define VENDOR_SMARTBRIDGES 0x08d1 ++#define VENDOR_SMC 0x0707 ++#define VENDOR_SOHOWARE 0x15e8 ++#define VENDOR_SIEMENS 0x067c ++ ++ ++#else /* PEGASUS_DEV */ ++ ++PEGASUS_DEV("3Com USB Ethernet 3C460B", VENDOR_3COM, 0x4601, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("ATEN USB Ethernet UC-110T", VENDOR_ATEN, 0x2007, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x110c, ++ DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA) ++PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4104, ++ DEFAULT_GPIO_RESET | HAS_HOME_PNA) ++PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4004, ++ DEFAULT_GPIO_RESET | HAS_HOME_PNA) ++PEGASUS_DEV("USB HPNA/Ethernet", VENDOR_ABOCOM, 0x4007, ++ DEFAULT_GPIO_RESET | HAS_HOME_PNA) ++PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4102, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x4002, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400b, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Philips USB 10/100 Ethernet", VENDOR_ACCTON, 0xb004, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("ADMtek ADM8511 "Pegasus II" USB Ethernet", ++ VENDOR_ADMTEK, 0x8511, ++ DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA) ++PEGASUS_DEV("ADMtek ADM8513 "Pegasus II" USB Ethernet", ++ VENDOR_ADMTEK, 0x8513, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("ADMtek ADM8515 "Pegasus II" USB-2.0 Ethernet", ++ VENDOR_ADMTEK, 0x8515, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("ADMtek AN986 "Pegasus" USB Ethernet (evaluation board)", ++ VENDOR_ADMTEK, 0x0986, ++ DEFAULT_GPIO_RESET | HAS_HOME_PNA) ++PEGASUS_DEV("AN986A USB MAC", VENDOR_ADMTEK, 1986, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++/* ++ * Distinguish between this Belkin adaptor and the Belkin bluetooth adaptors ++ * with the same product IDs by checking the device class too. ++ */ ++PEGASUS_DEV_CLASS("Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Billionton USB-100", VENDOR_BILLIONTON, 0x0986, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987, ++ DEFAULT_GPIO_RESET | HAS_HOME_PNA) ++PEGASUS_DEV("iPAQ Networking 10/100 USB", VENDOR_COMPAQ, 0x8511, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Billionton USBEL-100", VENDOR_BILLIONTON, 0x0988, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("Billionton USBE-100", VENDOR_BILLIONTON, 0x8511, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Corega FEther USB-TX", VENDOR_COREGA, 0x0004, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("Corega FEther USB-TXS", VENDOR_COREGA, 0x000d, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4001, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4002, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x4102, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x400b, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("D-Link DSB-650TX", VENDOR_DLINK, 0x200c, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("D-Link DSB-650TX(PNA)", VENDOR_DLINK, 0x4003, ++ DEFAULT_GPIO_RESET | HAS_HOME_PNA) ++PEGASUS_DEV("D-Link DSB-650", VENDOR_DLINK, 0xabc1, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002, ++ DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA) ++PEGASUS_DEV("ELECOM USB Ethernet LD-USB20", VENDOR_ELECOM, 0x4010, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("EasiDock Ethernet", VENDOR_MOBILITY, 0x0304, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("HP hn210c Ethernet USB", VENDOR_HP, 0x811c, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("IO DATA USB ET/TX", VENDOR_IODATA, 0x0904, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("IO DATA USB ETX-US2", VENDOR_IODATA, 0x093a, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("LANEED USB Ethernet LD-USBL/TX", VENDOR_LANEED, 0x4005, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("LANEED USB Ethernet LD-USB/T", VENDOR_LANEED, 0xabc1, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x200c, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Linksys USB10TX", VENDOR_LINKSYS, 0x2202, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("Linksys USB100TX", VENDOR_LINKSYS, 0x2203, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("Linksys USB100TX", VENDOR_LINKSYS, 0x2204, ++ DEFAULT_GPIO_RESET | HAS_HOME_PNA) ++PEGASUS_DEV("Linksys USB10T Ethernet Adapter", VENDOR_LINKSYS, 0x2206, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Linksys USBVPN1", VENDOR_LINKSYS2, 0x08b4, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("Linksys USB USB100TX", VENDOR_LINKSYS, 0x400b, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Linksys USB10TX", VENDOR_LINKSYS, 0x200c, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0001, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("Microsoft MN-110", VENDOR_MICROSOFT, 0x007a, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("NETGEAR FA101", VENDOR_NETGEAR, 0x1020, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("OCT Inc.", VENDOR_OCT, 0x0109, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("OCT USB TO Ethernet", VENDOR_OCT, 0x0901, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("SMC 202 USB Ethernet", VENDOR_SMC, 0x0200, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("SMC 2206 USB Ethernet", VENDOR_SMC, 0x0201, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100, ++ DEFAULT_GPIO_RESET) ++PEGASUS_DEV("SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++PEGASUS_DEV("SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001, ++ DEFAULT_GPIO_RESET | PEGASUS_II) ++ ++ ++#endif /* PEGASUS_DEV */ +diff -Naur backports-3.18.1-1.org/drivers/net/usb/plusb.c backports-3.18.1-1/drivers/net/usb/plusb.c +--- backports-3.18.1-1.org/drivers/net/usb/plusb.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/plusb.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,157 @@ ++/* ++ * PL-2301/2302 USB host-to-host link cables ++ * Copyright (C) 2000-2005 by David Brownell ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++// #define DEBUG // error path messages, extra info ++// #define VERBOSE // more; success messages ++ ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/usb/usbnet.h> ++ ++ ++/* ++ * Prolific PL-2301/PL-2302 driver ... http://www.prolific.com.tw/ ++ * ++ * The protocol and handshaking used here should be bug-compatible ++ * with the Linux 2.2 "plusb" driver, by Deti Fliegl. ++ * ++ * HEADS UP: this handshaking isn't all that robust. This driver ++ * gets confused easily if you unplug one end of the cable then ++ * try to connect it again; you'll need to restart both ends. The ++ * "naplink" software (used by some PlayStation/2 deveopers) does ++ * the handshaking much better! Also, sometimes this hardware ++ * seems to get wedged under load. Prolific docs are weak, and ++ * don't identify differences between PL2301 and PL2302, much less ++ * anything to explain the different PL2302 versions observed. ++ * ++ * NOTE: pl2501 has several modes, including pl2301 and pl2302 ++ * compatibility. Some docs suggest the difference between 2301 ++ * and 2302 is only to make MS-Windows use a different driver... ++ * ++ * pl25a1 glue based on patch from Tony Gibbs. Prolific "docs" on ++ * this chip are as usual incomplete about what control messages ++ * are supported. ++ */ ++ ++/* ++ * Bits 0-4 can be used for software handshaking; they're set from ++ * one end, cleared from the other, "read" with the interrupt byte. ++ */ ++#define PL_S_EN (1<<7) /* (feature only) suspend enable */ ++/* reserved bit -- rx ready (6) ? */ ++#define PL_TX_READY (1<<5) /* (interrupt only) transmit ready */ ++#define PL_RESET_OUT (1<<4) /* reset output pipe */ ++#define PL_RESET_IN (1<<3) /* reset input pipe */ ++#define PL_TX_C (1<<2) /* transmission complete */ ++#define PL_TX_REQ (1<<1) /* transmission received */ ++#define PL_PEER_E (1<<0) /* peer exists */ ++ ++static inline int ++pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index) ++{ ++ return usbnet_read_cmd(dev, req, ++ USB_DIR_IN | USB_TYPE_VENDOR | ++ USB_RECIP_DEVICE, ++ val, index, NULL, 0); ++} ++ ++static inline int ++pl_clear_QuickLink_features(struct usbnet *dev, int val) ++{ ++ return pl_vendor_req(dev, 1, (u8) val, 0); ++} ++ ++static inline int ++pl_set_QuickLink_features(struct usbnet *dev, int val) ++{ ++ return pl_vendor_req(dev, 3, (u8) val, 0); ++} ++ ++static int pl_reset(struct usbnet *dev) ++{ ++ int status; ++ ++ /* some units seem to need this reset, others reject it utterly. ++ * FIXME be more like "naplink" or windows drivers. ++ */ ++ status = pl_set_QuickLink_features(dev, ++ PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E); ++ if (status != 0 && netif_msg_probe(dev)) ++ netif_dbg(dev, link, dev->net, "pl_reset --> %d\n", status); ++ return 0; ++} ++ ++static const struct driver_info prolific_info = { ++ .description = "Prolific PL-2301/PL-2302/PL-25A1", ++ .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT, ++ /* some PL-2302 versions seem to fail usb_set_interface() */ ++ .reset = pl_reset, ++}; ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * Proilific's name won't normally be on the cables, and ++ * may not be on the device. ++ */ ++ ++static const struct usb_device_id products [] = { ++ ++/* full speed cables */ ++{ ++ USB_DEVICE(0x067b, 0x0000), // PL-2301 ++ .driver_info = (unsigned long) &prolific_info, ++}, { ++ USB_DEVICE(0x067b, 0x0001), // PL-2302 ++ .driver_info = (unsigned long) &prolific_info, ++}, ++ ++/* high speed cables */ ++{ ++ USB_DEVICE(0x067b, 0x25a1), /* PL-25A1, no eeprom */ ++ .driver_info = (unsigned long) &prolific_info, ++}, { ++ USB_DEVICE(0x050d, 0x258a), /* Belkin F5U258/F5U279 (PL-25A1) */ ++ .driver_info = (unsigned long) &prolific_info, ++}, ++ ++ { }, // END ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver plusb_driver = { ++ .name = "plusb", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(plusb_driver); ++ ++MODULE_AUTHOR("David Brownell"); ++MODULE_DESCRIPTION("Prolific PL-2301/2302/25A1 USB Host to Host Link Driver"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/r8152.c backports-3.18.1-1/drivers/net/usb/r8152.c +--- backports-3.18.1-1.org/drivers/net/usb/r8152.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/r8152.c 2015-01-03 13:42:25.000000000 +0100 +@@ -0,0 +1,3913 @@ ++/* ++ * Copyright (c) 2014 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 ++ * version 2 as published by the Free Software Foundation. ++ * ++ */ ++ ++#include <linux/signal.h> ++#include <linux/slab.h> ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/mii.h> ++#include <linux/ethtool.h> ++#include <linux/usb.h> ++#include <linux/crc32.h> ++#include <linux/if_vlan.h> ++#include <linux/uaccess.h> ++#include <linux/list.h> ++#include <linux/ip.h> ++#include <linux/ipv6.h> ++#include <net/ip6_checksum.h> ++#include <uapi/linux/mdio.h> ++#include <linux/mdio.h> ++ ++/* Version Information */ ++#define DRIVER_VERSION "v1.07.0 (2014/10/09)" ++#define DRIVER_AUTHOR "Realtek linux nic maintainers nic_swsd@realtek.com" ++#define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters" ++#define MODULENAME "r8152" ++ ++#define R8152_PHY_ID 32 ++ ++#define PLA_IDR 0xc000 ++#define PLA_RCR 0xc010 ++#define PLA_RMS 0xc016 ++#define PLA_RXFIFO_CTRL0 0xc0a0 ++#define PLA_RXFIFO_CTRL1 0xc0a4 ++#define PLA_RXFIFO_CTRL2 0xc0a8 ++#define PLA_FMC 0xc0b4 ++#define PLA_CFG_WOL 0xc0b6 ++#define PLA_TEREDO_CFG 0xc0bc ++#define PLA_MAR 0xcd00 ++#define PLA_BACKUP 0xd000 ++#define PAL_BDC_CR 0xd1a0 ++#define PLA_TEREDO_TIMER 0xd2cc ++#define PLA_REALWOW_TIMER 0xd2e8 ++#define PLA_LEDSEL 0xdd90 ++#define PLA_LED_FEATURE 0xdd92 ++#define PLA_PHYAR 0xde00 ++#define PLA_BOOT_CTRL 0xe004 ++#define PLA_GPHY_INTR_IMR 0xe022 ++#define PLA_EEE_CR 0xe040 ++#define PLA_EEEP_CR 0xe080 ++#define PLA_MAC_PWR_CTRL 0xe0c0 ++#define PLA_MAC_PWR_CTRL2 0xe0ca ++#define PLA_MAC_PWR_CTRL3 0xe0cc ++#define PLA_MAC_PWR_CTRL4 0xe0ce ++#define PLA_WDT6_CTRL 0xe428 ++#define PLA_TCR0 0xe610 ++#define PLA_TCR1 0xe612 ++#define PLA_MTPS 0xe615 ++#define PLA_TXFIFO_CTRL 0xe618 ++#define PLA_RSTTALLY 0xe800 ++#define PLA_CR 0xe813 ++#define PLA_CRWECR 0xe81c ++#define PLA_CONFIG12 0xe81e /* CONFIG1, CONFIG2 */ ++#define PLA_CONFIG34 0xe820 /* CONFIG3, CONFIG4 */ ++#define PLA_CONFIG5 0xe822 ++#define PLA_PHY_PWR 0xe84c ++#define PLA_OOB_CTRL 0xe84f ++#define PLA_CPCR 0xe854 ++#define PLA_MISC_0 0xe858 ++#define PLA_MISC_1 0xe85a ++#define PLA_OCP_GPHY_BASE 0xe86c ++#define PLA_TALLYCNT 0xe890 ++#define PLA_SFF_STS_7 0xe8de ++#define PLA_PHYSTATUS 0xe908 ++#define PLA_BP_BA 0xfc26 ++#define PLA_BP_0 0xfc28 ++#define PLA_BP_1 0xfc2a ++#define PLA_BP_2 0xfc2c ++#define PLA_BP_3 0xfc2e ++#define PLA_BP_4 0xfc30 ++#define PLA_BP_5 0xfc32 ++#define PLA_BP_6 0xfc34 ++#define PLA_BP_7 0xfc36 ++#define PLA_BP_EN 0xfc38 ++ ++#define USB_U2P3_CTRL 0xb460 ++#define USB_DEV_STAT 0xb808 ++#define USB_USB_CTRL 0xd406 ++#define USB_PHY_CTRL 0xd408 ++#define USB_TX_AGG 0xd40a ++#define USB_RX_BUF_TH 0xd40c ++#define USB_USB_TIMER 0xd428 ++#define USB_RX_EARLY_AGG 0xd42c ++#define USB_PM_CTRL_STATUS 0xd432 ++#define USB_TX_DMA 0xd434 ++#define USB_TOLERANCE 0xd490 ++#define USB_LPM_CTRL 0xd41a ++#define USB_UPS_CTRL 0xd800 ++#define USB_MISC_0 0xd81a ++#define USB_POWER_CUT 0xd80a ++#define USB_AFE_CTRL2 0xd824 ++#define USB_WDT11_CTRL 0xe43c ++#define USB_BP_BA 0xfc26 ++#define USB_BP_0 0xfc28 ++#define USB_BP_1 0xfc2a ++#define USB_BP_2 0xfc2c ++#define USB_BP_3 0xfc2e ++#define USB_BP_4 0xfc30 ++#define USB_BP_5 0xfc32 ++#define USB_BP_6 0xfc34 ++#define USB_BP_7 0xfc36 ++#define USB_BP_EN 0xfc38 ++ ++/* OCP Registers */ ++#define OCP_ALDPS_CONFIG 0x2010 ++#define OCP_EEE_CONFIG1 0x2080 ++#define OCP_EEE_CONFIG2 0x2092 ++#define OCP_EEE_CONFIG3 0x2094 ++#define OCP_BASE_MII 0xa400 ++#define OCP_EEE_AR 0xa41a ++#define OCP_EEE_DATA 0xa41c ++#define OCP_PHY_STATUS 0xa420 ++#define OCP_POWER_CFG 0xa430 ++#define OCP_EEE_CFG 0xa432 ++#define OCP_SRAM_ADDR 0xa436 ++#define OCP_SRAM_DATA 0xa438 ++#define OCP_DOWN_SPEED 0xa442 ++#define OCP_EEE_ABLE 0xa5c4 ++#define OCP_EEE_ADV 0xa5d0 ++#define OCP_EEE_LPABLE 0xa5d2 ++#define OCP_ADC_CFG 0xbc06 ++ ++/* SRAM Register */ ++#define SRAM_LPF_CFG 0x8012 ++#define SRAM_10M_AMP1 0x8080 ++#define SRAM_10M_AMP2 0x8082 ++#define SRAM_IMPEDANCE 0x8084 ++ ++/* PLA_RCR */ ++#define RCR_AAP 0x00000001 ++#define RCR_APM 0x00000002 ++#define RCR_AM 0x00000004 ++#define RCR_AB 0x00000008 ++#define RCR_ACPT_ALL (RCR_AAP | RCR_APM | RCR_AM | RCR_AB) ++ ++/* PLA_RXFIFO_CTRL0 */ ++#define RXFIFO_THR1_NORMAL 0x00080002 ++#define RXFIFO_THR1_OOB 0x01800003 ++ ++/* PLA_RXFIFO_CTRL1 */ ++#define RXFIFO_THR2_FULL 0x00000060 ++#define RXFIFO_THR2_HIGH 0x00000038 ++#define RXFIFO_THR2_OOB 0x0000004a ++#define RXFIFO_THR2_NORMAL 0x00a0 ++ ++/* PLA_RXFIFO_CTRL2 */ ++#define RXFIFO_THR3_FULL 0x00000078 ++#define RXFIFO_THR3_HIGH 0x00000048 ++#define RXFIFO_THR3_OOB 0x0000005a ++#define RXFIFO_THR3_NORMAL 0x0110 ++ ++/* PLA_TXFIFO_CTRL */ ++#define TXFIFO_THR_NORMAL 0x00400008 ++#define TXFIFO_THR_NORMAL2 0x01000008 ++ ++/* PLA_FMC */ ++#define FMC_FCR_MCU_EN 0x0001 ++ ++/* PLA_EEEP_CR */ ++#define EEEP_CR_EEEP_TX 0x0002 ++ ++/* PLA_WDT6_CTRL */ ++#define WDT6_SET_MODE 0x0010 ++ ++/* PLA_TCR0 */ ++#define TCR0_TX_EMPTY 0x0800 ++#define TCR0_AUTO_FIFO 0x0080 ++ ++/* PLA_TCR1 */ ++#define VERSION_MASK 0x7cf0 ++ ++/* PLA_MTPS */ ++#define MTPS_JUMBO (12 * 1024 / 64) ++#define MTPS_DEFAULT (6 * 1024 / 64) ++ ++/* PLA_RSTTALLY */ ++#define TALLY_RESET 0x0001 ++ ++/* PLA_CR */ ++#define CR_RST 0x10 ++#define CR_RE 0x08 ++#define CR_TE 0x04 ++ ++/* PLA_CRWECR */ ++#define CRWECR_NORAML 0x00 ++#define CRWECR_CONFIG 0xc0 ++ ++/* PLA_OOB_CTRL */ ++#define NOW_IS_OOB 0x80 ++#define TXFIFO_EMPTY 0x20 ++#define RXFIFO_EMPTY 0x10 ++#define LINK_LIST_READY 0x02 ++#define DIS_MCU_CLROOB 0x01 ++#define FIFO_EMPTY (TXFIFO_EMPTY | RXFIFO_EMPTY) ++ ++/* PLA_MISC_1 */ ++#define RXDY_GATED_EN 0x0008 ++ ++/* PLA_SFF_STS_7 */ ++#define RE_INIT_LL 0x8000 ++#define MCU_BORW_EN 0x4000 ++ ++/* PLA_CPCR */ ++#define CPCR_RX_VLAN 0x0040 ++ ++/* PLA_CFG_WOL */ ++#define MAGIC_EN 0x0001 ++ ++/* PLA_TEREDO_CFG */ ++#define TEREDO_SEL 0x8000 ++#define TEREDO_WAKE_MASK 0x7f00 ++#define TEREDO_RS_EVENT_MASK 0x00fe ++#define OOB_TEREDO_EN 0x0001 ++ ++/* PAL_BDC_CR */ ++#define ALDPS_PROXY_MODE 0x0001 ++ ++/* PLA_CONFIG34 */ ++#define LINK_ON_WAKE_EN 0x0010 ++#define LINK_OFF_WAKE_EN 0x0008 ++ ++/* PLA_CONFIG5 */ ++#define BWF_EN 0x0040 ++#define MWF_EN 0x0020 ++#define UWF_EN 0x0010 ++#define LAN_WAKE_EN 0x0002 ++ ++/* PLA_LED_FEATURE */ ++#define LED_MODE_MASK 0x0700 ++ ++/* PLA_PHY_PWR */ ++#define TX_10M_IDLE_EN 0x0080 ++#define PFM_PWM_SWITCH 0x0040 ++ ++/* PLA_MAC_PWR_CTRL */ ++#define D3_CLK_GATED_EN 0x00004000 ++#define MCU_CLK_RATIO 0x07010f07 ++#define MCU_CLK_RATIO_MASK 0x0f0f0f0f ++#define ALDPS_SPDWN_RATIO 0x0f87 ++ ++/* PLA_MAC_PWR_CTRL2 */ ++#define EEE_SPDWN_RATIO 0x8007 ++ ++/* PLA_MAC_PWR_CTRL3 */ ++#define PKT_AVAIL_SPDWN_EN 0x0100 ++#define SUSPEND_SPDWN_EN 0x0004 ++#define U1U2_SPDWN_EN 0x0002 ++#define L1_SPDWN_EN 0x0001 ++ ++/* PLA_MAC_PWR_CTRL4 */ ++#define PWRSAVE_SPDWN_EN 0x1000 ++#define RXDV_SPDWN_EN 0x0800 ++#define TX10MIDLE_EN 0x0100 ++#define TP100_SPDWN_EN 0x0020 ++#define TP500_SPDWN_EN 0x0010 ++#define TP1000_SPDWN_EN 0x0008 ++#define EEE_SPDWN_EN 0x0001 ++ ++/* PLA_GPHY_INTR_IMR */ ++#define GPHY_STS_MSK 0x0001 ++#define SPEED_DOWN_MSK 0x0002 ++#define SPDWN_RXDV_MSK 0x0004 ++#define SPDWN_LINKCHG_MSK 0x0008 ++ ++/* PLA_PHYAR */ ++#define PHYAR_FLAG 0x80000000 ++ ++/* PLA_EEE_CR */ ++#define EEE_RX_EN 0x0001 ++#define EEE_TX_EN 0x0002 ++ ++/* PLA_BOOT_CTRL */ ++#define AUTOLOAD_DONE 0x0002 ++ ++/* USB_DEV_STAT */ ++#define STAT_SPEED_MASK 0x0006 ++#define STAT_SPEED_HIGH 0x0000 ++#define STAT_SPEED_FULL 0x0002 ++ ++/* USB_TX_AGG */ ++#define TX_AGG_MAX_THRESHOLD 0x03 ++ ++/* USB_RX_BUF_TH */ ++#define RX_THR_SUPPER 0x0c350180 ++#define RX_THR_HIGH 0x7a120180 ++#define RX_THR_SLOW 0xffff0180 ++ ++/* USB_TX_DMA */ ++#define TEST_MODE_DISABLE 0x00000001 ++#define TX_SIZE_ADJUST1 0x00000100 ++ ++/* USB_UPS_CTRL */ ++#define POWER_CUT 0x0100 ++ ++/* USB_PM_CTRL_STATUS */ ++#define RESUME_INDICATE 0x0001 ++ ++/* USB_USB_CTRL */ ++#define RX_AGG_DISABLE 0x0010 ++ ++/* USB_U2P3_CTRL */ ++#define U2P3_ENABLE 0x0001 ++ ++/* USB_POWER_CUT */ ++#define PWR_EN 0x0001 ++#define PHASE2_EN 0x0008 ++ ++/* USB_MISC_0 */ ++#define PCUT_STATUS 0x0001 ++ ++/* USB_RX_EARLY_AGG */ ++#define EARLY_AGG_SUPPER 0x0e832981 ++#define EARLY_AGG_HIGH 0x0e837a12 ++#define EARLY_AGG_SLOW 0x0e83ffff ++ ++/* USB_WDT11_CTRL */ ++#define TIMER11_EN 0x0001 ++ ++/* USB_LPM_CTRL */ ++#define LPM_TIMER_MASK 0x0c ++#define LPM_TIMER_500MS 0x04 /* 500 ms */ ++#define LPM_TIMER_500US 0x0c /* 500 us */ ++ ++/* USB_AFE_CTRL2 */ ++#define SEN_VAL_MASK 0xf800 ++#define SEN_VAL_NORMAL 0xa000 ++#define SEL_RXIDLE 0x0100 ++ ++/* OCP_ALDPS_CONFIG */ ++#define ENPWRSAVE 0x8000 ++#define ENPDNPS 0x0200 ++#define LINKENA 0x0100 ++#define DIS_SDSAVE 0x0010 ++ ++/* OCP_PHY_STATUS */ ++#define PHY_STAT_MASK 0x0007 ++#define PHY_STAT_LAN_ON 3 ++#define PHY_STAT_PWRDN 5 ++ ++/* OCP_POWER_CFG */ ++#define EEE_CLKDIV_EN 0x8000 ++#define EN_ALDPS 0x0004 ++#define EN_10M_PLLOFF 0x0001 ++ ++/* OCP_EEE_CONFIG1 */ ++#define RG_TXLPI_MSK_HFDUP 0x8000 ++#define RG_MATCLR_EN 0x4000 ++#define EEE_10_CAP 0x2000 ++#define EEE_NWAY_EN 0x1000 ++#define TX_QUIET_EN 0x0200 ++#define RX_QUIET_EN 0x0100 ++#define sd_rise_time_mask 0x0070 ++#define sd_rise_time(x) (min(x, 7) << 4) /* bit 4 ~ 6 */ ++#define RG_RXLPI_MSK_HFDUP 0x0008 ++#define SDFALLTIME 0x0007 /* bit 0 ~ 2 */ ++ ++/* OCP_EEE_CONFIG2 */ ++#define RG_LPIHYS_NUM 0x7000 /* bit 12 ~ 15 */ ++#define RG_DACQUIET_EN 0x0400 ++#define RG_LDVQUIET_EN 0x0200 ++#define RG_CKRSEL 0x0020 ++#define RG_EEEPRG_EN 0x0010 ++ ++/* OCP_EEE_CONFIG3 */ ++#define fast_snr_mask 0xff80 ++#define fast_snr(x) (min(x, 0x1ff) << 7) /* bit 7 ~ 15 */ ++#define RG_LFS_SEL 0x0060 /* bit 6 ~ 5 */ ++#define MSK_PH 0x0006 /* bit 0 ~ 3 */ ++ ++/* OCP_EEE_AR */ ++/* bit[15:14] function */ ++#define FUN_ADDR 0x0000 ++#define FUN_DATA 0x4000 ++/* bit[4:0] device addr */ ++ ++/* OCP_EEE_CFG */ ++#define CTAP_SHORT_EN 0x0040 ++#define EEE10_EN 0x0010 ++ ++/* OCP_DOWN_SPEED */ ++#define EN_10M_BGOFF 0x0080 ++ ++/* OCP_ADC_CFG */ ++#define CKADSEL_L 0x0100 ++#define ADC_EN 0x0080 ++#define EN_EMI_L 0x0040 ++ ++/* SRAM_LPF_CFG */ ++#define LPF_AUTO_TUNE 0x8000 ++ ++/* SRAM_10M_AMP1 */ ++#define GDAC_IB_UPALL 0x0008 ++ ++/* SRAM_10M_AMP2 */ ++#define AMP_DN 0x0200 ++ ++/* SRAM_IMPEDANCE */ ++#define RX_DRIVING_MASK 0x6000 ++ ++enum rtl_register_content { ++ _1000bps = 0x10, ++ _100bps = 0x08, ++ _10bps = 0x04, ++ LINK_STATUS = 0x02, ++ FULL_DUP = 0x01, ++}; ++ ++#define RTL8152_MAX_TX 4 ++#define RTL8152_MAX_RX 10 ++#define INTBUFSIZE 2 ++#define CRC_SIZE 4 ++#define TX_ALIGN 4 ++#define RX_ALIGN 8 ++ ++#define INTR_LINK 0x0004 ++ ++#define RTL8152_REQT_READ 0xc0 ++#define RTL8152_REQT_WRITE 0x40 ++#define RTL8152_REQ_GET_REGS 0x05 ++#define RTL8152_REQ_SET_REGS 0x05 ++ ++#define BYTE_EN_DWORD 0xff ++#define BYTE_EN_WORD 0x33 ++#define BYTE_EN_BYTE 0x11 ++#define BYTE_EN_SIX_BYTES 0x3f ++#define BYTE_EN_START_MASK 0x0f ++#define BYTE_EN_END_MASK 0xf0 ++ ++#define RTL8153_MAX_PACKET 9216 /* 9K */ ++#define RTL8153_MAX_MTU (RTL8153_MAX_PACKET - VLAN_ETH_HLEN - VLAN_HLEN) ++#define RTL8152_RMS (VLAN_ETH_FRAME_LEN + VLAN_HLEN) ++#define RTL8153_RMS RTL8153_MAX_PACKET ++#define RTL8152_TX_TIMEOUT (5 * HZ) ++ ++/* rtl8152 flags */ ++enum rtl8152_flags { ++ RTL8152_UNPLUG = 0, ++ RTL8152_SET_RX_MODE, ++ WORK_ENABLE, ++ RTL8152_LINK_CHG, ++ SELECTIVE_SUSPEND, ++ PHY_RESET, ++ SCHEDULE_TASKLET, ++}; ++ ++/* Define these values to match your device */ ++#define VENDOR_ID_REALTEK 0x0bda ++#define PRODUCT_ID_RTL8152 0x8152 ++#define PRODUCT_ID_RTL8153 0x8153 ++ ++#define VENDOR_ID_SAMSUNG 0x04e8 ++#define PRODUCT_ID_SAMSUNG 0xa101 ++ ++#define MCU_TYPE_PLA 0x0100 ++#define MCU_TYPE_USB 0x0000 ++ ++#define REALTEK_USB_DEVICE(vend, prod) \ ++ USB_DEVICE_INTERFACE_CLASS(vend, prod, USB_CLASS_VENDOR_SPEC) ++ ++struct tally_counter { ++ __le64 tx_packets; ++ __le64 rx_packets; ++ __le64 tx_errors; ++ __le32 rx_errors; ++ __le16 rx_missed; ++ __le16 align_errors; ++ __le32 tx_one_collision; ++ __le32 tx_multi_collision; ++ __le64 rx_unicast; ++ __le64 rx_broadcast; ++ __le32 rx_multicast; ++ __le16 tx_aborted; ++ __le16 tx_underun; ++}; ++ ++struct rx_desc { ++ __le32 opts1; ++#define RX_LEN_MASK 0x7fff ++ ++ __le32 opts2; ++#define RD_UDP_CS (1 << 23) ++#define RD_TCP_CS (1 << 22) ++#define RD_IPV6_CS (1 << 20) ++#define RD_IPV4_CS (1 << 19) ++ ++ __le32 opts3; ++#define IPF (1 << 23) /* IP checksum fail */ ++#define UDPF (1 << 22) /* UDP checksum fail */ ++#define TCPF (1 << 21) /* TCP checksum fail */ ++#define RX_VLAN_TAG (1 << 16) ++ ++ __le32 opts4; ++ __le32 opts5; ++ __le32 opts6; ++}; ++ ++struct tx_desc { ++ __le32 opts1; ++#define TX_FS (1 << 31) /* First segment of a packet */ ++#define TX_LS (1 << 30) /* Final segment of a packet */ ++#define GTSENDV4 (1 << 28) ++#define GTSENDV6 (1 << 27) ++#define GTTCPHO_SHIFT 18 ++#define GTTCPHO_MAX 0x7fU ++#define TX_LEN_MAX 0x3ffffU ++ ++ __le32 opts2; ++#define UDP_CS (1 << 31) /* Calculate UDP/IP checksum */ ++#define TCP_CS (1 << 30) /* Calculate TCP/IP checksum */ ++#define IPV4_CS (1 << 29) /* Calculate IPv4 checksum */ ++#define IPV6_CS (1 << 28) /* Calculate IPv6 checksum */ ++#define MSS_SHIFT 17 ++#define MSS_MAX 0x7ffU ++#define TCPHO_SHIFT 17 ++#define TCPHO_MAX 0x7ffU ++#define TX_VLAN_TAG (1 << 16) ++}; ++ ++struct r8152; ++ ++struct rx_agg { ++ struct list_head list; ++ struct urb *urb; ++ struct r8152 *context; ++ void *buffer; ++ void *head; ++}; ++ ++struct tx_agg { ++ struct list_head list; ++ struct urb *urb; ++ struct r8152 *context; ++ void *buffer; ++ void *head; ++ u32 skb_num; ++ u32 skb_len; ++}; ++ ++struct r8152 { ++ unsigned long flags; ++ struct usb_device *udev; ++ struct tasklet_struct tl; ++ struct usb_interface *intf; ++ struct net_device *netdev; ++ struct urb *intr_urb; ++ struct tx_agg tx_info[RTL8152_MAX_TX]; ++ struct rx_agg rx_info[RTL8152_MAX_RX]; ++ struct list_head rx_done, tx_free; ++ struct sk_buff_head tx_queue; ++ spinlock_t rx_lock, tx_lock; ++ struct delayed_work schedule; ++ struct mii_if_info mii; ++ struct mutex control; /* use for hw setting */ ++ ++ struct rtl_ops { ++ void (*init)(struct r8152 *); ++ int (*enable)(struct r8152 *); ++ void (*disable)(struct r8152 *); ++ void (*up)(struct r8152 *); ++ void (*down)(struct r8152 *); ++ void (*unload)(struct r8152 *); ++ int (*eee_get)(struct r8152 *, struct ethtool_eee *); ++ int (*eee_set)(struct r8152 *, struct ethtool_eee *); ++ } __no_const rtl_ops; ++ ++ int intr_interval; ++ u32 saved_wolopts; ++ u32 msg_enable; ++ u32 tx_qlen; ++ u16 ocp_base; ++ u8 *intr_buff; ++ u8 version; ++ u8 speed; ++}; ++ ++enum rtl_version { ++ RTL_VER_UNKNOWN = 0, ++ RTL_VER_01, ++ RTL_VER_02, ++ RTL_VER_03, ++ RTL_VER_04, ++ RTL_VER_05, ++ RTL_VER_MAX ++}; ++ ++enum tx_csum_stat { ++ TX_CSUM_SUCCESS = 0, ++ TX_CSUM_TSO, ++ TX_CSUM_NONE ++}; ++ ++/* 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; ++static unsigned int agg_buf_sz = 16384; ++ ++#define RTL_LIMITED_TSO_SIZE (agg_buf_sz - sizeof(struct tx_desc) - \ ++ VLAN_ETH_HLEN - VLAN_HLEN) ++ ++static ++int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) ++{ ++ int ret; ++ void *tmp; ++ ++ tmp = kmalloc(size, GFP_KERNEL); ++ if (!tmp) ++ return -ENOMEM; ++ ++ ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), ++ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, ++ value, index, tmp, size, 500); ++ ++ memcpy(data, tmp, size); ++ kfree(tmp); ++ ++ return ret; ++} ++ ++static ++int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) ++{ ++ int ret; ++ void *tmp; ++ ++ tmp = kmemdup(data, size, GFP_KERNEL); ++ if (!tmp) ++ return -ENOMEM; ++ ++ ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), ++ RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, ++ value, index, tmp, size, 500); ++ ++ kfree(tmp); ++ ++ return ret; ++} ++ ++static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, ++ void *data, u16 type) ++{ ++ u16 limit = 64; ++ int ret = 0; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; ++ ++ /* both size and indix must be 4 bytes align */ ++ if ((size & 3) || !size || (index & 3) || !data) ++ return -EPERM; ++ ++ if ((u32)index + (u32)size > 0xffff) ++ return -EPERM; ++ ++ while (size) { ++ if (size > limit) { ++ ret = get_registers(tp, index, type, limit, data); ++ if (ret < 0) ++ break; ++ ++ index += limit; ++ data += limit; ++ size -= limit; ++ } else { ++ ret = get_registers(tp, index, type, size, data); ++ if (ret < 0) ++ break; ++ ++ index += size; ++ data += size; ++ size = 0; ++ break; ++ } ++ } ++ ++ return ret; ++} ++ ++static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, ++ u16 size, void *data, u16 type) ++{ ++ int ret; ++ u16 byteen_start, byteen_end, byen; ++ u16 limit = 512; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; ++ ++ /* both size and indix must be 4 bytes align */ ++ if ((size & 3) || !size || (index & 3) || !data) ++ return -EPERM; ++ ++ if ((u32)index + (u32)size > 0xffff) ++ return -EPERM; ++ ++ byteen_start = byteen & BYTE_EN_START_MASK; ++ byteen_end = byteen & BYTE_EN_END_MASK; ++ ++ byen = byteen_start | (byteen_start << 4); ++ ret = set_registers(tp, index, type | byen, 4, data); ++ if (ret < 0) ++ goto error1; ++ ++ index += 4; ++ data += 4; ++ size -= 4; ++ ++ if (size) { ++ size -= 4; ++ ++ while (size) { ++ if (size > limit) { ++ ret = set_registers(tp, index, ++ type | BYTE_EN_DWORD, ++ limit, data); ++ if (ret < 0) ++ goto error1; ++ ++ index += limit; ++ data += limit; ++ size -= limit; ++ } else { ++ ret = set_registers(tp, index, ++ type | BYTE_EN_DWORD, ++ size, data); ++ if (ret < 0) ++ goto error1; ++ ++ index += size; ++ data += size; ++ size = 0; ++ break; ++ } ++ } ++ ++ byen = byteen_end | (byteen_end >> 4); ++ ret = set_registers(tp, index, type | byen, 4, data); ++ if (ret < 0) ++ goto error1; ++ } ++ ++error1: ++ return ret; ++} ++ ++static inline ++int pla_ocp_read(struct r8152 *tp, u16 index, u16 size, void *data) ++{ ++ return generic_ocp_read(tp, index, size, data, MCU_TYPE_PLA); ++} ++ ++static inline ++int pla_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) ++{ ++ return generic_ocp_write(tp, index, byteen, size, data, MCU_TYPE_PLA); ++} ++ ++static inline ++int usb_ocp_read(struct r8152 *tp, u16 index, u16 size, void *data) ++{ ++ return generic_ocp_read(tp, index, size, data, MCU_TYPE_USB); ++} ++ ++static inline ++int usb_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) ++{ ++ return generic_ocp_write(tp, index, byteen, size, data, MCU_TYPE_USB); ++} ++ ++static u32 ocp_read_dword(struct r8152 *tp, u16 type, u16 index) ++{ ++ __le32 data; ++ ++ generic_ocp_read(tp, index, sizeof(data), &data, type); ++ ++ return __le32_to_cpu(data); ++} ++ ++static void ocp_write_dword(struct r8152 *tp, u16 type, u16 index, u32 data) ++{ ++ __le32 tmp = __cpu_to_le32(data); ++ ++ generic_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(tmp), &tmp, type); ++} ++ ++static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) ++{ ++ u32 data; ++ __le32 tmp; ++ u8 shift = index & 2; ++ ++ index &= ~3; ++ ++ generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); ++ ++ data = __le32_to_cpu(tmp); ++ data >>= (shift * 8); ++ data &= 0xffff; ++ ++ return (u16)data; ++} ++ ++static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) ++{ ++ u32 mask = 0xffff; ++ __le32 tmp; ++ u16 byen = BYTE_EN_WORD; ++ u8 shift = index & 2; ++ ++ data &= mask; ++ ++ if (index & 2) { ++ byen <<= shift; ++ mask <<= (shift * 8); ++ data <<= (shift * 8); ++ index &= ~3; ++ } ++ ++ generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); ++ ++ data |= __le32_to_cpu(tmp) & ~mask; ++ tmp = __cpu_to_le32(data); ++ ++ generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); ++} ++ ++static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) ++{ ++ u32 data; ++ __le32 tmp; ++ u8 shift = index & 3; ++ ++ index &= ~3; ++ ++ generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); ++ ++ data = __le32_to_cpu(tmp); ++ data >>= (shift * 8); ++ data &= 0xff; ++ ++ return (u8)data; ++} ++ ++static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) ++{ ++ u32 mask = 0xff; ++ __le32 tmp; ++ u16 byen = BYTE_EN_BYTE; ++ u8 shift = index & 3; ++ ++ data &= mask; ++ ++ if (index & 3) { ++ byen <<= shift; ++ mask <<= (shift * 8); ++ data <<= (shift * 8); ++ index &= ~3; ++ } ++ ++ generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); ++ ++ data |= __le32_to_cpu(tmp) & ~mask; ++ tmp = __cpu_to_le32(data); ++ ++ generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); ++} ++ ++static u16 ocp_reg_read(struct r8152 *tp, u16 addr) ++{ ++ u16 ocp_base, ocp_index; ++ ++ ocp_base = addr & 0xf000; ++ if (ocp_base != tp->ocp_base) { ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, ocp_base); ++ tp->ocp_base = ocp_base; ++ } ++ ++ ocp_index = (addr & 0x0fff) | 0xb000; ++ return ocp_read_word(tp, MCU_TYPE_PLA, ocp_index); ++} ++ ++static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) ++{ ++ u16 ocp_base, ocp_index; ++ ++ ocp_base = addr & 0xf000; ++ if (ocp_base != tp->ocp_base) { ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, ocp_base); ++ tp->ocp_base = ocp_base; ++ } ++ ++ ocp_index = (addr & 0x0fff) | 0xb000; ++ ocp_write_word(tp, MCU_TYPE_PLA, ocp_index, data); ++} ++ ++static inline void r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 value) ++{ ++ ocp_reg_write(tp, OCP_BASE_MII + reg_addr * 2, value); ++} ++ ++static inline int r8152_mdio_read(struct r8152 *tp, u32 reg_addr) ++{ ++ return ocp_reg_read(tp, OCP_BASE_MII + reg_addr * 2); ++} ++ ++static void sram_write(struct r8152 *tp, u16 addr, u16 data) ++{ ++ ocp_reg_write(tp, OCP_SRAM_ADDR, addr); ++ ocp_reg_write(tp, OCP_SRAM_DATA, data); ++} ++ ++static u16 sram_read(struct r8152 *tp, u16 addr) ++{ ++ ocp_reg_write(tp, OCP_SRAM_ADDR, addr); ++ return ocp_reg_read(tp, OCP_SRAM_DATA); ++} ++ ++static int read_mii_word(struct net_device *netdev, int phy_id, int reg) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ int ret; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; ++ ++ if (phy_id != R8152_PHY_ID) ++ return -EINVAL; ++ ++ ret = r8152_mdio_read(tp, reg); ++ ++ return ret; ++} ++ ++static ++void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ if (phy_id != R8152_PHY_ID) ++ return; ++ ++ r8152_mdio_write(tp, reg, val); ++} ++ ++static int ++r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags); ++ ++static int rtl8152_set_mac_address(struct net_device *netdev, void *p) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ struct sockaddr *addr = p; ++ int ret = -EADDRNOTAVAIL; ++ ++ if (!is_valid_ether_addr(addr->sa_data)) ++ goto out1; ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out1; ++ ++ mutex_lock(&tp->control); ++ ++ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); ++ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); ++ pla_ocp_write(tp, PLA_IDR, BYTE_EN_SIX_BYTES, 8, addr->sa_data); ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++out1: ++ return ret; ++} ++ ++static int set_ethernet_addr(struct r8152 *tp) ++{ ++ struct net_device *dev = tp->netdev; ++ struct sockaddr sa; ++ int ret; ++ ++ if (tp->version == RTL_VER_01) ++ ret = pla_ocp_read(tp, PLA_IDR, 8, sa.sa_data); ++ else ++ ret = pla_ocp_read(tp, PLA_BACKUP, 8, sa.sa_data); ++ ++ if (ret < 0) { ++ netif_err(tp, probe, dev, "Get ether addr fail\n"); ++ } else if (!is_valid_ether_addr(sa.sa_data)) { ++ netif_err(tp, probe, dev, "Invalid ether addr %pM\n", ++ sa.sa_data); ++ eth_hw_addr_random(dev); ++ ether_addr_copy(sa.sa_data, dev->dev_addr); ++ ret = rtl8152_set_mac_address(dev, &sa); ++ netif_info(tp, probe, dev, "Random ether addr %pM\n", ++ sa.sa_data); ++ } else { ++ if (tp->version == RTL_VER_01) ++ ether_addr_copy(dev->dev_addr, sa.sa_data); ++ else ++ ret = rtl8152_set_mac_address(dev, &sa); ++ } ++ ++ return ret; ++} ++ ++static void read_bulk_callback(struct urb *urb) ++{ ++ struct net_device *netdev; ++ int status = urb->status; ++ struct rx_agg *agg; ++ struct r8152 *tp; ++ int result; ++ ++ agg = urb->context; ++ if (!agg) ++ return; ++ ++ tp = agg->context; ++ if (!tp) ++ return; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ if (!test_bit(WORK_ENABLE, &tp->flags)) ++ return; ++ ++ netdev = tp->netdev; ++ ++ /* When link down, the driver would cancel all bulks. */ ++ /* This avoid the re-submitting bulk */ ++ if (!netif_carrier_ok(netdev)) ++ return; ++ ++ usb_mark_last_busy(tp->udev); ++ ++ switch (status) { ++ case 0: ++ if (urb->actual_length < ETH_ZLEN) ++ break; ++ ++ spin_lock(&tp->rx_lock); ++ list_add_tail(&agg->list, &tp->rx_done); ++ spin_unlock(&tp->rx_lock); ++ tasklet_schedule(&tp->tl); ++ return; ++ case -ESHUTDOWN: ++ set_bit(RTL8152_UNPLUG, &tp->flags); ++ netif_device_detach(tp->netdev); ++ return; ++ case -ENOENT: ++ return; /* the urb is in unlink state */ ++ case -ETIME: ++ if (net_ratelimit()) ++ netdev_warn(netdev, "maybe reset is needed?\n"); ++ break; ++ default: ++ if (net_ratelimit()) ++ netdev_warn(netdev, "Rx status %d\n", status); ++ break; ++ } ++ ++ result = r8152_submit_rx(tp, agg, GFP_ATOMIC); ++ if (result == -ENODEV) { ++ netif_device_detach(tp->netdev); ++ } else if (result) { ++ spin_lock(&tp->rx_lock); ++ list_add_tail(&agg->list, &tp->rx_done); ++ spin_unlock(&tp->rx_lock); ++ tasklet_schedule(&tp->tl); ++ } ++} ++ ++static void write_bulk_callback(struct urb *urb) ++{ ++ struct net_device_stats *stats; ++ struct net_device *netdev; ++ struct tx_agg *agg; ++ struct r8152 *tp; ++ int status = urb->status; ++ ++ agg = urb->context; ++ if (!agg) ++ return; ++ ++ tp = agg->context; ++ if (!tp) ++ return; ++ ++ netdev = tp->netdev; ++ stats = &netdev->stats; ++ if (status) { ++ if (net_ratelimit()) ++ netdev_warn(netdev, "Tx status %d\n", status); ++ stats->tx_errors += agg->skb_num; ++ } else { ++ stats->tx_packets += agg->skb_num; ++ stats->tx_bytes += agg->skb_len; ++ } ++ ++ spin_lock(&tp->tx_lock); ++ list_add_tail(&agg->list, &tp->tx_free); ++ spin_unlock(&tp->tx_lock); ++ ++ usb_autopm_put_interface_async(tp->intf); ++ ++ if (!netif_carrier_ok(netdev)) ++ return; ++ ++ if (!test_bit(WORK_ENABLE, &tp->flags)) ++ return; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ if (!skb_queue_empty(&tp->tx_queue)) ++ tasklet_schedule(&tp->tl); ++} ++ ++static void intr_callback(struct urb *urb) ++{ ++ struct r8152 *tp; ++ __le16 *d; ++ int status = urb->status; ++ int res; ++ ++ tp = urb->context; ++ if (!tp) ++ return; ++ ++ if (!test_bit(WORK_ENABLE, &tp->flags)) ++ return; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ switch (status) { ++ case 0: /* success */ ++ break; ++ case -ECONNRESET: /* unlink */ ++ case -ESHUTDOWN: ++ netif_device_detach(tp->netdev); ++ case -ENOENT: ++ case -EPROTO: ++ netif_info(tp, intr, tp->netdev, ++ "Stop submitting intr, status %d\n", status); ++ return; ++ case -EOVERFLOW: ++ netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n"); ++ goto resubmit; ++ /* -EPIPE: should clear the halt */ ++ default: ++ netif_info(tp, intr, tp->netdev, "intr status %d\n", status); ++ goto resubmit; ++ } ++ ++ d = urb->transfer_buffer; ++ if (INTR_LINK & __le16_to_cpu(d[0])) { ++ if (!(tp->speed & LINK_STATUS)) { ++ set_bit(RTL8152_LINK_CHG, &tp->flags); ++ schedule_delayed_work(&tp->schedule, 0); ++ } ++ } else { ++ if (tp->speed & LINK_STATUS) { ++ set_bit(RTL8152_LINK_CHG, &tp->flags); ++ schedule_delayed_work(&tp->schedule, 0); ++ } ++ } ++ ++resubmit: ++ res = usb_submit_urb(urb, GFP_ATOMIC); ++ if (res == -ENODEV) ++ netif_device_detach(tp->netdev); ++ else if (res) ++ netif_err(tp, intr, tp->netdev, ++ "can't resubmit intr, status %d\n", res); ++} ++ ++static inline void *rx_agg_align(void *data) ++{ ++ return (void *)ALIGN((uintptr_t)data, RX_ALIGN); ++} ++ ++static inline void *tx_agg_align(void *data) ++{ ++ return (void *)ALIGN((uintptr_t)data, TX_ALIGN); ++} ++ ++static void free_all_mem(struct r8152 *tp) ++{ ++ int i; ++ ++ for (i = 0; i < RTL8152_MAX_RX; i++) { ++ usb_free_urb(tp->rx_info[i].urb); ++ tp->rx_info[i].urb = NULL; ++ ++ kfree(tp->rx_info[i].buffer); ++ tp->rx_info[i].buffer = NULL; ++ tp->rx_info[i].head = NULL; ++ } ++ ++ for (i = 0; i < RTL8152_MAX_TX; i++) { ++ usb_free_urb(tp->tx_info[i].urb); ++ tp->tx_info[i].urb = NULL; ++ ++ kfree(tp->tx_info[i].buffer); ++ tp->tx_info[i].buffer = NULL; ++ tp->tx_info[i].head = NULL; ++ } ++ ++ usb_free_urb(tp->intr_urb); ++ tp->intr_urb = NULL; ++ ++ kfree(tp->intr_buff); ++ tp->intr_buff = NULL; ++} ++ ++static int alloc_all_mem(struct r8152 *tp) ++{ ++ struct net_device *netdev = tp->netdev; ++ struct usb_interface *intf = tp->intf; ++ struct usb_host_interface *alt = intf->cur_altsetting; ++ struct usb_host_endpoint *ep_intr = alt->endpoint + 2; ++ struct urb *urb; ++ int node, i; ++ u8 *buf; ++ ++ node = netdev->dev.parent ? dev_to_node(netdev->dev.parent) : -1; ++ ++ spin_lock_init(&tp->rx_lock); ++ spin_lock_init(&tp->tx_lock); ++ INIT_LIST_HEAD(&tp->rx_done); ++ INIT_LIST_HEAD(&tp->tx_free); ++ skb_queue_head_init(&tp->tx_queue); ++ ++ for (i = 0; i < RTL8152_MAX_RX; i++) { ++ buf = kmalloc_node(agg_buf_sz, GFP_KERNEL, node); ++ if (!buf) ++ goto err1; ++ ++ if (buf != rx_agg_align(buf)) { ++ kfree(buf); ++ buf = kmalloc_node(agg_buf_sz + RX_ALIGN, GFP_KERNEL, ++ node); ++ if (!buf) ++ goto err1; ++ } ++ ++ urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!urb) { ++ kfree(buf); ++ goto err1; ++ } ++ ++ INIT_LIST_HEAD(&tp->rx_info[i].list); ++ tp->rx_info[i].context = tp; ++ tp->rx_info[i].urb = urb; ++ tp->rx_info[i].buffer = buf; ++ tp->rx_info[i].head = rx_agg_align(buf); ++ } ++ ++ for (i = 0; i < RTL8152_MAX_TX; i++) { ++ buf = kmalloc_node(agg_buf_sz, GFP_KERNEL, node); ++ if (!buf) ++ goto err1; ++ ++ if (buf != tx_agg_align(buf)) { ++ kfree(buf); ++ buf = kmalloc_node(agg_buf_sz + TX_ALIGN, GFP_KERNEL, ++ node); ++ if (!buf) ++ goto err1; ++ } ++ ++ urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!urb) { ++ kfree(buf); ++ goto err1; ++ } ++ ++ INIT_LIST_HEAD(&tp->tx_info[i].list); ++ tp->tx_info[i].context = tp; ++ tp->tx_info[i].urb = urb; ++ tp->tx_info[i].buffer = buf; ++ tp->tx_info[i].head = tx_agg_align(buf); ++ ++ list_add_tail(&tp->tx_info[i].list, &tp->tx_free); ++ } ++ ++ tp->intr_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!tp->intr_urb) ++ goto err1; ++ ++ tp->intr_buff = kmalloc(INTBUFSIZE, GFP_KERNEL); ++ if (!tp->intr_buff) ++ goto err1; ++ ++ tp->intr_interval = (int)ep_intr->desc.bInterval; ++ usb_fill_int_urb(tp->intr_urb, tp->udev, usb_rcvintpipe(tp->udev, 3), ++ tp->intr_buff, INTBUFSIZE, intr_callback, ++ tp, tp->intr_interval); ++ ++ return 0; ++ ++err1: ++ free_all_mem(tp); ++ return -ENOMEM; ++} ++ ++static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp) ++{ ++ struct tx_agg *agg = NULL; ++ unsigned long flags; ++ ++ if (list_empty(&tp->tx_free)) ++ return NULL; ++ ++ spin_lock_irqsave(&tp->tx_lock, flags); ++ if (!list_empty(&tp->tx_free)) { ++ struct list_head *cursor; ++ ++ cursor = tp->tx_free.next; ++ list_del_init(cursor); ++ agg = list_entry(cursor, struct tx_agg, list); ++ } ++ spin_unlock_irqrestore(&tp->tx_lock, flags); ++ ++ return agg; ++} ++ ++static inline __be16 get_protocol(struct sk_buff *skb) ++{ ++ __be16 protocol; ++ ++ if (skb->protocol == htons(ETH_P_8021Q)) ++ protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; ++ else ++ protocol = skb->protocol; ++ ++ return protocol; ++} ++ ++/* r8152_csum_workaround() ++ * The hw limites the value the transport offset. When the offset is out of the ++ * range, calculate the checksum by sw. ++ */ ++static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb, ++ struct sk_buff_head *list) ++{ ++ if (skb_shinfo(skb)->gso_size) { ++ netdev_features_t features = tp->netdev->features; ++ struct sk_buff_head seg_list; ++ struct sk_buff *segs, *nskb; ++ ++ features &= ~(NETIF_F_SG | NETIF_F_IPV6_CSUM | NETIF_F_TSO6); ++ segs = skb_gso_segment(skb, features); ++ if (IS_ERR(segs) || !segs) ++ goto drop; ++ ++ __skb_queue_head_init(&seg_list); ++ ++ do { ++ nskb = segs; ++ segs = segs->next; ++ nskb->next = NULL; ++ __skb_queue_tail(&seg_list, nskb); ++ } while (segs); ++ ++ skb_queue_splice(&seg_list, list); ++ dev_kfree_skb(skb); ++ } else if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ if (skb_checksum_help(skb) < 0) ++ goto drop; ++ ++ __skb_queue_head(list, skb); ++ } else { ++ struct net_device_stats *stats; ++ ++drop: ++ stats = &tp->netdev->stats; ++ stats->tx_dropped++; ++ dev_kfree_skb(skb); ++ } ++} ++ ++/* msdn_giant_send_check() ++ * According to the document of microsoft, the TCP Pseudo Header excludes the ++ * packet length for IPv6 TCP large packets. ++ */ ++static int msdn_giant_send_check(struct sk_buff *skb) ++{ ++ const struct ipv6hdr *ipv6h; ++ struct tcphdr *th; ++ int ret; ++ ++ ret = skb_cow_head(skb, 0); ++ if (ret) ++ return ret; ++ ++ ipv6h = ipv6_hdr(skb); ++ th = tcp_hdr(skb); ++ ++ th->check = 0; ++ th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0); ++ ++ return ret; ++} ++ ++static inline void rtl_tx_vlan_tag(struct tx_desc *desc, struct sk_buff *skb) ++{ ++ if (vlan_tx_tag_present(skb)) { ++ u32 opts2; ++ ++ opts2 = TX_VLAN_TAG | swab16(vlan_tx_tag_get(skb)); ++ desc->opts2 |= cpu_to_le32(opts2); ++ } ++} ++ ++static inline void rtl_rx_vlan_tag(struct rx_desc *desc, struct sk_buff *skb) ++{ ++ u32 opts2 = le32_to_cpu(desc->opts2); ++ ++ if (opts2 & RX_VLAN_TAG) ++ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ++ swab16(opts2 & 0xffff)); ++} ++ ++static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, ++ struct sk_buff *skb, u32 len, u32 transport_offset) ++{ ++ u32 mss = skb_shinfo(skb)->gso_size; ++ u32 opts1, opts2 = 0; ++ int ret = TX_CSUM_SUCCESS; ++ ++ WARN_ON_ONCE(len > TX_LEN_MAX); ++ ++ opts1 = len | TX_FS | TX_LS; ++ ++ if (mss) { ++ if (transport_offset > GTTCPHO_MAX) { ++ netif_warn(tp, tx_err, tp->netdev, ++ "Invalid transport offset 0x%x for TSO\n", ++ transport_offset); ++ ret = TX_CSUM_TSO; ++ goto unavailable; ++ } ++ ++ switch (get_protocol(skb)) { ++ case htons(ETH_P_IP): ++ opts1 |= GTSENDV4; ++ break; ++ ++ case htons(ETH_P_IPV6): ++ if (msdn_giant_send_check(skb)) { ++ ret = TX_CSUM_TSO; ++ goto unavailable; ++ } ++ opts1 |= GTSENDV6; ++ break; ++ ++ default: ++ WARN_ON_ONCE(1); ++ break; ++ } ++ ++ opts1 |= transport_offset << GTTCPHO_SHIFT; ++ opts2 |= min(mss, MSS_MAX) << MSS_SHIFT; ++ } else if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ u8 ip_protocol; ++ ++ if (transport_offset > TCPHO_MAX) { ++ netif_warn(tp, tx_err, tp->netdev, ++ "Invalid transport offset 0x%x\n", ++ transport_offset); ++ ret = TX_CSUM_NONE; ++ goto unavailable; ++ } ++ ++ switch (get_protocol(skb)) { ++ case htons(ETH_P_IP): ++ opts2 |= IPV4_CS; ++ ip_protocol = ip_hdr(skb)->protocol; ++ break; ++ ++ case htons(ETH_P_IPV6): ++ opts2 |= IPV6_CS; ++ ip_protocol = ipv6_hdr(skb)->nexthdr; ++ break; ++ ++ default: ++ ip_protocol = IPPROTO_RAW; ++ break; ++ } ++ ++ if (ip_protocol == IPPROTO_TCP) ++ opts2 |= TCP_CS; ++ else if (ip_protocol == IPPROTO_UDP) ++ opts2 |= UDP_CS; ++ else ++ WARN_ON_ONCE(1); ++ ++ opts2 |= transport_offset << TCPHO_SHIFT; ++ } ++ ++ desc->opts2 = cpu_to_le32(opts2); ++ desc->opts1 = cpu_to_le32(opts1); ++ ++unavailable: ++ return ret; ++} ++ ++static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) ++{ ++ struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue; ++ int remain, ret; ++ u8 *tx_data; ++ ++ __skb_queue_head_init(&skb_head); ++ spin_lock(&tx_queue->lock); ++ skb_queue_splice_init(tx_queue, &skb_head); ++ spin_unlock(&tx_queue->lock); ++ ++ tx_data = agg->head; ++ agg->skb_num = 0; ++ agg->skb_len = 0; ++ remain = agg_buf_sz; ++ ++ while (remain >= ETH_ZLEN + sizeof(struct tx_desc)) { ++ struct tx_desc *tx_desc; ++ struct sk_buff *skb; ++ unsigned int len; ++ u32 offset; ++ ++ skb = __skb_dequeue(&skb_head); ++ if (!skb) ++ break; ++ ++ len = skb->len + sizeof(*tx_desc); ++ ++ if (len > remain) { ++ __skb_queue_head(&skb_head, skb); ++ break; ++ } ++ ++ tx_data = tx_agg_align(tx_data); ++ tx_desc = (struct tx_desc *)tx_data; ++ ++ offset = (u32)skb_transport_offset(skb); ++ ++ if (r8152_tx_csum(tp, tx_desc, skb, skb->len, offset)) { ++ r8152_csum_workaround(tp, skb, &skb_head); ++ continue; ++ } ++ ++ rtl_tx_vlan_tag(tx_desc, skb); ++ ++ tx_data += sizeof(*tx_desc); ++ ++ len = skb->len; ++ if (skb_copy_bits(skb, 0, tx_data, len) < 0) { ++ struct net_device_stats *stats = &tp->netdev->stats; ++ ++ stats->tx_dropped++; ++ dev_kfree_skb_any(skb); ++ tx_data -= sizeof(*tx_desc); ++ continue; ++ } ++ ++ tx_data += len; ++ agg->skb_len += len; ++ agg->skb_num++; ++ ++ dev_kfree_skb_any(skb); ++ ++ remain = agg_buf_sz - (int)(tx_agg_align(tx_data) - agg->head); ++ } ++ ++ if (!skb_queue_empty(&skb_head)) { ++ spin_lock(&tx_queue->lock); ++ skb_queue_splice(&skb_head, tx_queue); ++ spin_unlock(&tx_queue->lock); ++ } ++ ++ netif_tx_lock(tp->netdev); ++ ++ if (netif_queue_stopped(tp->netdev) && ++ skb_queue_len(&tp->tx_queue) < tp->tx_qlen) ++ netif_wake_queue(tp->netdev); ++ ++ netif_tx_unlock(tp->netdev); ++ ++ ret = usb_autopm_get_interface_async(tp->intf); ++ if (ret < 0) ++ goto out_tx_fill; ++ ++ usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2), ++ agg->head, (int)(tx_data - (u8 *)agg->head), ++ (usb_complete_t)write_bulk_callback, agg); ++ ++ ret = usb_submit_urb(agg->urb, GFP_ATOMIC); ++ if (ret < 0) ++ usb_autopm_put_interface_async(tp->intf); ++ ++out_tx_fill: ++ return ret; ++} ++ ++static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc) ++{ ++ u8 checksum = CHECKSUM_NONE; ++ u32 opts2, opts3; ++ ++ if (tp->version == RTL_VER_01) ++ goto return_result; ++ ++ opts2 = le32_to_cpu(rx_desc->opts2); ++ opts3 = le32_to_cpu(rx_desc->opts3); ++ ++ if (opts2 & RD_IPV4_CS) { ++ if (opts3 & IPF) ++ checksum = CHECKSUM_NONE; ++ else if ((opts2 & RD_UDP_CS) && (opts3 & UDPF)) ++ checksum = CHECKSUM_NONE; ++ else if ((opts2 & RD_TCP_CS) && (opts3 & TCPF)) ++ checksum = CHECKSUM_NONE; ++ else ++ checksum = CHECKSUM_UNNECESSARY; ++ } else if (RD_IPV6_CS) { ++ if ((opts2 & RD_UDP_CS) && !(opts3 & UDPF)) ++ checksum = CHECKSUM_UNNECESSARY; ++ else if ((opts2 & RD_TCP_CS) && !(opts3 & TCPF)) ++ checksum = CHECKSUM_UNNECESSARY; ++ } ++ ++return_result: ++ return checksum; ++} ++ ++static void rx_bottom(struct r8152 *tp) ++{ ++ unsigned long flags; ++ struct list_head *cursor, *next, rx_queue; ++ ++ if (list_empty(&tp->rx_done)) ++ return; ++ ++ INIT_LIST_HEAD(&rx_queue); ++ spin_lock_irqsave(&tp->rx_lock, flags); ++ list_splice_init(&tp->rx_done, &rx_queue); ++ spin_unlock_irqrestore(&tp->rx_lock, flags); ++ ++ list_for_each_safe(cursor, next, &rx_queue) { ++ struct rx_desc *rx_desc; ++ struct rx_agg *agg; ++ int len_used = 0; ++ struct urb *urb; ++ u8 *rx_data; ++ int ret; ++ ++ list_del_init(cursor); ++ ++ agg = list_entry(cursor, struct rx_agg, list); ++ urb = agg->urb; ++ if (urb->actual_length < ETH_ZLEN) ++ goto submit; ++ ++ rx_desc = agg->head; ++ rx_data = agg->head; ++ len_used += sizeof(struct rx_desc); ++ ++ while (urb->actual_length > len_used) { ++ struct net_device *netdev = tp->netdev; ++ struct net_device_stats *stats = &netdev->stats; ++ unsigned int pkt_len; ++ struct sk_buff *skb; ++ ++ pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK; ++ if (pkt_len < ETH_ZLEN) ++ break; ++ ++ len_used += pkt_len; ++ if (urb->actual_length < len_used) ++ break; ++ ++ pkt_len -= CRC_SIZE; ++ rx_data += sizeof(struct rx_desc); ++ ++ skb = netdev_alloc_skb_ip_align(netdev, pkt_len); ++ if (!skb) { ++ stats->rx_dropped++; ++ goto find_next_rx; ++ } ++ ++ skb->ip_summed = r8152_rx_csum(tp, rx_desc); ++ memcpy(skb->data, rx_data, pkt_len); ++ skb_put(skb, pkt_len); ++ skb->protocol = eth_type_trans(skb, netdev); ++ rtl_rx_vlan_tag(rx_desc, skb); ++ netif_receive_skb(skb); ++ stats->rx_packets++; ++ stats->rx_bytes += pkt_len; ++ ++find_next_rx: ++ rx_data = rx_agg_align(rx_data + pkt_len + CRC_SIZE); ++ rx_desc = (struct rx_desc *)rx_data; ++ len_used = (int)(rx_data - (u8 *)agg->head); ++ len_used += sizeof(struct rx_desc); ++ } ++ ++submit: ++ ret = r8152_submit_rx(tp, agg, GFP_ATOMIC); ++ if (ret && ret != -ENODEV) { ++ spin_lock_irqsave(&tp->rx_lock, flags); ++ list_add_tail(&agg->list, &tp->rx_done); ++ spin_unlock_irqrestore(&tp->rx_lock, flags); ++ tasklet_schedule(&tp->tl); ++ } ++ } ++} ++ ++static void tx_bottom(struct r8152 *tp) ++{ ++ int res; ++ ++ do { ++ struct tx_agg *agg; ++ ++ if (skb_queue_empty(&tp->tx_queue)) ++ break; ++ ++ agg = r8152_get_tx_agg(tp); ++ if (!agg) ++ break; ++ ++ res = r8152_tx_agg_fill(tp, agg); ++ if (res) { ++ struct net_device *netdev = tp->netdev; ++ ++ if (res == -ENODEV) { ++ netif_device_detach(netdev); ++ } else { ++ struct net_device_stats *stats = &netdev->stats; ++ unsigned long flags; ++ ++ netif_warn(tp, tx_err, netdev, ++ "failed tx_urb %d\n", res); ++ stats->tx_dropped += agg->skb_num; ++ ++ spin_lock_irqsave(&tp->tx_lock, flags); ++ list_add_tail(&agg->list, &tp->tx_free); ++ spin_unlock_irqrestore(&tp->tx_lock, flags); ++ } ++ } ++ } while (res == 0); ++} ++ ++static void bottom_half(unsigned long data) ++{ ++ struct r8152 *tp; ++ ++ tp = (struct r8152 *)data; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ if (!test_bit(WORK_ENABLE, &tp->flags)) ++ return; ++ ++ /* When link down, the driver would cancel all bulks. */ ++ /* This avoid the re-submitting bulk */ ++ if (!netif_carrier_ok(tp->netdev)) ++ return; ++ ++ rx_bottom(tp); ++ tx_bottom(tp); ++} ++ ++static ++int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) ++{ ++ usb_fill_bulk_urb(agg->urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1), ++ agg->head, agg_buf_sz, ++ (usb_complete_t)read_bulk_callback, agg); ++ ++ return usb_submit_urb(agg->urb, mem_flags); ++} ++ ++static void rtl_drop_queued_tx(struct r8152 *tp) ++{ ++ struct net_device_stats *stats = &tp->netdev->stats; ++ struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue; ++ struct sk_buff *skb; ++ ++ if (skb_queue_empty(tx_queue)) ++ return; ++ ++ __skb_queue_head_init(&skb_head); ++ spin_lock_bh(&tx_queue->lock); ++ skb_queue_splice_init(tx_queue, &skb_head); ++ spin_unlock_bh(&tx_queue->lock); ++ ++ while ((skb = __skb_dequeue(&skb_head))) { ++ dev_kfree_skb(skb); ++ stats->tx_dropped++; ++ } ++} ++ ++static void rtl8152_tx_timeout(struct net_device *netdev) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ int i; ++ ++ netif_warn(tp, tx_err, netdev, "Tx timeout\n"); ++ for (i = 0; i < RTL8152_MAX_TX; i++) ++ usb_unlink_urb(tp->tx_info[i].urb); ++} ++ ++static void rtl8152_set_rx_mode(struct net_device *netdev) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ ++ if (tp->speed & LINK_STATUS) { ++ set_bit(RTL8152_SET_RX_MODE, &tp->flags); ++ schedule_delayed_work(&tp->schedule, 0); ++ } ++} ++ ++static void _rtl8152_set_rx_mode(struct net_device *netdev) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ u32 mc_filter[2]; /* Multicast hash filter */ ++ __le32 tmp[2]; ++ u32 ocp_data; ++ ++ clear_bit(RTL8152_SET_RX_MODE, &tp->flags); ++ netif_stop_queue(netdev); ++ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ++ ocp_data &= ~RCR_ACPT_ALL; ++ ocp_data |= RCR_AB | RCR_APM; ++ ++ if (netdev->flags & IFF_PROMISC) { ++ /* Unconditionally log net taps. */ ++ netif_notice(tp, link, netdev, "Promiscuous mode enabled\n"); ++ ocp_data |= RCR_AM | RCR_AAP; ++ mc_filter[1] = 0xffffffff; ++ mc_filter[0] = 0xffffffff; ++ } else if ((netdev_mc_count(netdev) > multicast_filter_limit) || ++ (netdev->flags & IFF_ALLMULTI)) { ++ /* Too many to filter perfectly -- accept all multicasts. */ ++ ocp_data |= RCR_AM; ++ mc_filter[1] = 0xffffffff; ++ mc_filter[0] = 0xffffffff; ++ } else { ++ struct netdev_hw_addr *ha; ++ ++ mc_filter[1] = 0; ++ mc_filter[0] = 0; ++ netdev_for_each_mc_addr(ha, netdev) { ++ int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; ++ ++ mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); ++ ocp_data |= RCR_AM; ++ } ++ } ++ ++ tmp[0] = __cpu_to_le32(swab32(mc_filter[1])); ++ tmp[1] = __cpu_to_le32(swab32(mc_filter[0])); ++ ++ pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(tmp), tmp); ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ netif_wake_queue(netdev); ++} ++ ++static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, ++ struct net_device *netdev) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ ++ skb_tx_timestamp(skb); ++ ++ skb_queue_tail(&tp->tx_queue, skb); ++ ++ if (!list_empty(&tp->tx_free)) { ++ if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { ++ set_bit(SCHEDULE_TASKLET, &tp->flags); ++ schedule_delayed_work(&tp->schedule, 0); ++ } else { ++ usb_mark_last_busy(tp->udev); ++ tasklet_schedule(&tp->tl); ++ } ++ } else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen) { ++ netif_stop_queue(netdev); ++ } ++ ++ return NETDEV_TX_OK; ++} ++ ++static void r8152b_reset_packet_filter(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_FMC); ++ ocp_data &= ~FMC_FCR_MCU_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_FMC, ocp_data); ++ ocp_data |= FMC_FCR_MCU_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_FMC, ocp_data); ++} ++ ++static void rtl8152_nic_reset(struct r8152 *tp) ++{ ++ int i; ++ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST); ++ ++ for (i = 0; i < 1000; i++) { ++ if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST)) ++ break; ++ usleep_range(100, 400); ++ } ++} ++ ++static void set_tx_qlen(struct r8152 *tp) ++{ ++ struct net_device *netdev = tp->netdev; ++ ++ tp->tx_qlen = agg_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + VLAN_HLEN + ++ sizeof(struct tx_desc)); ++} ++ ++static inline u8 rtl8152_get_speed(struct r8152 *tp) ++{ ++ return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS); ++} ++ ++static void rtl_set_eee_plus(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ u8 speed; ++ ++ speed = rtl8152_get_speed(tp); ++ if (speed & _10bps) { ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); ++ ocp_data |= EEEP_CR_EEEP_TX; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data); ++ } else { ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); ++ ocp_data &= ~EEEP_CR_EEEP_TX; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data); ++ } ++} ++ ++static void rxdy_gated_en(struct r8152 *tp, bool enable) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1); ++ if (enable) ++ ocp_data |= RXDY_GATED_EN; ++ else ++ ocp_data &= ~RXDY_GATED_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data); ++} ++ ++static int rtl_start_rx(struct r8152 *tp) ++{ ++ int i, ret = 0; ++ ++ INIT_LIST_HEAD(&tp->rx_done); ++ for (i = 0; i < RTL8152_MAX_RX; i++) { ++ INIT_LIST_HEAD(&tp->rx_info[i].list); ++ ret = r8152_submit_rx(tp, &tp->rx_info[i], GFP_KERNEL); ++ if (ret) ++ break; ++ } ++ ++ return ret; ++} ++ ++static int rtl_stop_rx(struct r8152 *tp) ++{ ++ int i; ++ ++ for (i = 0; i < RTL8152_MAX_RX; i++) ++ usb_kill_urb(tp->rx_info[i].urb); ++ ++ return 0; ++} ++ ++static int rtl_enable(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ ++ r8152b_reset_packet_filter(tp); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR); ++ ocp_data |= CR_RE | CR_TE; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); ++ ++ rxdy_gated_en(tp, false); ++ ++ return rtl_start_rx(tp); ++} ++ ++static int rtl8152_enable(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; ++ ++ set_tx_qlen(tp); ++ rtl_set_eee_plus(tp); ++ ++ return rtl_enable(tp); ++} ++ ++static void r8153_set_rx_agg(struct r8152 *tp) ++{ ++ u8 speed; ++ ++ speed = rtl8152_get_speed(tp); ++ if (speed & _1000bps) { ++ if (tp->udev->speed == USB_SPEED_SUPER) { ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, ++ RX_THR_SUPPER); ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG, ++ EARLY_AGG_SUPPER); ++ } else { ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, ++ RX_THR_HIGH); ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG, ++ EARLY_AGG_HIGH); ++ } ++ } else { ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_SLOW); ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG, ++ EARLY_AGG_SLOW); ++ } ++} ++ ++static int rtl8153_enable(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; ++ ++ set_tx_qlen(tp); ++ rtl_set_eee_plus(tp); ++ r8153_set_rx_agg(tp); ++ ++ return rtl_enable(tp); ++} ++ ++static void rtl_disable(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ int i; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ rtl_drop_queued_tx(tp); ++ return; ++ } ++ ++ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ++ ocp_data &= ~RCR_ACPT_ALL; ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ++ rtl_drop_queued_tx(tp); ++ ++ for (i = 0; i < RTL8152_MAX_TX; i++) ++ usb_kill_urb(tp->tx_info[i].urb); ++ ++ rxdy_gated_en(tp, true); ++ ++ for (i = 0; i < 1000; i++) { ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ if ((ocp_data & FIFO_EMPTY) == FIFO_EMPTY) ++ break; ++ usleep_range(1000, 2000); ++ } ++ ++ for (i = 0; i < 1000; i++) { ++ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0) & TCR0_TX_EMPTY) ++ break; ++ usleep_range(1000, 2000); ++ } ++ ++ rtl_stop_rx(tp); ++ ++ rtl8152_nic_reset(tp); ++} ++ ++static void r8152_power_cut_en(struct r8152 *tp, bool enable) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CTRL); ++ if (enable) ++ ocp_data |= POWER_CUT; ++ else ++ ocp_data &= ~POWER_CUT; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CTRL, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS); ++ ocp_data &= ~RESUME_INDICATE; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS, ocp_data); ++} ++ ++static void rtl_rx_vlan_en(struct r8152 *tp, bool enable) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR); ++ if (enable) ++ ocp_data |= CPCR_RX_VLAN; ++ else ++ ocp_data &= ~CPCR_RX_VLAN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data); ++} ++ ++static int rtl8152_set_features(struct net_device *dev, ++ netdev_features_t features) ++{ ++ netdev_features_t changed = features ^ dev->features; ++ struct r8152 *tp = netdev_priv(dev); ++ int ret; ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out; ++ ++ mutex_lock(&tp->control); ++ ++ if (changed & NETIF_F_HW_VLAN_CTAG_RX) { ++ if (features & NETIF_F_HW_VLAN_CTAG_RX) ++ rtl_rx_vlan_en(tp, true); ++ else ++ rtl_rx_vlan_en(tp, false); ++ } ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return ret; ++} ++ ++#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) ++ ++static u32 __rtl_get_wol(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ u32 wolopts = 0; ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG5); ++ if (!(ocp_data & LAN_WAKE_EN)) ++ return 0; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); ++ if (ocp_data & LINK_ON_WAKE_EN) ++ wolopts |= WAKE_PHY; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5); ++ if (ocp_data & UWF_EN) ++ wolopts |= WAKE_UCAST; ++ if (ocp_data & BWF_EN) ++ wolopts |= WAKE_BCAST; ++ if (ocp_data & MWF_EN) ++ wolopts |= WAKE_MCAST; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL); ++ if (ocp_data & MAGIC_EN) ++ wolopts |= WAKE_MAGIC; ++ ++ return wolopts; ++} ++ ++static void __rtl_set_wol(struct r8152 *tp, u32 wolopts) ++{ ++ u32 ocp_data; ++ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); ++ ocp_data &= ~LINK_ON_WAKE_EN; ++ if (wolopts & WAKE_PHY) ++ ocp_data |= LINK_ON_WAKE_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5); ++ ocp_data &= ~(UWF_EN | BWF_EN | MWF_EN | LAN_WAKE_EN); ++ if (wolopts & WAKE_UCAST) ++ ocp_data |= UWF_EN; ++ if (wolopts & WAKE_BCAST) ++ ocp_data |= BWF_EN; ++ if (wolopts & WAKE_MCAST) ++ ocp_data |= MWF_EN; ++ if (wolopts & WAKE_ANY) ++ ocp_data |= LAN_WAKE_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG5, ocp_data); ++ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL); ++ ocp_data &= ~MAGIC_EN; ++ if (wolopts & WAKE_MAGIC) ++ ocp_data |= MAGIC_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL, ocp_data); ++ ++ if (wolopts & WAKE_ANY) ++ device_set_wakeup_enable(&tp->udev->dev, true); ++ else ++ device_set_wakeup_enable(&tp->udev->dev, false); ++} ++ ++static void rtl_runtime_suspend_enable(struct r8152 *tp, bool enable) ++{ ++ if (enable) { ++ u32 ocp_data; ++ ++ __rtl_set_wol(tp, WAKE_ANY); ++ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34); ++ ocp_data |= LINK_OFF_WAKE_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data); ++ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); ++ } else { ++ __rtl_set_wol(tp, tp->saved_wolopts); ++ } ++} ++ ++static void rtl_phy_reset(struct r8152 *tp) ++{ ++ u16 data; ++ int i; ++ ++ clear_bit(PHY_RESET, &tp->flags); ++ ++ data = r8152_mdio_read(tp, MII_BMCR); ++ ++ /* don't reset again before the previous one complete */ ++ if (data & BMCR_RESET) ++ return; ++ ++ data |= BMCR_RESET; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ ++ for (i = 0; i < 50; i++) { ++ msleep(20); ++ if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0) ++ break; ++ } ++} ++ ++static void r8153_teredo_off(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG); ++ ocp_data &= ~(TEREDO_SEL | TEREDO_RS_EVENT_MASK | OOB_TEREDO_EN); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data); ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_WDT6_CTRL, WDT6_SET_MODE); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_REALWOW_TIMER, 0); ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TEREDO_TIMER, 0); ++} ++ ++static void r8152b_disable_aldps(struct r8152 *tp) ++{ ++ ocp_reg_write(tp, OCP_ALDPS_CONFIG, ENPDNPS | LINKENA | DIS_SDSAVE); ++ msleep(20); ++} ++ ++static inline void r8152b_enable_aldps(struct r8152 *tp) ++{ ++ ocp_reg_write(tp, OCP_ALDPS_CONFIG, ENPWRSAVE | ENPDNPS | ++ LINKENA | DIS_SDSAVE); ++} ++ ++static void rtl8152_disable(struct r8152 *tp) ++{ ++ r8152b_disable_aldps(tp); ++ rtl_disable(tp); ++ r8152b_enable_aldps(tp); ++} ++ ++static void r8152b_hw_phy_cfg(struct r8152 *tp) ++{ ++ u16 data; ++ ++ data = r8152_mdio_read(tp, MII_BMCR); ++ if (data & BMCR_PDOWN) { ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ } ++ ++ set_bit(PHY_RESET, &tp->flags); ++} ++ ++static void r8152b_exit_oob(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ int i; ++ ++ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ++ ocp_data &= ~RCR_ACPT_ALL; ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ++ rxdy_gated_en(tp, true); ++ r8153_teredo_off(tp); ++ r8152b_hw_phy_cfg(tp); ++ ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML); ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, 0x00); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ ocp_data &= ~NOW_IS_OOB; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ++ ocp_data &= ~MCU_BORW_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ++ for (i = 0; i < 1000; i++) { ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ if (ocp_data & LINK_LIST_READY) ++ break; ++ usleep_range(1000, 2000); ++ } ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ++ ocp_data |= RE_INIT_LL; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ++ for (i = 0; i < 1000; i++) { ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ if (ocp_data & LINK_LIST_READY) ++ break; ++ usleep_range(1000, 2000); ++ } ++ ++ rtl8152_nic_reset(tp); ++ ++ /* rx share fifo credit full threshold */ ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_NORMAL); ++ ++ if (tp->udev->speed == USB_SPEED_FULL || ++ tp->udev->speed == USB_SPEED_LOW) { ++ /* rx share fifo credit near full threshold */ ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, ++ RXFIFO_THR2_FULL); ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, ++ RXFIFO_THR3_FULL); ++ } else { ++ /* rx share fifo credit near full threshold */ ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, ++ RXFIFO_THR2_HIGH); ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, ++ RXFIFO_THR3_HIGH); ++ } ++ ++ /* TX share fifo free credit full threshold */ ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL); ++ ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_TX_AGG, TX_AGG_MAX_THRESHOLD); ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_HIGH); ++ ocp_write_dword(tp, MCU_TYPE_USB, USB_TX_DMA, ++ TEST_MODE_DISABLE | TX_SIZE_ADJUST1); ++ ++ rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0); ++ ocp_data |= TCR0_AUTO_FIFO; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR0, ocp_data); ++} ++ ++static void r8152b_enter_oob(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ int i; ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ ocp_data &= ~NOW_IS_OOB; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_OOB); ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_OOB); ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_OOB); ++ ++ rtl_disable(tp); ++ ++ for (i = 0; i < 1000; i++) { ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ if (ocp_data & LINK_LIST_READY) ++ break; ++ usleep_range(1000, 2000); ++ } ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ++ ocp_data |= RE_INIT_LL; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ++ for (i = 0; i < 1000; i++) { ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ if (ocp_data & LINK_LIST_READY) ++ break; ++ usleep_range(1000, 2000); ++ } ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); ++ ++ rtl_rx_vlan_en(tp, true); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PAL_BDC_CR); ++ ocp_data |= ALDPS_PROXY_MODE; ++ ocp_write_word(tp, MCU_TYPE_PLA, PAL_BDC_CR, ocp_data); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ++ rxdy_gated_en(tp, false); ++ ++ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ++ ocp_data |= RCR_APM | RCR_AM | RCR_AB; ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++} ++ ++static void r8153_hw_phy_cfg(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ u16 data; ++ ++ ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L); ++ data = r8152_mdio_read(tp, MII_BMCR); ++ if (data & BMCR_PDOWN) { ++ data &= ~BMCR_PDOWN; ++ r8152_mdio_write(tp, MII_BMCR, data); ++ } ++ ++ if (tp->version == RTL_VER_03) { ++ data = ocp_reg_read(tp, OCP_EEE_CFG); ++ data &= ~CTAP_SHORT_EN; ++ ocp_reg_write(tp, OCP_EEE_CFG, data); ++ } ++ ++ data = ocp_reg_read(tp, OCP_POWER_CFG); ++ data |= EEE_CLKDIV_EN; ++ ocp_reg_write(tp, OCP_POWER_CFG, data); ++ ++ data = ocp_reg_read(tp, OCP_DOWN_SPEED); ++ data |= EN_10M_BGOFF; ++ ocp_reg_write(tp, OCP_DOWN_SPEED, data); ++ data = ocp_reg_read(tp, OCP_POWER_CFG); ++ data |= EN_10M_PLLOFF; ++ ocp_reg_write(tp, OCP_POWER_CFG, data); ++ data = sram_read(tp, SRAM_IMPEDANCE); ++ data &= ~RX_DRIVING_MASK; ++ sram_write(tp, SRAM_IMPEDANCE, data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); ++ ocp_data |= PFM_PWM_SWITCH; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); ++ ++ data = sram_read(tp, SRAM_LPF_CFG); ++ data |= LPF_AUTO_TUNE; ++ sram_write(tp, SRAM_LPF_CFG, data); ++ ++ data = sram_read(tp, SRAM_10M_AMP1); ++ data |= GDAC_IB_UPALL; ++ sram_write(tp, SRAM_10M_AMP1, data); ++ data = sram_read(tp, SRAM_10M_AMP2); ++ data |= AMP_DN; ++ sram_write(tp, SRAM_10M_AMP2, data); ++ ++ set_bit(PHY_RESET, &tp->flags); ++} ++ ++static void r8153_u1u2en(struct r8152 *tp, bool enable) ++{ ++ u8 u1u2[8]; ++ ++ if (enable) ++ memset(u1u2, 0xff, sizeof(u1u2)); ++ else ++ memset(u1u2, 0x00, sizeof(u1u2)); ++ ++ usb_ocp_write(tp, USB_TOLERANCE, BYTE_EN_SIX_BYTES, sizeof(u1u2), u1u2); ++} ++ ++static void r8153_u2p3en(struct r8152 *tp, bool enable) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL); ++ if (enable) ++ ocp_data |= U2P3_ENABLE; ++ else ++ ocp_data &= ~U2P3_ENABLE; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data); ++} ++ ++static void r8153_power_cut_en(struct r8152 *tp, bool enable) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_POWER_CUT); ++ if (enable) ++ ocp_data |= PWR_EN | PHASE2_EN; ++ else ++ ocp_data &= ~(PWR_EN | PHASE2_EN); ++ ocp_write_word(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); ++ ocp_data &= ~PCUT_STATUS; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data); ++} ++ ++static void r8153_first_init(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ int i; ++ ++ rxdy_gated_en(tp, true); ++ r8153_teredo_off(tp); ++ ++ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ++ ocp_data &= ~RCR_ACPT_ALL; ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++ ++ r8153_hw_phy_cfg(tp); ++ ++ rtl8152_nic_reset(tp); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ ocp_data &= ~NOW_IS_OOB; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ++ ocp_data &= ~MCU_BORW_EN; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ++ for (i = 0; i < 1000; i++) { ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ if (ocp_data & LINK_LIST_READY) ++ break; ++ usleep_range(1000, 2000); ++ } ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ++ ocp_data |= RE_INIT_LL; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ++ for (i = 0; i < 1000; i++) { ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ if (ocp_data & LINK_LIST_READY) ++ break; ++ usleep_range(1000, 2000); ++ } ++ ++ rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8153_RMS); ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0); ++ ocp_data |= TCR0_AUTO_FIFO; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR0, ocp_data); ++ ++ rtl8152_nic_reset(tp); ++ ++ /* rx share fifo credit full threshold */ ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_NORMAL); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_NORMAL); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_NORMAL); ++ /* TX share fifo free credit full threshold */ ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL2); ++ ++ /* rx aggregation */ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ++ ocp_data &= ~RX_AGG_DISABLE; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++} ++ ++static void r8153_enter_oob(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ int i; ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ ocp_data &= ~NOW_IS_OOB; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ++ rtl_disable(tp); ++ ++ for (i = 0; i < 1000; i++) { ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ if (ocp_data & LINK_LIST_READY) ++ break; ++ usleep_range(1000, 2000); ++ } ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ++ ocp_data |= RE_INIT_LL; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); ++ ++ for (i = 0; i < 1000; i++) { ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ if (ocp_data & LINK_LIST_READY) ++ break; ++ usleep_range(1000, 2000); ++ } ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8153_RMS); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG); ++ ocp_data &= ~TEREDO_WAKE_MASK; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data); ++ ++ rtl_rx_vlan_en(tp, true); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PAL_BDC_CR); ++ ocp_data |= ALDPS_PROXY_MODE; ++ ocp_write_word(tp, MCU_TYPE_PLA, PAL_BDC_CR, ocp_data); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ++ ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB; ++ ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); ++ ++ rxdy_gated_en(tp, false); ++ ++ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ++ ocp_data |= RCR_APM | RCR_AM | RCR_AB; ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); ++} ++ ++static void r8153_disable_aldps(struct r8152 *tp) ++{ ++ u16 data; ++ ++ data = ocp_reg_read(tp, OCP_POWER_CFG); ++ data &= ~EN_ALDPS; ++ ocp_reg_write(tp, OCP_POWER_CFG, data); ++ msleep(20); ++} ++ ++static void r8153_enable_aldps(struct r8152 *tp) ++{ ++ u16 data; ++ ++ data = ocp_reg_read(tp, OCP_POWER_CFG); ++ data |= EN_ALDPS; ++ ocp_reg_write(tp, OCP_POWER_CFG, data); ++} ++ ++static void rtl8153_disable(struct r8152 *tp) ++{ ++ r8153_disable_aldps(tp); ++ rtl_disable(tp); ++ r8153_enable_aldps(tp); ++} ++ ++static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex) ++{ ++ u16 bmcr, anar, gbcr; ++ int ret = 0; ++ ++ cancel_delayed_work_sync(&tp->schedule); ++ anar = r8152_mdio_read(tp, MII_ADVERTISE); ++ anar &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | ++ ADVERTISE_100HALF | ADVERTISE_100FULL); ++ if (tp->mii.supports_gmii) { ++ gbcr = r8152_mdio_read(tp, MII_CTRL1000); ++ gbcr &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); ++ } else { ++ gbcr = 0; ++ } ++ ++ if (autoneg == AUTONEG_DISABLE) { ++ if (speed == SPEED_10) { ++ bmcr = 0; ++ anar |= ADVERTISE_10HALF | ADVERTISE_10FULL; ++ } else if (speed == SPEED_100) { ++ bmcr = BMCR_SPEED100; ++ anar |= ADVERTISE_100HALF | ADVERTISE_100FULL; ++ } else if (speed == SPEED_1000 && tp->mii.supports_gmii) { ++ bmcr = BMCR_SPEED1000; ++ gbcr |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; ++ } else { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (duplex == DUPLEX_FULL) ++ bmcr |= BMCR_FULLDPLX; ++ } else { ++ if (speed == SPEED_10) { ++ if (duplex == DUPLEX_FULL) ++ anar |= ADVERTISE_10HALF | ADVERTISE_10FULL; ++ else ++ anar |= ADVERTISE_10HALF; ++ } else if (speed == SPEED_100) { ++ if (duplex == DUPLEX_FULL) { ++ anar |= ADVERTISE_10HALF | ADVERTISE_10FULL; ++ anar |= ADVERTISE_100HALF | ADVERTISE_100FULL; ++ } else { ++ anar |= ADVERTISE_10HALF; ++ anar |= ADVERTISE_100HALF; ++ } ++ } else if (speed == SPEED_1000 && tp->mii.supports_gmii) { ++ if (duplex == DUPLEX_FULL) { ++ anar |= ADVERTISE_10HALF | ADVERTISE_10FULL; ++ anar |= ADVERTISE_100HALF | ADVERTISE_100FULL; ++ gbcr |= ADVERTISE_1000FULL | ADVERTISE_1000HALF; ++ } else { ++ anar |= ADVERTISE_10HALF; ++ anar |= ADVERTISE_100HALF; ++ gbcr |= ADVERTISE_1000HALF; ++ } ++ } else { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ bmcr = BMCR_ANENABLE | BMCR_ANRESTART; ++ } ++ ++ if (test_bit(PHY_RESET, &tp->flags)) ++ bmcr |= BMCR_RESET; ++ ++ if (tp->mii.supports_gmii) ++ r8152_mdio_write(tp, MII_CTRL1000, gbcr); ++ ++ r8152_mdio_write(tp, MII_ADVERTISE, anar); ++ r8152_mdio_write(tp, MII_BMCR, bmcr); ++ ++ if (test_bit(PHY_RESET, &tp->flags)) { ++ int i; ++ ++ clear_bit(PHY_RESET, &tp->flags); ++ for (i = 0; i < 50; i++) { ++ msleep(20); ++ if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0) ++ break; ++ } ++ } ++ ++out: ++ ++ return ret; ++} ++ ++static void rtl8152_up(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8152b_disable_aldps(tp); ++ r8152b_exit_oob(tp); ++ r8152b_enable_aldps(tp); ++} ++ ++static void rtl8152_down(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ rtl_drop_queued_tx(tp); ++ return; ++ } ++ ++ r8152_power_cut_en(tp, false); ++ r8152b_disable_aldps(tp); ++ r8152b_enter_oob(tp); ++ r8152b_enable_aldps(tp); ++} ++ ++static void rtl8153_up(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8153_disable_aldps(tp); ++ r8153_first_init(tp); ++ r8153_enable_aldps(tp); ++} ++ ++static void rtl8153_down(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) { ++ rtl_drop_queued_tx(tp); ++ return; ++ } ++ ++ r8153_u1u2en(tp, false); ++ r8153_power_cut_en(tp, false); ++ r8153_disable_aldps(tp); ++ r8153_enter_oob(tp); ++ r8153_enable_aldps(tp); ++} ++ ++static void set_carrier(struct r8152 *tp) ++{ ++ struct net_device *netdev = tp->netdev; ++ u8 speed; ++ ++ clear_bit(RTL8152_LINK_CHG, &tp->flags); ++ speed = rtl8152_get_speed(tp); ++ ++ if (speed & LINK_STATUS) { ++ if (!(tp->speed & LINK_STATUS)) { ++ tp->rtl_ops.enable(tp); ++ set_bit(RTL8152_SET_RX_MODE, &tp->flags); ++ netif_carrier_on(netdev); ++ } ++ } else { ++ if (tp->speed & LINK_STATUS) { ++ netif_carrier_off(netdev); ++ tasklet_disable(&tp->tl); ++ tp->rtl_ops.disable(tp); ++ tasklet_enable(&tp->tl); ++ } ++ } ++ tp->speed = speed; ++} ++ ++static void rtl_work_func_t(struct work_struct *work) ++{ ++ struct r8152 *tp = container_of(work, struct r8152, schedule.work); ++ ++ if (usb_autopm_get_interface(tp->intf) < 0) ++ return; ++ ++ if (!test_bit(WORK_ENABLE, &tp->flags)) ++ goto out1; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ goto out1; ++ ++ if (!mutex_trylock(&tp->control)) { ++ schedule_delayed_work(&tp->schedule, 0); ++ goto out1; ++ } ++ ++ if (test_bit(RTL8152_LINK_CHG, &tp->flags)) ++ set_carrier(tp); ++ ++ if (test_bit(RTL8152_SET_RX_MODE, &tp->flags)) ++ _rtl8152_set_rx_mode(tp->netdev); ++ ++ if (test_bit(SCHEDULE_TASKLET, &tp->flags) && ++ (tp->speed & LINK_STATUS)) { ++ clear_bit(SCHEDULE_TASKLET, &tp->flags); ++ tasklet_schedule(&tp->tl); ++ } ++ ++ if (test_bit(PHY_RESET, &tp->flags)) ++ rtl_phy_reset(tp); ++ ++ mutex_unlock(&tp->control); ++ ++out1: ++ usb_autopm_put_interface(tp->intf); ++} ++ ++static int rtl8152_open(struct net_device *netdev) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ int res = 0; ++ ++ res = alloc_all_mem(tp); ++ if (res) ++ goto out; ++ ++ /* set speed to 0 to avoid autoresume try to submit rx */ ++ tp->speed = 0; ++ ++ res = usb_autopm_get_interface(tp->intf); ++ if (res < 0) { ++ free_all_mem(tp); ++ goto out; ++ } ++ ++ mutex_lock(&tp->control); ++ ++ /* The WORK_ENABLE may be set when autoresume occurs */ ++ if (test_bit(WORK_ENABLE, &tp->flags)) { ++ clear_bit(WORK_ENABLE, &tp->flags); ++ usb_kill_urb(tp->intr_urb); ++ cancel_delayed_work_sync(&tp->schedule); ++ ++ /* disable the tx/rx, if the workqueue has enabled them. */ ++ if (tp->speed & LINK_STATUS) ++ tp->rtl_ops.disable(tp); ++ } ++ ++ tp->rtl_ops.up(tp); ++ ++ rtl8152_set_speed(tp, AUTONEG_ENABLE, ++ tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, ++ DUPLEX_FULL); ++ tp->speed = 0; ++ netif_carrier_off(netdev); ++ netif_start_queue(netdev); ++ set_bit(WORK_ENABLE, &tp->flags); ++ ++ res = usb_submit_urb(tp->intr_urb, GFP_KERNEL); ++ if (res) { ++ if (res == -ENODEV) ++ netif_device_detach(tp->netdev); ++ netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n", ++ res); ++ free_all_mem(tp); ++ } ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return res; ++} ++ ++static int rtl8152_close(struct net_device *netdev) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ int res = 0; ++ ++ clear_bit(WORK_ENABLE, &tp->flags); ++ usb_kill_urb(tp->intr_urb); ++ cancel_delayed_work_sync(&tp->schedule); ++ netif_stop_queue(netdev); ++ ++ res = usb_autopm_get_interface(tp->intf); ++ if (res < 0) { ++ rtl_drop_queued_tx(tp); ++ } else { ++ mutex_lock(&tp->control); ++ ++ /* The autosuspend may have been enabled and wouldn't ++ * be disable when autoresume occurs, because the ++ * netif_running() would be false. ++ */ ++ rtl_runtime_suspend_enable(tp, false); ++ ++ tasklet_disable(&tp->tl); ++ tp->rtl_ops.down(tp); ++ tasklet_enable(&tp->tl); ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ } ++ ++ free_all_mem(tp); ++ ++ return res; ++} ++ ++static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg) ++{ ++ ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | dev); ++ ocp_reg_write(tp, OCP_EEE_DATA, reg); ++ ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | dev); ++} ++ ++static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg) ++{ ++ u16 data; ++ ++ r8152_mmd_indirect(tp, dev, reg); ++ data = ocp_reg_read(tp, OCP_EEE_DATA); ++ ocp_reg_write(tp, OCP_EEE_AR, 0x0000); ++ ++ return data; ++} ++ ++static void r8152_mmd_write(struct r8152 *tp, u16 dev, u16 reg, u16 data) ++{ ++ r8152_mmd_indirect(tp, dev, reg); ++ ocp_reg_write(tp, OCP_EEE_DATA, data); ++ ocp_reg_write(tp, OCP_EEE_AR, 0x0000); ++} ++ ++static void r8152_eee_en(struct r8152 *tp, bool enable) ++{ ++ u16 config1, config2, config3; ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); ++ config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask; ++ config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2); ++ config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask; ++ ++ if (enable) { ++ ocp_data |= EEE_RX_EN | EEE_TX_EN; ++ config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN; ++ config1 |= sd_rise_time(1); ++ config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN; ++ config3 |= fast_snr(42); ++ } else { ++ ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); ++ config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | ++ RX_QUIET_EN); ++ config1 |= sd_rise_time(7); ++ config2 &= ~(RG_DACQUIET_EN | RG_LDVQUIET_EN); ++ config3 |= fast_snr(511); ++ } ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); ++ ocp_reg_write(tp, OCP_EEE_CONFIG1, config1); ++ ocp_reg_write(tp, OCP_EEE_CONFIG2, config2); ++ ocp_reg_write(tp, OCP_EEE_CONFIG3, config3); ++} ++ ++static void r8152b_enable_eee(struct r8152 *tp) ++{ ++ r8152_eee_en(tp, true); ++ r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, MDIO_EEE_100TX); ++} ++ ++static void r8153_eee_en(struct r8152 *tp, bool enable) ++{ ++ u32 ocp_data; ++ u16 config; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); ++ config = ocp_reg_read(tp, OCP_EEE_CFG); ++ ++ if (enable) { ++ ocp_data |= EEE_RX_EN | EEE_TX_EN; ++ config |= EEE10_EN; ++ } else { ++ ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); ++ config &= ~EEE10_EN; ++ } ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); ++ ocp_reg_write(tp, OCP_EEE_CFG, config); ++} ++ ++static void r8153_enable_eee(struct r8152 *tp) ++{ ++ r8153_eee_en(tp, true); ++ ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX); ++} ++ ++static void r8152b_enable_fc(struct r8152 *tp) ++{ ++ u16 anar; ++ ++ anar = r8152_mdio_read(tp, MII_ADVERTISE); ++ anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; ++ r8152_mdio_write(tp, MII_ADVERTISE, anar); ++} ++ ++static void rtl_tally_reset(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY); ++ ocp_data |= TALLY_RESET; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data); ++} ++ ++static void r8152b_init(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8152b_disable_aldps(tp); ++ ++ if (tp->version == RTL_VER_01) { ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE); ++ ocp_data &= ~LED_MODE_MASK; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data); ++ } ++ ++ r8152_power_cut_en(tp, false); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); ++ ocp_data |= TX_10M_IDLE_EN | PFM_PWM_SWITCH; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); ++ ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL); ++ ocp_data &= ~MCU_CLK_RATIO_MASK; ++ ocp_data |= MCU_CLK_RATIO | D3_CLK_GATED_EN; ++ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, ocp_data); ++ ocp_data = GPHY_STS_MSK | SPEED_DOWN_MSK | ++ SPDWN_RXDV_MSK | SPDWN_LINKCHG_MSK; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_GPHY_INTR_IMR, ocp_data); ++ ++ r8152b_enable_eee(tp); ++ r8152b_enable_aldps(tp); ++ r8152b_enable_fc(tp); ++ rtl_tally_reset(tp); ++ ++ /* enable rx aggregation */ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ++ ocp_data &= ~RX_AGG_DISABLE; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); ++} ++ ++static void r8153_init(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ int i; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8153_disable_aldps(tp); ++ r8153_u1u2en(tp, false); ++ ++ for (i = 0; i < 500; i++) { ++ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & ++ AUTOLOAD_DONE) ++ break; ++ msleep(20); ++ } ++ ++ for (i = 0; i < 500; i++) { ++ ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK; ++ if (ocp_data == PHY_STAT_LAN_ON || ocp_data == PHY_STAT_PWRDN) ++ break; ++ msleep(20); ++ } ++ ++ r8153_u2p3en(tp, false); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL); ++ ocp_data &= ~TIMER11_EN; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE); ++ ocp_data &= ~LED_MODE_MASK; ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data); ++ ++ ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_LPM_CTRL); ++ ocp_data &= ~LPM_TIMER_MASK; ++ if (tp->udev->speed == USB_SPEED_SUPER) ++ ocp_data |= LPM_TIMER_500US; ++ else ++ ocp_data |= LPM_TIMER_500MS; ++ ocp_write_byte(tp, MCU_TYPE_USB, USB_LPM_CTRL, ocp_data); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2); ++ ocp_data &= ~SEN_VAL_MASK; ++ ocp_data |= SEN_VAL_NORMAL | SEL_RXIDLE; ++ ocp_write_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2, ocp_data); ++ ++ r8153_power_cut_en(tp, false); ++ r8153_u1u2en(tp, true); ++ ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, ALDPS_SPDWN_RATIO); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, EEE_SPDWN_RATIO); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ++ PKT_AVAIL_SPDWN_EN | SUSPEND_SPDWN_EN | ++ U1U2_SPDWN_EN | L1_SPDWN_EN); ++ ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ++ PWRSAVE_SPDWN_EN | RXDV_SPDWN_EN | TX10MIDLE_EN | ++ TP100_SPDWN_EN | TP500_SPDWN_EN | TP1000_SPDWN_EN | ++ EEE_SPDWN_EN); ++ ++ r8153_enable_eee(tp); ++ r8153_enable_aldps(tp); ++ r8152b_enable_fc(tp); ++ rtl_tally_reset(tp); ++} ++ ++static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct r8152 *tp = usb_get_intfdata(intf); ++ struct net_device *netdev = tp->netdev; ++ int ret = 0; ++ ++ mutex_lock(&tp->control); ++ ++ if (PMSG_IS_AUTO(message)) { ++ if (netif_running(netdev) && work_busy(&tp->schedule.work)) { ++ ret = -EBUSY; ++ goto out1; ++ } ++ ++ set_bit(SELECTIVE_SUSPEND, &tp->flags); ++ } else { ++ netif_device_detach(netdev); ++ } ++ ++ if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) { ++ clear_bit(WORK_ENABLE, &tp->flags); ++ usb_kill_urb(tp->intr_urb); ++ tasklet_disable(&tp->tl); ++ if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { ++ rtl_stop_rx(tp); ++ rtl_runtime_suspend_enable(tp, true); ++ } else { ++ cancel_delayed_work_sync(&tp->schedule); ++ tp->rtl_ops.down(tp); ++ } ++ tasklet_enable(&tp->tl); ++ } ++out1: ++ mutex_unlock(&tp->control); ++ ++ return ret; ++} ++ ++static int rtl8152_resume(struct usb_interface *intf) ++{ ++ struct r8152 *tp = usb_get_intfdata(intf); ++ ++ mutex_lock(&tp->control); ++ ++ if (!test_bit(SELECTIVE_SUSPEND, &tp->flags)) { ++ tp->rtl_ops.init(tp); ++ netif_device_attach(tp->netdev); ++ } ++ ++ if (netif_running(tp->netdev)) { ++ if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { ++ rtl_runtime_suspend_enable(tp, false); ++ clear_bit(SELECTIVE_SUSPEND, &tp->flags); ++ set_bit(WORK_ENABLE, &tp->flags); ++ if (tp->speed & LINK_STATUS) ++ rtl_start_rx(tp); ++ } else { ++ tp->rtl_ops.up(tp); ++ rtl8152_set_speed(tp, AUTONEG_ENABLE, ++ tp->mii.supports_gmii ? ++ SPEED_1000 : SPEED_100, ++ DUPLEX_FULL); ++ tp->speed = 0; ++ netif_carrier_off(tp->netdev); ++ set_bit(WORK_ENABLE, &tp->flags); ++ } ++ usb_submit_urb(tp->intr_urb, GFP_KERNEL); ++ } else if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { ++ clear_bit(SELECTIVE_SUSPEND, &tp->flags); ++ } ++ ++ mutex_unlock(&tp->control); ++ ++ return 0; ++} ++ ++static void rtl8152_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ ++ if (usb_autopm_get_interface(tp->intf) < 0) ++ return; ++ ++ mutex_lock(&tp->control); ++ ++ wol->supported = WAKE_ANY; ++ wol->wolopts = __rtl_get_wol(tp); ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++} ++ ++static int rtl8152_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ int ret; ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out_set_wol; ++ ++ mutex_lock(&tp->control); ++ ++ __rtl_set_wol(tp, wol->wolopts); ++ tp->saved_wolopts = wol->wolopts & WAKE_ANY; ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out_set_wol: ++ return ret; ++} ++ ++static u32 rtl8152_get_msglevel(struct net_device *dev) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ ++ return tp->msg_enable; ++} ++ ++static void rtl8152_set_msglevel(struct net_device *dev, u32 value) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ ++ tp->msg_enable = value; ++} ++ ++static void rtl8152_get_drvinfo(struct net_device *netdev, ++ struct ethtool_drvinfo *info) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ ++ strlcpy(info->driver, MODULENAME, sizeof(info->driver)); ++ strlcpy(info->version, DRIVER_VERSION, sizeof(info->version)); ++ usb_make_path(tp->udev, info->bus_info, sizeof(info->bus_info)); ++} ++ ++static ++int rtl8152_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ int ret; ++ ++ if (!tp->mii.mdio_read) ++ return -EOPNOTSUPP; ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out; ++ ++ mutex_lock(&tp->control); ++ ++ ret = mii_ethtool_gset(&tp->mii, cmd); ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return ret; ++} ++ ++static int rtl8152_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ int ret; ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out; ++ ++ mutex_lock(&tp->control); ++ ++ ret = rtl8152_set_speed(tp, cmd->autoneg, cmd->speed, cmd->duplex); ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return ret; ++} ++ ++static const char rtl8152_gstrings[][ETH_GSTRING_LEN] = { ++ "tx_packets", ++ "rx_packets", ++ "tx_errors", ++ "rx_errors", ++ "rx_missed", ++ "align_errors", ++ "tx_single_collisions", ++ "tx_multi_collisions", ++ "rx_unicast", ++ "rx_broadcast", ++ "rx_multicast", ++ "tx_aborted", ++ "tx_underrun", ++}; ++ ++static int rtl8152_get_sset_count(struct net_device *dev, int sset) ++{ ++ switch (sset) { ++ case ETH_SS_STATS: ++ return ARRAY_SIZE(rtl8152_gstrings); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ ++static void rtl8152_get_ethtool_stats(struct net_device *dev, ++ struct ethtool_stats *stats, u64 *data) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ struct tally_counter tally; ++ ++ if (usb_autopm_get_interface(tp->intf) < 0) ++ return; ++ ++ generic_ocp_read(tp, PLA_TALLYCNT, sizeof(tally), &tally, MCU_TYPE_PLA); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++ data[0] = le64_to_cpu(tally.tx_packets); ++ data[1] = le64_to_cpu(tally.rx_packets); ++ data[2] = le64_to_cpu(tally.tx_errors); ++ data[3] = le32_to_cpu(tally.rx_errors); ++ data[4] = le16_to_cpu(tally.rx_missed); ++ data[5] = le16_to_cpu(tally.align_errors); ++ data[6] = le32_to_cpu(tally.tx_one_collision); ++ data[7] = le32_to_cpu(tally.tx_multi_collision); ++ data[8] = le64_to_cpu(tally.rx_unicast); ++ data[9] = le64_to_cpu(tally.rx_broadcast); ++ data[10] = le32_to_cpu(tally.rx_multicast); ++ data[11] = le16_to_cpu(tally.tx_aborted); ++ data[12] = le16_to_cpu(tally.tx_underun); ++} ++ ++static void rtl8152_get_strings(struct net_device *dev, u32 stringset, u8 *data) ++{ ++ switch (stringset) { ++ case ETH_SS_STATS: ++ memcpy(data, *rtl8152_gstrings, sizeof(rtl8152_gstrings)); ++ break; ++ } ++} ++ ++static int r8152_get_eee(struct r8152 *tp, struct ethtool_eee *eee) ++{ ++ u32 ocp_data, lp, adv, supported = 0; ++ u16 val; ++ ++ val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); ++ supported = mmd_eee_cap_to_ethtool_sup_t(val); ++ ++ val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV); ++ adv = mmd_eee_adv_to_ethtool_adv_t(val); ++ ++ val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE); ++ lp = mmd_eee_adv_to_ethtool_adv_t(val); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); ++ ocp_data &= EEE_RX_EN | EEE_TX_EN; ++ ++ eee->eee_enabled = !!ocp_data; ++ eee->eee_active = !!(supported & adv & lp); ++ eee->supported = supported; ++ eee->advertised = adv; ++ eee->lp_advertised = lp; ++ ++ return 0; ++} ++ ++static int r8152_set_eee(struct r8152 *tp, struct ethtool_eee *eee) ++{ ++ u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); ++ ++ r8152_eee_en(tp, eee->eee_enabled); ++ ++ if (!eee->eee_enabled) ++ val = 0; ++ ++ r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); ++ ++ return 0; ++} ++ ++static int r8153_get_eee(struct r8152 *tp, struct ethtool_eee *eee) ++{ ++ u32 ocp_data, lp, adv, supported = 0; ++ u16 val; ++ ++ val = ocp_reg_read(tp, OCP_EEE_ABLE); ++ supported = mmd_eee_cap_to_ethtool_sup_t(val); ++ ++ val = ocp_reg_read(tp, OCP_EEE_ADV); ++ adv = mmd_eee_adv_to_ethtool_adv_t(val); ++ ++ val = ocp_reg_read(tp, OCP_EEE_LPABLE); ++ lp = mmd_eee_adv_to_ethtool_adv_t(val); ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); ++ ocp_data &= EEE_RX_EN | EEE_TX_EN; ++ ++ eee->eee_enabled = !!ocp_data; ++ eee->eee_active = !!(supported & adv & lp); ++ eee->supported = supported; ++ eee->advertised = adv; ++ eee->lp_advertised = lp; ++ ++ return 0; ++} ++ ++static int r8153_set_eee(struct r8152 *tp, struct ethtool_eee *eee) ++{ ++ u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); ++ ++ r8153_eee_en(tp, eee->eee_enabled); ++ ++ if (!eee->eee_enabled) ++ val = 0; ++ ++ ocp_reg_write(tp, OCP_EEE_ADV, val); ++ ++ return 0; ++} ++ ++static int ++rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *edata) ++{ ++ struct r8152 *tp = netdev_priv(net); ++ int ret; ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out; ++ ++ mutex_lock(&tp->control); ++ ++ ret = tp->rtl_ops.eee_get(tp, edata); ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return ret; ++} ++ ++static int ++rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata) ++{ ++ struct r8152 *tp = netdev_priv(net); ++ int ret; ++ ++ ret = usb_autopm_get_interface(tp->intf); ++ if (ret < 0) ++ goto out; ++ ++ mutex_lock(&tp->control); ++ ++ ret = tp->rtl_ops.eee_set(tp, edata); ++ if (!ret) ++ ret = mii_nway_restart(&tp->mii); ++ ++ mutex_unlock(&tp->control); ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return ret; ++} ++ ++static struct ethtool_ops ops = { ++ .get_drvinfo = rtl8152_get_drvinfo, ++ .get_settings = rtl8152_get_settings, ++ .set_settings = rtl8152_set_settings, ++ .get_link = ethtool_op_get_link, ++ .get_msglevel = rtl8152_get_msglevel, ++ .set_msglevel = rtl8152_set_msglevel, ++ .get_wol = rtl8152_get_wol, ++ .set_wol = rtl8152_set_wol, ++ .get_strings = rtl8152_get_strings, ++ .get_sset_count = rtl8152_get_sset_count, ++ .get_ethtool_stats = rtl8152_get_ethtool_stats, ++ .get_eee = rtl_ethtool_get_eee, ++ .set_eee = rtl_ethtool_set_eee, ++}; ++ ++static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) ++{ ++ struct r8152 *tp = netdev_priv(netdev); ++ struct mii_ioctl_data *data = if_mii(rq); ++ int res; ++ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return -ENODEV; ++ ++ res = usb_autopm_get_interface(tp->intf); ++ if (res < 0) ++ goto out; ++ ++ switch (cmd) { ++ case SIOCGMIIPHY: ++ data->phy_id = R8152_PHY_ID; /* Internal PHY */ ++ break; ++ ++ case SIOCGMIIREG: ++ mutex_lock(&tp->control); ++ data->val_out = r8152_mdio_read(tp, data->reg_num); ++ mutex_unlock(&tp->control); ++ break; ++ ++ case SIOCSMIIREG: ++ if (!capable(CAP_NET_ADMIN)) { ++ res = -EPERM; ++ break; ++ } ++ mutex_lock(&tp->control); ++ r8152_mdio_write(tp, data->reg_num, data->val_in); ++ mutex_unlock(&tp->control); ++ break; ++ ++ default: ++ res = -EOPNOTSUPP; ++ } ++ ++ usb_autopm_put_interface(tp->intf); ++ ++out: ++ return res; ++} ++ ++static int rtl8152_change_mtu(struct net_device *dev, int new_mtu) ++{ ++ struct r8152 *tp = netdev_priv(dev); ++ ++ switch (tp->version) { ++ case RTL_VER_01: ++ case RTL_VER_02: ++ return eth_change_mtu(dev, new_mtu); ++ default: ++ break; ++ } ++ ++ if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU) ++ return -EINVAL; ++ ++ dev->mtu = new_mtu; ++ ++ return 0; ++} ++ ++static const struct net_device_ops rtl8152_netdev_ops = { ++ .ndo_open = rtl8152_open, ++ .ndo_stop = rtl8152_close, ++ .ndo_do_ioctl = rtl8152_ioctl, ++ .ndo_start_xmit = rtl8152_start_xmit, ++ .ndo_tx_timeout = rtl8152_tx_timeout, ++ .ndo_set_features = rtl8152_set_features, ++ .ndo_set_rx_mode = rtl8152_set_rx_mode, ++ .ndo_set_mac_address = rtl8152_set_mac_address, ++ .ndo_change_mtu = rtl8152_change_mtu, ++ .ndo_validate_addr = eth_validate_addr, ++}; ++ ++static void r8152b_get_version(struct r8152 *tp) ++{ ++ u32 ocp_data; ++ u16 version; ++ ++ ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR1); ++ version = (u16)(ocp_data & VERSION_MASK); ++ ++ switch (version) { ++ case 0x4c00: ++ tp->version = RTL_VER_01; ++ break; ++ case 0x4c10: ++ tp->version = RTL_VER_02; ++ break; ++ case 0x5c00: ++ tp->version = RTL_VER_03; ++ tp->mii.supports_gmii = 1; ++ break; ++ case 0x5c10: ++ tp->version = RTL_VER_04; ++ tp->mii.supports_gmii = 1; ++ break; ++ case 0x5c20: ++ tp->version = RTL_VER_05; ++ tp->mii.supports_gmii = 1; ++ break; ++ default: ++ netif_info(tp, probe, tp->netdev, ++ "Unknown version 0x%04x\n", version); ++ break; ++ } ++} ++ ++static void rtl8152_unload(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ if (tp->version != RTL_VER_01) ++ r8152_power_cut_en(tp, true); ++} ++ ++static void rtl8153_unload(struct r8152 *tp) ++{ ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ return; ++ ++ r8153_power_cut_en(tp, false); ++} ++ ++static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id) ++{ ++ struct rtl_ops *ops = &tp->rtl_ops; ++ int ret = -ENODEV; ++ ++ switch (id->idVendor) { ++ case VENDOR_ID_REALTEK: ++ switch (id->idProduct) { ++ case PRODUCT_ID_RTL8152: ++ ops->init = r8152b_init; ++ ops->enable = rtl8152_enable; ++ ops->disable = rtl8152_disable; ++ ops->up = rtl8152_up; ++ ops->down = rtl8152_down; ++ ops->unload = rtl8152_unload; ++ ops->eee_get = r8152_get_eee; ++ ops->eee_set = r8152_set_eee; ++ ret = 0; ++ break; ++ case PRODUCT_ID_RTL8153: ++ ops->init = r8153_init; ++ ops->enable = rtl8153_enable; ++ ops->disable = rtl8153_disable; ++ ops->up = rtl8153_up; ++ ops->down = rtl8153_down; ++ ops->unload = rtl8153_unload; ++ ops->eee_get = r8153_get_eee; ++ ops->eee_set = r8153_set_eee; ++ ret = 0; ++ break; ++ default: ++ break; ++ } ++ break; ++ ++ case VENDOR_ID_SAMSUNG: ++ switch (id->idProduct) { ++ case PRODUCT_ID_SAMSUNG: ++ ops->init = r8153_init; ++ ops->enable = rtl8153_enable; ++ ops->disable = rtl8153_disable; ++ ops->up = rtl8153_up; ++ ops->down = rtl8153_down; ++ ops->unload = rtl8153_unload; ++ ops->eee_get = r8153_get_eee; ++ ops->eee_set = r8153_set_eee; ++ ret = 0; ++ break; ++ default: ++ break; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (ret) ++ netif_err(tp, probe, tp->netdev, "Unknown Device\n"); ++ ++ return ret; ++} ++ ++static int rtl8152_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *udev = interface_to_usbdev(intf); ++ struct r8152 *tp; ++ struct net_device *netdev; ++ int ret; ++ ++ if (udev->actconfig->desc.bConfigurationValue != 1) { ++ usb_driver_set_configuration(udev, 1); ++ return -ENODEV; ++ } ++ ++ usb_reset_device(udev); ++ netdev = alloc_etherdev(sizeof(struct r8152)); ++ if (!netdev) { ++ dev_err(&intf->dev, "Out of memory\n"); ++ return -ENOMEM; ++ } ++ ++ SET_NETDEV_DEV(netdev, &intf->dev); ++ tp = netdev_priv(netdev); ++ tp->msg_enable = 0x7FFF; ++ ++ tp->udev = udev; ++ tp->netdev = netdev; ++ tp->intf = intf; ++ ++ ret = rtl_ops_init(tp, id); ++ if (ret) ++ goto out; ++ ++ tasklet_init(&tp->tl, bottom_half, (unsigned long)tp); ++ mutex_init(&tp->control); ++ INIT_DELAYED_WORK(&tp->schedule, rtl_work_func_t); ++ ++ netdev->netdev_ops = &rtl8152_netdev_ops; ++ netdev->watchdog_timeo = RTL8152_TX_TIMEOUT; ++ ++ netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG | ++ NETIF_F_TSO | NETIF_F_FRAGLIST | NETIF_F_IPV6_CSUM | ++ NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_RX | ++ NETIF_F_HW_VLAN_CTAG_TX; ++ netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG | ++ NETIF_F_TSO | NETIF_F_FRAGLIST | ++ NETIF_F_IPV6_CSUM | NETIF_F_TSO6 | ++ NETIF_F_HW_VLAN_CTAG_RX | ++ NETIF_F_HW_VLAN_CTAG_TX; ++ netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | ++ NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | ++ NETIF_F_IPV6_CSUM | NETIF_F_TSO6; ++ ++ netdev->ethtool_ops = &ops; ++ netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE); ++ ++ tp->mii.dev = netdev; ++ tp->mii.mdio_read = read_mii_word; ++ tp->mii.mdio_write = write_mii_word; ++ tp->mii.phy_id_mask = 0x3f; ++ tp->mii.reg_num_mask = 0x1f; ++ tp->mii.phy_id = R8152_PHY_ID; ++ tp->mii.supports_gmii = 0; ++ ++ intf->needs_remote_wakeup = 1; ++ ++ r8152b_get_version(tp); ++ tp->rtl_ops.init(tp); ++ set_ethernet_addr(tp); ++ ++ usb_set_intfdata(intf, tp); ++ ++ ret = register_netdev(netdev); ++ if (ret != 0) { ++ netif_err(tp, probe, netdev, "couldn't register the device\n"); ++ goto out1; ++ } ++ ++ tp->saved_wolopts = __rtl_get_wol(tp); ++ if (tp->saved_wolopts) ++ device_set_wakeup_enable(&udev->dev, true); ++ else ++ device_set_wakeup_enable(&udev->dev, false); ++ ++ netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION); ++ ++ return 0; ++ ++out1: ++ usb_set_intfdata(intf, NULL); ++out: ++ free_netdev(netdev); ++ return ret; ++} ++ ++static void rtl8152_disconnect(struct usb_interface *intf) ++{ ++ struct r8152 *tp = usb_get_intfdata(intf); ++ ++ usb_set_intfdata(intf, NULL); ++ if (tp) { ++ struct usb_device *udev = tp->udev; ++ ++ if (udev->state == USB_STATE_NOTATTACHED) ++ set_bit(RTL8152_UNPLUG, &tp->flags); ++ ++ tasklet_kill(&tp->tl); ++ unregister_netdev(tp->netdev); ++ tp->rtl_ops.unload(tp); ++ free_netdev(tp->netdev); ++ } ++} ++ ++/* table of devices that work with this driver */ ++static struct usb_device_id rtl8152_table[] = { ++ {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)}, ++ {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8153)}, ++ {USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG)}, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(usb, rtl8152_table); ++ ++static struct usb_driver rtl8152_driver = { ++ .name = MODULENAME, ++ .id_table = rtl8152_table, ++ .probe = rtl8152_probe, ++ .disconnect = rtl8152_disconnect, ++ .suspend = rtl8152_suspend, ++ .resume = rtl8152_resume, ++ .reset_resume = rtl8152_resume, ++ .supports_autosuspend = 1, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(rtl8152_driver); ++ ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/rtl8150.c backports-3.18.1-1/drivers/net/usb/rtl8150.c +--- backports-3.18.1-1.org/drivers/net/usb/rtl8150.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/rtl8150.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,950 @@ ++/* ++ * Copyright (c) 2002 Petko Manolov (petkan@users.sourceforge.net) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ */ ++ ++#include <linux/signal.h> ++#include <linux/slab.h> ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/mii.h> ++#include <linux/ethtool.h> ++#include <linux/usb.h> ++#include <asm/uaccess.h> ++ ++/* Version Information */ ++#define DRIVER_VERSION "v0.6.2 (2004/08/27)" ++#define DRIVER_AUTHOR "Petko Manolov petkan@users.sourceforge.net" ++#define DRIVER_DESC "rtl8150 based usb-ethernet driver" ++ ++#define IDR 0x0120 ++#define MAR 0x0126 ++#define CR 0x012e ++#define TCR 0x012f ++#define RCR 0x0130 ++#define TSR 0x0132 ++#define RSR 0x0133 ++#define CON0 0x0135 ++#define CON1 0x0136 ++#define MSR 0x0137 ++#define PHYADD 0x0138 ++#define PHYDAT 0x0139 ++#define PHYCNT 0x013b ++#define GPPC 0x013d ++#define BMCR 0x0140 ++#define BMSR 0x0142 ++#define ANAR 0x0144 ++#define ANLP 0x0146 ++#define AER 0x0148 ++#define CSCR 0x014C /* This one has the link status */ ++#define CSCR_LINK_STATUS (1 << 3) ++ ++#define IDR_EEPROM 0x1202 ++ ++#define PHY_READ 0 ++#define PHY_WRITE 0x20 ++#define PHY_GO 0x40 ++ ++#define MII_TIMEOUT 10 ++#define INTBUFSIZE 8 ++ ++#define RTL8150_REQT_READ 0xc0 ++#define RTL8150_REQT_WRITE 0x40 ++#define RTL8150_REQ_GET_REGS 0x05 ++#define RTL8150_REQ_SET_REGS 0x05 ++ ++ ++/* Transmit status register errors */ ++#define TSR_ECOL (1<<5) ++#define TSR_LCOL (1<<4) ++#define TSR_LOSS_CRS (1<<3) ++#define TSR_JBR (1<<2) ++#define TSR_ERRORS (TSR_ECOL | TSR_LCOL | TSR_LOSS_CRS | TSR_JBR) ++/* Receive status register errors */ ++#define RSR_CRC (1<<2) ++#define RSR_FAE (1<<1) ++#define RSR_ERRORS (RSR_CRC | RSR_FAE) ++ ++/* Media status register definitions */ ++#define MSR_DUPLEX (1<<4) ++#define MSR_SPEED (1<<3) ++#define MSR_LINK (1<<2) ++ ++/* Interrupt pipe data */ ++#define INT_TSR 0x00 ++#define INT_RSR 0x01 ++#define INT_MSR 0x02 ++#define INT_WAKSR 0x03 ++#define INT_TXOK_CNT 0x04 ++#define INT_RXLOST_CNT 0x05 ++#define INT_CRERR_CNT 0x06 ++#define INT_COL_CNT 0x07 ++ ++ ++#define RTL8150_MTU 1540 ++#define RTL8150_TX_TIMEOUT (HZ) ++#define RX_SKB_POOL_SIZE 4 ++ ++/* rtl8150 flags */ ++#define RTL8150_HW_CRC 0 ++#define RX_REG_SET 1 ++#define RTL8150_UNPLUG 2 ++#define RX_URB_FAIL 3 ++ ++/* Define these values to match your device */ ++#define VENDOR_ID_REALTEK 0x0bda ++#define VENDOR_ID_MELCO 0x0411 ++#define VENDOR_ID_MICRONET 0x3980 ++#define VENDOR_ID_LONGSHINE 0x07b8 ++#define VENDOR_ID_OQO 0x1557 ++#define VENDOR_ID_ZYXEL 0x0586 ++ ++#define PRODUCT_ID_RTL8150 0x8150 ++#define PRODUCT_ID_LUAKTX 0x0012 ++#define PRODUCT_ID_LCS8138TX 0x401a ++#define PRODUCT_ID_SP128AR 0x0003 ++#define PRODUCT_ID_PRESTIGE 0x401a ++ ++#undef EEPROM_WRITE ++ ++/* table of devices that work with this driver */ ++static struct usb_device_id rtl8150_table[] = { ++ {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8150)}, ++ {USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)}, ++ {USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)}, ++ {USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)}, ++ {USB_DEVICE(VENDOR_ID_OQO, PRODUCT_ID_RTL8150)}, ++ {USB_DEVICE(VENDOR_ID_ZYXEL, PRODUCT_ID_PRESTIGE)}, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(usb, rtl8150_table); ++ ++struct rtl8150 { ++ unsigned long flags; ++ struct usb_device *udev; ++ struct tasklet_struct tl; ++ struct net_device *netdev; ++ struct urb *rx_urb, *tx_urb, *intr_urb; ++ struct sk_buff *tx_skb, *rx_skb; ++ struct sk_buff *rx_skb_pool[RX_SKB_POOL_SIZE]; ++ spinlock_t rx_pool_lock; ++ struct usb_ctrlrequest dr; ++ int intr_interval; ++ u8 *intr_buff; ++ u8 phy; ++}; ++ ++typedef struct rtl8150 rtl8150_t; ++ ++struct async_req { ++ struct usb_ctrlrequest dr; ++ u16 rx_creg; ++}; ++ ++static const char driver_name [] = "rtl8150"; ++ ++/* ++** ++** device related part of the code ++** ++*/ ++static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) ++{ ++ return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), ++ RTL8150_REQ_GET_REGS, RTL8150_REQT_READ, ++ indx, 0, data, size, 500); ++} ++ ++static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) ++{ ++ return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), ++ RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE, ++ indx, 0, data, size, 500); ++} ++ ++static void async_set_reg_cb(struct urb *urb) ++{ ++ struct async_req *req = (struct async_req *)urb->context; ++ int status = urb->status; ++ ++ if (status < 0) ++ dev_dbg(&urb->dev->dev, "%s failed with %d", __func__, status); ++ kfree(req); ++ usb_free_urb(urb); ++} ++ ++static int async_set_registers(rtl8150_t *dev, u16 indx, u16 size, u16 reg) ++{ ++ int res = -ENOMEM; ++ struct urb *async_urb; ++ struct async_req *req; ++ ++ req = kmalloc(sizeof(struct async_req), GFP_ATOMIC); ++ if (req == NULL) ++ return res; ++ async_urb = usb_alloc_urb(0, GFP_ATOMIC); ++ if (async_urb == NULL) { ++ kfree(req); ++ return res; ++ } ++ req->rx_creg = cpu_to_le16(reg); ++ req->dr.bRequestType = RTL8150_REQT_WRITE; ++ req->dr.bRequest = RTL8150_REQ_SET_REGS; ++ req->dr.wIndex = 0; ++ req->dr.wValue = cpu_to_le16(indx); ++ req->dr.wLength = cpu_to_le16(size); ++ usb_fill_control_urb(async_urb, dev->udev, ++ usb_sndctrlpipe(dev->udev, 0), (void *)&req->dr, ++ &req->rx_creg, size, async_set_reg_cb, req); ++ res = usb_submit_urb(async_urb, GFP_ATOMIC); ++ if (res) { ++ if (res == -ENODEV) ++ netif_device_detach(dev->netdev); ++ dev_err(&dev->udev->dev, "%s failed with %d\n", __func__, res); ++ } ++ return res; ++} ++ ++static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg) ++{ ++ int i; ++ u8 data[3], tmp; ++ ++ data[0] = phy; ++ data[1] = data[2] = 0; ++ tmp = indx | PHY_READ | PHY_GO; ++ i = 0; ++ ++ set_registers(dev, PHYADD, sizeof(data), data); ++ set_registers(dev, PHYCNT, 1, &tmp); ++ do { ++ get_registers(dev, PHYCNT, 1, data); ++ } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); ++ ++ if (i <= MII_TIMEOUT) { ++ get_registers(dev, PHYDAT, 2, data); ++ *reg = data[0] | (data[1] << 8); ++ return 0; ++ } else ++ return 1; ++} ++ ++static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg) ++{ ++ int i; ++ u8 data[3], tmp; ++ ++ data[0] = phy; ++ data[1] = reg & 0xff; ++ data[2] = (reg >> 8) & 0xff; ++ tmp = indx | PHY_WRITE | PHY_GO; ++ i = 0; ++ ++ set_registers(dev, PHYADD, sizeof(data), data); ++ set_registers(dev, PHYCNT, 1, &tmp); ++ do { ++ get_registers(dev, PHYCNT, 1, data); ++ } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); ++ ++ if (i <= MII_TIMEOUT) ++ return 0; ++ else ++ return 1; ++} ++ ++static inline void set_ethernet_addr(rtl8150_t * dev) ++{ ++ u8 node_id[6]; ++ ++ get_registers(dev, IDR, sizeof(node_id), node_id); ++ memcpy(dev->netdev->dev_addr, node_id, sizeof(node_id)); ++} ++ ++static int rtl8150_set_mac_address(struct net_device *netdev, void *p) ++{ ++ struct sockaddr *addr = p; ++ rtl8150_t *dev = netdev_priv(netdev); ++ ++ if (netif_running(netdev)) ++ return -EBUSY; ++ ++ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); ++ netdev_dbg(netdev, "Setting MAC address to %pM\n", netdev->dev_addr); ++ /* Set the IDR registers. */ ++ set_registers(dev, IDR, netdev->addr_len, netdev->dev_addr); ++#ifdef EEPROM_WRITE ++ { ++ int i; ++ u8 cr; ++ /* Get the CR contents. */ ++ get_registers(dev, CR, 1, &cr); ++ /* Set the WEPROM bit (eeprom write enable). */ ++ cr |= 0x20; ++ set_registers(dev, CR, 1, &cr); ++ /* Write the MAC address into eeprom. Eeprom writes must be word-sized, ++ so we need to split them up. */ ++ for (i = 0; i * 2 < netdev->addr_len; i++) { ++ set_registers(dev, IDR_EEPROM + (i * 2), 2, ++ netdev->dev_addr + (i * 2)); ++ } ++ /* Clear the WEPROM bit (preventing accidental eeprom writes). */ ++ cr &= 0xdf; ++ set_registers(dev, CR, 1, &cr); ++ } ++#endif ++ return 0; ++} ++ ++static int rtl8150_reset(rtl8150_t * dev) ++{ ++ u8 data = 0x10; ++ int i = HZ; ++ ++ set_registers(dev, CR, 1, &data); ++ do { ++ get_registers(dev, CR, 1, &data); ++ } while ((data & 0x10) && --i); ++ ++ return (i > 0) ? 1 : 0; ++} ++ ++static int alloc_all_urbs(rtl8150_t * dev) ++{ ++ dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!dev->rx_urb) ++ return 0; ++ dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!dev->tx_urb) { ++ usb_free_urb(dev->rx_urb); ++ return 0; ++ } ++ dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!dev->intr_urb) { ++ usb_free_urb(dev->rx_urb); ++ usb_free_urb(dev->tx_urb); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static void free_all_urbs(rtl8150_t * dev) ++{ ++ usb_free_urb(dev->rx_urb); ++ usb_free_urb(dev->tx_urb); ++ usb_free_urb(dev->intr_urb); ++} ++ ++static void unlink_all_urbs(rtl8150_t * dev) ++{ ++ usb_kill_urb(dev->rx_urb); ++ usb_kill_urb(dev->tx_urb); ++ usb_kill_urb(dev->intr_urb); ++} ++ ++static inline struct sk_buff *pull_skb(rtl8150_t *dev) ++{ ++ struct sk_buff *skb; ++ int i; ++ ++ for (i = 0; i < RX_SKB_POOL_SIZE; i++) { ++ if (dev->rx_skb_pool[i]) { ++ skb = dev->rx_skb_pool[i]; ++ dev->rx_skb_pool[i] = NULL; ++ return skb; ++ } ++ } ++ return NULL; ++} ++ ++static void read_bulk_callback(struct urb *urb) ++{ ++ rtl8150_t *dev; ++ unsigned pkt_len, res; ++ struct sk_buff *skb; ++ struct net_device *netdev; ++ u16 rx_stat; ++ int status = urb->status; ++ int result; ++ ++ dev = urb->context; ++ if (!dev) ++ return; ++ if (test_bit(RTL8150_UNPLUG, &dev->flags)) ++ return; ++ netdev = dev->netdev; ++ if (!netif_device_present(netdev)) ++ return; ++ ++ switch (status) { ++ case 0: ++ break; ++ case -ENOENT: ++ return; /* the urb is in unlink state */ ++ case -ETIME: ++ if (printk_ratelimit()) ++ dev_warn(&urb->dev->dev, "may be reset is needed?..\n"); ++ goto goon; ++ default: ++ if (printk_ratelimit()) ++ dev_warn(&urb->dev->dev, "Rx status %d\n", status); ++ goto goon; ++ } ++ ++ if (!dev->rx_skb) ++ goto resched; ++ /* protect against short packets (tell me why we got some?!?) */ ++ if (urb->actual_length < 4) ++ goto goon; ++ ++ res = urb->actual_length; ++ rx_stat = le16_to_cpu(*(__le16 *)(urb->transfer_buffer + res - 4)); ++ pkt_len = res - 4; ++ ++ skb_put(dev->rx_skb, pkt_len); ++ dev->rx_skb->protocol = eth_type_trans(dev->rx_skb, netdev); ++ netif_rx(dev->rx_skb); ++ netdev->stats.rx_packets++; ++ netdev->stats.rx_bytes += pkt_len; ++ ++ spin_lock(&dev->rx_pool_lock); ++ skb = pull_skb(dev); ++ spin_unlock(&dev->rx_pool_lock); ++ if (!skb) ++ goto resched; ++ ++ dev->rx_skb = skb; ++goon: ++ usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), ++ dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); ++ result = usb_submit_urb(dev->rx_urb, GFP_ATOMIC); ++ if (result == -ENODEV) ++ netif_device_detach(dev->netdev); ++ else if (result) { ++ set_bit(RX_URB_FAIL, &dev->flags); ++ goto resched; ++ } else { ++ clear_bit(RX_URB_FAIL, &dev->flags); ++ } ++ ++ return; ++resched: ++ tasklet_schedule(&dev->tl); ++} ++ ++static void write_bulk_callback(struct urb *urb) ++{ ++ rtl8150_t *dev; ++ int status = urb->status; ++ ++ dev = urb->context; ++ if (!dev) ++ return; ++ dev_kfree_skb_irq(dev->tx_skb); ++ if (!netif_device_present(dev->netdev)) ++ return; ++ if (status) ++ dev_info(&urb->dev->dev, "%s: Tx status %d\n", ++ dev->netdev->name, status); ++ dev->netdev->trans_start = jiffies; ++ netif_wake_queue(dev->netdev); ++} ++ ++static void intr_callback(struct urb *urb) ++{ ++ rtl8150_t *dev; ++ __u8 *d; ++ int status = urb->status; ++ int res; ++ ++ dev = urb->context; ++ if (!dev) ++ return; ++ switch (status) { ++ case 0: /* success */ ++ break; ++ case -ECONNRESET: /* unlink */ ++ case -ENOENT: ++ case -ESHUTDOWN: ++ return; ++ /* -EPIPE: should clear the halt */ ++ default: ++ dev_info(&urb->dev->dev, "%s: intr status %d\n", ++ dev->netdev->name, status); ++ goto resubmit; ++ } ++ ++ d = urb->transfer_buffer; ++ if (d[0] & TSR_ERRORS) { ++ dev->netdev->stats.tx_errors++; ++ if (d[INT_TSR] & (TSR_ECOL | TSR_JBR)) ++ dev->netdev->stats.tx_aborted_errors++; ++ if (d[INT_TSR] & TSR_LCOL) ++ dev->netdev->stats.tx_window_errors++; ++ if (d[INT_TSR] & TSR_LOSS_CRS) ++ dev->netdev->stats.tx_carrier_errors++; ++ } ++ /* Report link status changes to the network stack */ ++ if ((d[INT_MSR] & MSR_LINK) == 0) { ++ if (netif_carrier_ok(dev->netdev)) { ++ netif_carrier_off(dev->netdev); ++ netdev_dbg(dev->netdev, "%s: LINK LOST\n", __func__); ++ } ++ } else { ++ if (!netif_carrier_ok(dev->netdev)) { ++ netif_carrier_on(dev->netdev); ++ netdev_dbg(dev->netdev, "%s: LINK CAME BACK\n", __func__); ++ } ++ } ++ ++resubmit: ++ res = usb_submit_urb (urb, GFP_ATOMIC); ++ if (res == -ENODEV) ++ netif_device_detach(dev->netdev); ++ else if (res) ++ dev_err(&dev->udev->dev, ++ "can't resubmit intr, %s-%s/input0, status %d\n", ++ dev->udev->bus->bus_name, dev->udev->devpath, res); ++} ++ ++static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ rtl8150_t *dev = usb_get_intfdata(intf); ++ ++ netif_device_detach(dev->netdev); ++ ++ if (netif_running(dev->netdev)) { ++ usb_kill_urb(dev->rx_urb); ++ usb_kill_urb(dev->intr_urb); ++ } ++ return 0; ++} ++ ++static int rtl8150_resume(struct usb_interface *intf) ++{ ++ rtl8150_t *dev = usb_get_intfdata(intf); ++ ++ netif_device_attach(dev->netdev); ++ if (netif_running(dev->netdev)) { ++ dev->rx_urb->status = 0; ++ dev->rx_urb->actual_length = 0; ++ read_bulk_callback(dev->rx_urb); ++ ++ dev->intr_urb->status = 0; ++ dev->intr_urb->actual_length = 0; ++ intr_callback(dev->intr_urb); ++ } ++ return 0; ++} ++ ++/* ++** ++** network related part of the code ++** ++*/ ++ ++static void fill_skb_pool(rtl8150_t *dev) ++{ ++ struct sk_buff *skb; ++ int i; ++ ++ for (i = 0; i < RX_SKB_POOL_SIZE; i++) { ++ if (dev->rx_skb_pool[i]) ++ continue; ++ skb = dev_alloc_skb(RTL8150_MTU + 2); ++ if (!skb) { ++ return; ++ } ++ skb_reserve(skb, 2); ++ dev->rx_skb_pool[i] = skb; ++ } ++} ++ ++static void free_skb_pool(rtl8150_t *dev) ++{ ++ int i; ++ ++ for (i = 0; i < RX_SKB_POOL_SIZE; i++) ++ if (dev->rx_skb_pool[i]) ++ dev_kfree_skb(dev->rx_skb_pool[i]); ++} ++ ++static void rx_fixup(unsigned long data) ++{ ++ struct rtl8150 *dev = (struct rtl8150 *)data; ++ struct sk_buff *skb; ++ int status; ++ ++ spin_lock_irq(&dev->rx_pool_lock); ++ fill_skb_pool(dev); ++ spin_unlock_irq(&dev->rx_pool_lock); ++ if (test_bit(RX_URB_FAIL, &dev->flags)) ++ if (dev->rx_skb) ++ goto try_again; ++ spin_lock_irq(&dev->rx_pool_lock); ++ skb = pull_skb(dev); ++ spin_unlock_irq(&dev->rx_pool_lock); ++ if (skb == NULL) ++ goto tlsched; ++ dev->rx_skb = skb; ++ usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), ++ dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); ++try_again: ++ status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC); ++ if (status == -ENODEV) { ++ netif_device_detach(dev->netdev); ++ } else if (status) { ++ set_bit(RX_URB_FAIL, &dev->flags); ++ goto tlsched; ++ } else { ++ clear_bit(RX_URB_FAIL, &dev->flags); ++ } ++ ++ return; ++tlsched: ++ tasklet_schedule(&dev->tl); ++} ++ ++static int enable_net_traffic(rtl8150_t * dev) ++{ ++ u8 cr, tcr, rcr, msr; ++ ++ if (!rtl8150_reset(dev)) { ++ dev_warn(&dev->udev->dev, "device reset failed\n"); ++ } ++ /* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */ ++ rcr = 0x9e; ++ tcr = 0xd8; ++ cr = 0x0c; ++ if (!(rcr & 0x80)) ++ set_bit(RTL8150_HW_CRC, &dev->flags); ++ set_registers(dev, RCR, 1, &rcr); ++ set_registers(dev, TCR, 1, &tcr); ++ set_registers(dev, CR, 1, &cr); ++ get_registers(dev, MSR, 1, &msr); ++ ++ return 0; ++} ++ ++static void disable_net_traffic(rtl8150_t * dev) ++{ ++ u8 cr; ++ ++ get_registers(dev, CR, 1, &cr); ++ cr &= 0xf3; ++ set_registers(dev, CR, 1, &cr); ++} ++ ++static void rtl8150_tx_timeout(struct net_device *netdev) ++{ ++ rtl8150_t *dev = netdev_priv(netdev); ++ dev_warn(&netdev->dev, "Tx timeout.\n"); ++ usb_unlink_urb(dev->tx_urb); ++ netdev->stats.tx_errors++; ++} ++ ++static void rtl8150_set_multicast(struct net_device *netdev) ++{ ++ rtl8150_t *dev = netdev_priv(netdev); ++ u16 rx_creg = 0x9e; ++ ++ netif_stop_queue(netdev); ++ if (netdev->flags & IFF_PROMISC) { ++ rx_creg |= 0x0001; ++ dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name); ++ } else if (!netdev_mc_empty(netdev) || ++ (netdev->flags & IFF_ALLMULTI)) { ++ rx_creg &= 0xfffe; ++ rx_creg |= 0x0002; ++ dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name); ++ } else { ++ /* ~RX_MULTICAST, ~RX_PROMISCUOUS */ ++ rx_creg &= 0x00fc; ++ } ++ async_set_registers(dev, RCR, sizeof(rx_creg), rx_creg); ++ netif_wake_queue(netdev); ++} ++ ++static netdev_tx_t rtl8150_start_xmit(struct sk_buff *skb, ++ struct net_device *netdev) ++{ ++ rtl8150_t *dev = netdev_priv(netdev); ++ int count, res; ++ ++ netif_stop_queue(netdev); ++ count = (skb->len < 60) ? 60 : skb->len; ++ count = (count & 0x3f) ? count : count + 1; ++ dev->tx_skb = skb; ++ usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), ++ skb->data, count, write_bulk_callback, dev); ++ if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) { ++ /* Can we get/handle EPIPE here? */ ++ if (res == -ENODEV) ++ netif_device_detach(dev->netdev); ++ else { ++ dev_warn(&netdev->dev, "failed tx_urb %d\n", res); ++ netdev->stats.tx_errors++; ++ netif_start_queue(netdev); ++ } ++ } else { ++ netdev->stats.tx_packets++; ++ netdev->stats.tx_bytes += skb->len; ++ netdev->trans_start = jiffies; ++ } ++ ++ return NETDEV_TX_OK; ++} ++ ++ ++static void set_carrier(struct net_device *netdev) ++{ ++ rtl8150_t *dev = netdev_priv(netdev); ++ short tmp; ++ ++ get_registers(dev, CSCR, 2, &tmp); ++ if (tmp & CSCR_LINK_STATUS) ++ netif_carrier_on(netdev); ++ else ++ netif_carrier_off(netdev); ++} ++ ++static int rtl8150_open(struct net_device *netdev) ++{ ++ rtl8150_t *dev = netdev_priv(netdev); ++ int res; ++ ++ if (dev->rx_skb == NULL) ++ dev->rx_skb = pull_skb(dev); ++ if (!dev->rx_skb) ++ return -ENOMEM; ++ ++ set_registers(dev, IDR, 6, netdev->dev_addr); ++ ++ usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), ++ dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); ++ if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) { ++ if (res == -ENODEV) ++ netif_device_detach(dev->netdev); ++ dev_warn(&netdev->dev, "rx_urb submit failed: %d\n", res); ++ return res; ++ } ++ usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3), ++ dev->intr_buff, INTBUFSIZE, intr_callback, ++ dev, dev->intr_interval); ++ if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) { ++ if (res == -ENODEV) ++ netif_device_detach(dev->netdev); ++ dev_warn(&netdev->dev, "intr_urb submit failed: %d\n", res); ++ usb_kill_urb(dev->rx_urb); ++ return res; ++ } ++ enable_net_traffic(dev); ++ set_carrier(netdev); ++ netif_start_queue(netdev); ++ ++ return res; ++} ++ ++static int rtl8150_close(struct net_device *netdev) ++{ ++ rtl8150_t *dev = netdev_priv(netdev); ++ int res = 0; ++ ++ netif_stop_queue(netdev); ++ if (!test_bit(RTL8150_UNPLUG, &dev->flags)) ++ disable_net_traffic(dev); ++ unlink_all_urbs(dev); ++ ++ return res; ++} ++ ++static void rtl8150_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info) ++{ ++ rtl8150_t *dev = netdev_priv(netdev); ++ ++ strlcpy(info->driver, driver_name, sizeof(info->driver)); ++ strlcpy(info->version, DRIVER_VERSION, sizeof(info->version)); ++ usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info)); ++} ++ ++static int rtl8150_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ++{ ++ rtl8150_t *dev = netdev_priv(netdev); ++ short lpa, bmcr; ++ ++ ecmd->supported = (SUPPORTED_10baseT_Half | ++ SUPPORTED_10baseT_Full | ++ SUPPORTED_100baseT_Half | ++ SUPPORTED_100baseT_Full | ++ SUPPORTED_Autoneg | ++ SUPPORTED_TP | SUPPORTED_MII); ++ ecmd->port = PORT_TP; ++ ecmd->transceiver = XCVR_INTERNAL; ++ ecmd->phy_address = dev->phy; ++ get_registers(dev, BMCR, 2, &bmcr); ++ get_registers(dev, ANLP, 2, &lpa); ++ if (bmcr & BMCR_ANENABLE) { ++ u32 speed = ((lpa & (LPA_100HALF | LPA_100FULL)) ? ++ SPEED_100 : SPEED_10); ++ ethtool_cmd_speed_set(ecmd, speed); ++ ecmd->autoneg = AUTONEG_ENABLE; ++ if (speed == SPEED_100) ++ ecmd->duplex = (lpa & LPA_100FULL) ? ++ DUPLEX_FULL : DUPLEX_HALF; ++ else ++ ecmd->duplex = (lpa & LPA_10FULL) ? ++ DUPLEX_FULL : DUPLEX_HALF; ++ } else { ++ ecmd->autoneg = AUTONEG_DISABLE; ++ ethtool_cmd_speed_set(ecmd, ((bmcr & BMCR_SPEED100) ? ++ SPEED_100 : SPEED_10)); ++ ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? ++ DUPLEX_FULL : DUPLEX_HALF; ++ } ++ return 0; ++} ++ ++static const struct ethtool_ops ops = { ++ .get_drvinfo = rtl8150_get_drvinfo, ++ .get_settings = rtl8150_get_settings, ++ .get_link = ethtool_op_get_link ++}; ++ ++static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) ++{ ++ rtl8150_t *dev = netdev_priv(netdev); ++ u16 *data = (u16 *) & rq->ifr_ifru; ++ int res = 0; ++ ++ switch (cmd) { ++ case SIOCDEVPRIVATE: ++ data[0] = dev->phy; ++ case SIOCDEVPRIVATE + 1: ++ read_mii_word(dev, dev->phy, (data[1] & 0x1f), &data[3]); ++ break; ++ case SIOCDEVPRIVATE + 2: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ write_mii_word(dev, dev->phy, (data[1] & 0x1f), data[2]); ++ break; ++ default: ++ res = -EOPNOTSUPP; ++ } ++ ++ return res; ++} ++ ++static const struct net_device_ops rtl8150_netdev_ops = { ++ .ndo_open = rtl8150_open, ++ .ndo_stop = rtl8150_close, ++ .ndo_do_ioctl = rtl8150_ioctl, ++ .ndo_start_xmit = rtl8150_start_xmit, ++ .ndo_tx_timeout = rtl8150_tx_timeout, ++ .ndo_set_rx_mode = rtl8150_set_multicast, ++ .ndo_set_mac_address = rtl8150_set_mac_address, ++ ++ .ndo_change_mtu = eth_change_mtu, ++ .ndo_validate_addr = eth_validate_addr, ++}; ++ ++static int rtl8150_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *udev = interface_to_usbdev(intf); ++ rtl8150_t *dev; ++ struct net_device *netdev; ++ ++ netdev = alloc_etherdev(sizeof(rtl8150_t)); ++ if (!netdev) ++ return -ENOMEM; ++ ++ dev = netdev_priv(netdev); ++ ++ dev->intr_buff = kmalloc(INTBUFSIZE, GFP_KERNEL); ++ if (!dev->intr_buff) { ++ free_netdev(netdev); ++ return -ENOMEM; ++ } ++ ++ tasklet_init(&dev->tl, rx_fixup, (unsigned long)dev); ++ spin_lock_init(&dev->rx_pool_lock); ++ ++ dev->udev = udev; ++ dev->netdev = netdev; ++ netdev->netdev_ops = &rtl8150_netdev_ops; ++ netdev->watchdog_timeo = RTL8150_TX_TIMEOUT; ++ netdev->ethtool_ops = &ops; ++ dev->intr_interval = 100; /* 100ms */ ++ ++ if (!alloc_all_urbs(dev)) { ++ dev_err(&intf->dev, "out of memory\n"); ++ goto out; ++ } ++ if (!rtl8150_reset(dev)) { ++ dev_err(&intf->dev, "couldn't reset the device\n"); ++ goto out1; ++ } ++ fill_skb_pool(dev); ++ set_ethernet_addr(dev); ++ ++ usb_set_intfdata(intf, dev); ++ SET_NETDEV_DEV(netdev, &intf->dev); ++ if (register_netdev(netdev) != 0) { ++ dev_err(&intf->dev, "couldn't register the device\n"); ++ goto out2; ++ } ++ ++ dev_info(&intf->dev, "%s: rtl8150 is detected\n", netdev->name); ++ ++ return 0; ++ ++out2: ++ usb_set_intfdata(intf, NULL); ++ free_skb_pool(dev); ++out1: ++ free_all_urbs(dev); ++out: ++ kfree(dev->intr_buff); ++ free_netdev(netdev); ++ return -EIO; ++} ++ ++static void rtl8150_disconnect(struct usb_interface *intf) ++{ ++ rtl8150_t *dev = usb_get_intfdata(intf); ++ ++ usb_set_intfdata(intf, NULL); ++ if (dev) { ++ set_bit(RTL8150_UNPLUG, &dev->flags); ++ tasklet_kill(&dev->tl); ++ unregister_netdev(dev->netdev); ++ unlink_all_urbs(dev); ++ free_all_urbs(dev); ++ free_skb_pool(dev); ++ if (dev->rx_skb) ++ dev_kfree_skb(dev->rx_skb); ++ kfree(dev->intr_buff); ++ free_netdev(dev->netdev); ++ } ++} ++ ++static struct usb_driver rtl8150_driver = { ++ .name = driver_name, ++ .probe = rtl8150_probe, ++ .disconnect = rtl8150_disconnect, ++ .id_table = rtl8150_table, ++ .suspend = rtl8150_suspend, ++ .resume = rtl8150_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(rtl8150_driver); ++ ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/smsc75xx.c backports-3.18.1-1/drivers/net/usb/smsc75xx.c +--- backports-3.18.1-1.org/drivers/net/usb/smsc75xx.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/smsc75xx.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,2286 @@ ++ /*************************************************************************** ++ * ++ * Copyright (C) 2007-2010 SMSC ++ * ++ * 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 http://www.gnu.org/licenses/. ++ * ++ *****************************************************************************/ ++ ++#include <linux/module.h> ++#include <linux/kmod.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/bitrev.h> ++#include <linux/crc16.h> ++#include <linux/crc32.h> ++#include <linux/usb/usbnet.h> ++#include <linux/slab.h> ++#include "smsc75xx.h" ++ ++#define SMSC_CHIPNAME "smsc75xx" ++#define SMSC_DRIVER_VERSION "1.0.0" ++#define HS_USB_PKT_SIZE (512) ++#define FS_USB_PKT_SIZE (64) ++#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE) ++#define DEFAULT_FS_BURST_CAP_SIZE (6 * 1024 + 33 * FS_USB_PKT_SIZE) ++#define DEFAULT_BULK_IN_DELAY (0x00002000) ++#define MAX_SINGLE_PACKET_SIZE (9000) ++#define LAN75XX_EEPROM_MAGIC (0x7500) ++#define EEPROM_MAC_OFFSET (0x01) ++#define DEFAULT_TX_CSUM_ENABLE (true) ++#define DEFAULT_RX_CSUM_ENABLE (true) ++#define SMSC75XX_INTERNAL_PHY_ID (1) ++#define SMSC75XX_TX_OVERHEAD (8) ++#define MAX_RX_FIFO_SIZE (20 * 1024) ++#define MAX_TX_FIFO_SIZE (12 * 1024) ++#define USB_VENDOR_ID_SMSC (0x0424) ++#define USB_PRODUCT_ID_LAN7500 (0x7500) ++#define USB_PRODUCT_ID_LAN7505 (0x7505) ++#define RXW_PADDING 2 ++#define SUPPORTED_WAKE (WAKE_PHY | WAKE_UCAST | WAKE_BCAST | \ ++ WAKE_MCAST | WAKE_ARP | WAKE_MAGIC) ++ ++#define SUSPEND_SUSPEND0 (0x01) ++#define SUSPEND_SUSPEND1 (0x02) ++#define SUSPEND_SUSPEND2 (0x04) ++#define SUSPEND_SUSPEND3 (0x08) ++#define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \ ++ SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) ++ ++struct smsc75xx_priv { ++ struct usbnet *dev; ++ u32 rfe_ctl; ++ u32 wolopts; ++ u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN]; ++ struct mutex dataport_mutex; ++ spinlock_t rfe_ctl_lock; ++ struct work_struct set_multicast; ++ u8 suspend_flags; ++}; ++ ++struct usb_context { ++ struct usb_ctrlrequest req; ++ struct usbnet *dev; ++}; ++ ++static bool turbo_mode = true; ++module_param(turbo_mode, bool, 0644); ++MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); ++ ++static int __must_check __smsc75xx_read_reg(struct usbnet *dev, u32 index, ++ u32 *data, int in_pm) ++{ ++ u32 buf; ++ int ret; ++ int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16); ++ ++ BUG_ON(!dev); ++ ++ if (!in_pm) ++ fn = usbnet_read_cmd; ++ else ++ fn = usbnet_read_cmd_nopm; ++ ++ ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN ++ | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ 0, index, &buf, 4); ++ if (unlikely(ret < 0)) ++ netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n", ++ index, ret); ++ ++ le32_to_cpus(&buf); ++ *data = buf; ++ ++ return ret; ++} ++ ++static int __must_check __smsc75xx_write_reg(struct usbnet *dev, u32 index, ++ u32 data, int in_pm) ++{ ++ u32 buf; ++ int ret; ++ int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16); ++ ++ BUG_ON(!dev); ++ ++ if (!in_pm) ++ fn = usbnet_write_cmd; ++ else ++ fn = usbnet_write_cmd_nopm; ++ ++ buf = data; ++ cpu_to_le32s(&buf); ++ ++ ret = fn(dev, USB_VENDOR_REQUEST_WRITE_REGISTER, USB_DIR_OUT ++ | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ 0, index, &buf, 4); ++ if (unlikely(ret < 0)) ++ netdev_warn(dev->net, "Failed to write reg index 0x%08x: %d\n", ++ index, ret); ++ ++ return ret; ++} ++ ++static int __must_check smsc75xx_read_reg_nopm(struct usbnet *dev, u32 index, ++ u32 *data) ++{ ++ return __smsc75xx_read_reg(dev, index, data, 1); ++} ++ ++static int __must_check smsc75xx_write_reg_nopm(struct usbnet *dev, u32 index, ++ u32 data) ++{ ++ return __smsc75xx_write_reg(dev, index, data, 1); ++} ++ ++static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index, ++ u32 *data) ++{ ++ return __smsc75xx_read_reg(dev, index, data, 0); ++} ++ ++static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index, ++ u32 data) ++{ ++ return __smsc75xx_write_reg(dev, index, data, 0); ++} ++ ++/* Loop until the read is completed with timeout ++ * called with phy_mutex held */ ++static __must_check int __smsc75xx_phy_wait_not_busy(struct usbnet *dev, ++ int in_pm) ++{ ++ unsigned long start_time = jiffies; ++ u32 val; ++ int ret; ++ ++ do { ++ ret = __smsc75xx_read_reg(dev, MII_ACCESS, &val, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading MII_ACCESS\n"); ++ return ret; ++ } ++ ++ if (!(val & MII_ACCESS_BUSY)) ++ return 0; ++ } while (!time_after(jiffies, start_time + HZ)); ++ ++ return -EIO; ++} ++ ++static int __smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx, ++ int in_pm) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ u32 val, addr; ++ int ret; ++ ++ mutex_lock(&dev->phy_mutex); ++ ++ /* confirm MII not busy */ ++ ret = __smsc75xx_phy_wait_not_busy(dev, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "MII is busy in smsc75xx_mdio_read\n"); ++ goto done; ++ } ++ ++ /* set the address, index & direction (read from PHY) */ ++ phy_id &= dev->mii.phy_id_mask; ++ idx &= dev->mii.reg_num_mask; ++ addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) ++ | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) ++ | MII_ACCESS_READ | MII_ACCESS_BUSY; ++ ret = __smsc75xx_write_reg(dev, MII_ACCESS, addr, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing MII_ACCESS\n"); ++ goto done; ++ } ++ ++ ret = __smsc75xx_phy_wait_not_busy(dev, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Timed out reading MII reg %02X\n", idx); ++ goto done; ++ } ++ ++ ret = __smsc75xx_read_reg(dev, MII_DATA, &val, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading MII_DATA\n"); ++ goto done; ++ } ++ ++ ret = (u16)(val & 0xFFFF); ++ ++done: ++ mutex_unlock(&dev->phy_mutex); ++ return ret; ++} ++ ++static void __smsc75xx_mdio_write(struct net_device *netdev, int phy_id, ++ int idx, int regval, int in_pm) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ u32 val, addr; ++ int ret; ++ ++ mutex_lock(&dev->phy_mutex); ++ ++ /* confirm MII not busy */ ++ ret = __smsc75xx_phy_wait_not_busy(dev, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "MII is busy in smsc75xx_mdio_write\n"); ++ goto done; ++ } ++ ++ val = regval; ++ ret = __smsc75xx_write_reg(dev, MII_DATA, val, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing MII_DATA\n"); ++ goto done; ++ } ++ ++ /* set the address, index & direction (write to PHY) */ ++ phy_id &= dev->mii.phy_id_mask; ++ idx &= dev->mii.reg_num_mask; ++ addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) ++ | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) ++ | MII_ACCESS_WRITE | MII_ACCESS_BUSY; ++ ret = __smsc75xx_write_reg(dev, MII_ACCESS, addr, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing MII_ACCESS\n"); ++ goto done; ++ } ++ ++ ret = __smsc75xx_phy_wait_not_busy(dev, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Timed out writing MII reg %02X\n", idx); ++ goto done; ++ } ++ ++done: ++ mutex_unlock(&dev->phy_mutex); ++} ++ ++static int smsc75xx_mdio_read_nopm(struct net_device *netdev, int phy_id, ++ int idx) ++{ ++ return __smsc75xx_mdio_read(netdev, phy_id, idx, 1); ++} ++ ++static void smsc75xx_mdio_write_nopm(struct net_device *netdev, int phy_id, ++ int idx, int regval) ++{ ++ __smsc75xx_mdio_write(netdev, phy_id, idx, regval, 1); ++} ++ ++static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx) ++{ ++ return __smsc75xx_mdio_read(netdev, phy_id, idx, 0); ++} ++ ++static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx, ++ int regval) ++{ ++ __smsc75xx_mdio_write(netdev, phy_id, idx, regval, 0); ++} ++ ++static int smsc75xx_wait_eeprom(struct usbnet *dev) ++{ ++ unsigned long start_time = jiffies; ++ u32 val; ++ int ret; ++ ++ do { ++ ret = smsc75xx_read_reg(dev, E2P_CMD, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading E2P_CMD\n"); ++ return ret; ++ } ++ ++ if (!(val & E2P_CMD_BUSY) || (val & E2P_CMD_TIMEOUT)) ++ break; ++ udelay(40); ++ } while (!time_after(jiffies, start_time + HZ)); ++ ++ if (val & (E2P_CMD_TIMEOUT | E2P_CMD_BUSY)) { ++ netdev_warn(dev->net, "EEPROM read operation timeout\n"); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static int smsc75xx_eeprom_confirm_not_busy(struct usbnet *dev) ++{ ++ unsigned long start_time = jiffies; ++ u32 val; ++ int ret; ++ ++ do { ++ ret = smsc75xx_read_reg(dev, E2P_CMD, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading E2P_CMD\n"); ++ return ret; ++ } ++ ++ if (!(val & E2P_CMD_BUSY)) ++ return 0; ++ ++ udelay(40); ++ } while (!time_after(jiffies, start_time + HZ)); ++ ++ netdev_warn(dev->net, "EEPROM is busy\n"); ++ return -EIO; ++} ++ ++static int smsc75xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length, ++ u8 *data) ++{ ++ u32 val; ++ int i, ret; ++ ++ BUG_ON(!dev); ++ BUG_ON(!data); ++ ++ ret = smsc75xx_eeprom_confirm_not_busy(dev); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < length; i++) { ++ val = E2P_CMD_BUSY | E2P_CMD_READ | (offset & E2P_CMD_ADDR); ++ ret = smsc75xx_write_reg(dev, E2P_CMD, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing E2P_CMD\n"); ++ return ret; ++ } ++ ++ ret = smsc75xx_wait_eeprom(dev); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc75xx_read_reg(dev, E2P_DATA, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading E2P_DATA\n"); ++ return ret; ++ } ++ ++ data[i] = val & 0xFF; ++ offset++; ++ } ++ ++ return 0; ++} ++ ++static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length, ++ u8 *data) ++{ ++ u32 val; ++ int i, ret; ++ ++ BUG_ON(!dev); ++ BUG_ON(!data); ++ ++ ret = smsc75xx_eeprom_confirm_not_busy(dev); ++ if (ret) ++ return ret; ++ ++ /* Issue write/erase enable command */ ++ val = E2P_CMD_BUSY | E2P_CMD_EWEN; ++ ret = smsc75xx_write_reg(dev, E2P_CMD, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing E2P_CMD\n"); ++ return ret; ++ } ++ ++ ret = smsc75xx_wait_eeprom(dev); ++ if (ret < 0) ++ return ret; ++ ++ for (i = 0; i < length; i++) { ++ ++ /* Fill data register */ ++ val = data[i]; ++ ret = smsc75xx_write_reg(dev, E2P_DATA, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing E2P_DATA\n"); ++ return ret; ++ } ++ ++ /* Send "write" command */ ++ val = E2P_CMD_BUSY | E2P_CMD_WRITE | (offset & E2P_CMD_ADDR); ++ ret = smsc75xx_write_reg(dev, E2P_CMD, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing E2P_CMD\n"); ++ return ret; ++ } ++ ++ ret = smsc75xx_wait_eeprom(dev); ++ if (ret < 0) ++ return ret; ++ ++ offset++; ++ } ++ ++ return 0; ++} ++ ++static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev) ++{ ++ int i, ret; ++ ++ for (i = 0; i < 100; i++) { ++ u32 dp_sel; ++ ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading DP_SEL\n"); ++ return ret; ++ } ++ ++ if (dp_sel & DP_SEL_DPRDY) ++ return 0; ++ ++ udelay(40); ++ } ++ ++ netdev_warn(dev->net, "smsc75xx_dataport_wait_not_busy timed out\n"); ++ ++ return -EIO; ++} ++ ++static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr, ++ u32 length, u32 *buf) ++{ ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ u32 dp_sel; ++ int i, ret; ++ ++ mutex_lock(&pdata->dataport_mutex); ++ ++ ret = smsc75xx_dataport_wait_not_busy(dev); ++ if (ret < 0) { ++ netdev_warn(dev->net, "smsc75xx_dataport_write busy on entry\n"); ++ goto done; ++ } ++ ++ ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading DP_SEL\n"); ++ goto done; ++ } ++ ++ dp_sel &= ~DP_SEL_RSEL; ++ dp_sel |= ram_select; ++ ret = smsc75xx_write_reg(dev, DP_SEL, dp_sel); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing DP_SEL\n"); ++ goto done; ++ } ++ ++ for (i = 0; i < length; i++) { ++ ret = smsc75xx_write_reg(dev, DP_ADDR, addr + i); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing DP_ADDR\n"); ++ goto done; ++ } ++ ++ ret = smsc75xx_write_reg(dev, DP_DATA, buf[i]); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing DP_DATA\n"); ++ goto done; ++ } ++ ++ ret = smsc75xx_write_reg(dev, DP_CMD, DP_CMD_WRITE); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing DP_CMD\n"); ++ goto done; ++ } ++ ++ ret = smsc75xx_dataport_wait_not_busy(dev); ++ if (ret < 0) { ++ netdev_warn(dev->net, "smsc75xx_dataport_write timeout\n"); ++ goto done; ++ } ++ } ++ ++done: ++ mutex_unlock(&pdata->dataport_mutex); ++ return ret; ++} ++ ++/* returns hash bit number for given MAC address */ ++static u32 smsc75xx_hash(char addr[ETH_ALEN]) ++{ ++ return (ether_crc(ETH_ALEN, addr) >> 23) & 0x1ff; ++} ++ ++static void smsc75xx_deferred_multicast_write(struct work_struct *param) ++{ ++ struct smsc75xx_priv *pdata = ++ container_of(param, struct smsc75xx_priv, set_multicast); ++ struct usbnet *dev = pdata->dev; ++ int ret; ++ ++ netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x\n", ++ pdata->rfe_ctl); ++ ++ smsc75xx_dataport_write(dev, DP_SEL_VHF, DP_SEL_VHF_VLAN_LEN, ++ DP_SEL_VHF_HASH_LEN, pdata->multicast_hash_table); ++ ++ ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); ++ if (ret < 0) ++ netdev_warn(dev->net, "Error writing RFE_CRL\n"); ++} ++ ++static void smsc75xx_set_multicast(struct net_device *netdev) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ unsigned long flags; ++ int i; ++ ++ spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); ++ ++ pdata->rfe_ctl &= ++ ~(RFE_CTL_AU | RFE_CTL_AM | RFE_CTL_DPF | RFE_CTL_MHF); ++ pdata->rfe_ctl |= RFE_CTL_AB; ++ ++ for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++) ++ pdata->multicast_hash_table[i] = 0; ++ ++ if (dev->net->flags & IFF_PROMISC) { ++ netif_dbg(dev, drv, dev->net, "promiscuous mode enabled\n"); ++ pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_AU; ++ } else if (dev->net->flags & IFF_ALLMULTI) { ++ netif_dbg(dev, drv, dev->net, "receive all multicast enabled\n"); ++ pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_DPF; ++ } else if (!netdev_mc_empty(dev->net)) { ++ struct netdev_hw_addr *ha; ++ ++ netif_dbg(dev, drv, dev->net, "receive multicast hash filter\n"); ++ ++ pdata->rfe_ctl |= RFE_CTL_MHF | RFE_CTL_DPF; ++ ++ netdev_for_each_mc_addr(ha, netdev) { ++ u32 bitnum = smsc75xx_hash(ha->addr); ++ pdata->multicast_hash_table[bitnum / 32] |= ++ (1 << (bitnum % 32)); ++ } ++ } else { ++ netif_dbg(dev, drv, dev->net, "receive own packets only\n"); ++ pdata->rfe_ctl |= RFE_CTL_DPF; ++ } ++ ++ spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); ++ ++ /* defer register writes to a sleepable context */ ++ schedule_work(&pdata->set_multicast); ++} ++ ++static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex, ++ u16 lcladv, u16 rmtadv) ++{ ++ u32 flow = 0, fct_flow = 0; ++ int ret; ++ ++ if (duplex == DUPLEX_FULL) { ++ u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv); ++ ++ if (cap & FLOW_CTRL_TX) { ++ flow = (FLOW_TX_FCEN | 0xFFFF); ++ /* set fct_flow thresholds to 20% and 80% */ ++ fct_flow = (8 << 8) | 32; ++ } ++ ++ if (cap & FLOW_CTRL_RX) ++ flow |= FLOW_RX_FCEN; ++ ++ netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s\n", ++ (cap & FLOW_CTRL_RX ? "enabled" : "disabled"), ++ (cap & FLOW_CTRL_TX ? "enabled" : "disabled")); ++ } else { ++ netif_dbg(dev, link, dev->net, "half duplex\n"); ++ } ++ ++ ret = smsc75xx_write_reg(dev, FLOW, flow); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing FLOW\n"); ++ return ret; ++ } ++ ++ ret = smsc75xx_write_reg(dev, FCT_FLOW, fct_flow); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing FCT_FLOW\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int smsc75xx_link_reset(struct usbnet *dev) ++{ ++ struct mii_if_info *mii = &dev->mii; ++ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; ++ u16 lcladv, rmtadv; ++ int ret; ++ ++ /* write to clear phy interrupt status */ ++ smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, ++ PHY_INT_SRC_CLEAR_ALL); ++ ++ ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing INT_STS\n"); ++ return ret; ++ } ++ ++ mii_check_media(mii, 1, 1); ++ mii_ethtool_gset(&dev->mii, &ecmd); ++ lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE); ++ rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA); ++ ++ netif_dbg(dev, link, dev->net, "speed: %u duplex: %d lcladv: %04x rmtadv: %04x\n", ++ ethtool_cmd_speed(&ecmd), ecmd.duplex, lcladv, rmtadv); ++ ++ return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv); ++} ++ ++static void smsc75xx_status(struct usbnet *dev, struct urb *urb) ++{ ++ u32 intdata; ++ ++ if (urb->actual_length != 4) { ++ netdev_warn(dev->net, "unexpected urb length %d\n", ++ urb->actual_length); ++ return; ++ } ++ ++ memcpy(&intdata, urb->transfer_buffer, 4); ++ le32_to_cpus(&intdata); ++ ++ netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata); ++ ++ if (intdata & INT_ENP_PHY_INT) ++ usbnet_defer_kevent(dev, EVENT_LINK_RESET); ++ else ++ netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n", ++ intdata); ++} ++ ++static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net) ++{ ++ return MAX_EEPROM_SIZE; ++} ++ ++static int smsc75xx_ethtool_get_eeprom(struct net_device *netdev, ++ struct ethtool_eeprom *ee, u8 *data) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ ++ ee->magic = LAN75XX_EEPROM_MAGIC; ++ ++ return smsc75xx_read_eeprom(dev, ee->offset, ee->len, data); ++} ++ ++static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev, ++ struct ethtool_eeprom *ee, u8 *data) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ ++ if (ee->magic != LAN75XX_EEPROM_MAGIC) { ++ netdev_warn(dev->net, "EEPROM: magic value mismatch: 0x%x\n", ++ ee->magic); ++ return -EINVAL; ++ } ++ ++ return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data); ++} ++ ++static void smsc75xx_ethtool_get_wol(struct net_device *net, ++ struct ethtool_wolinfo *wolinfo) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ ++ wolinfo->supported = SUPPORTED_WAKE; ++ wolinfo->wolopts = pdata->wolopts; ++} ++ ++static int smsc75xx_ethtool_set_wol(struct net_device *net, ++ struct ethtool_wolinfo *wolinfo) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ int ret; ++ ++ pdata->wolopts = wolinfo->wolopts & SUPPORTED_WAKE; ++ ++ ret = device_set_wakeup_enable(&dev->udev->dev, pdata->wolopts); ++ if (ret < 0) ++ netdev_warn(dev->net, "device_set_wakeup_enable error %d\n", ret); ++ ++ return ret; ++} ++ ++static const struct ethtool_ops smsc75xx_ethtool_ops = { ++ .get_link = usbnet_get_link, ++ .nway_reset = usbnet_nway_reset, ++ .get_drvinfo = usbnet_get_drvinfo, ++ .get_msglevel = usbnet_get_msglevel, ++ .set_msglevel = usbnet_set_msglevel, ++ .get_settings = usbnet_get_settings, ++ .set_settings = usbnet_set_settings, ++ .get_eeprom_len = smsc75xx_ethtool_get_eeprom_len, ++ .get_eeprom = smsc75xx_ethtool_get_eeprom, ++ .set_eeprom = smsc75xx_ethtool_set_eeprom, ++ .get_wol = smsc75xx_ethtool_get_wol, ++ .set_wol = smsc75xx_ethtool_set_wol, ++}; ++ ++static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ ++ if (!netif_running(netdev)) ++ return -EINVAL; ++ ++ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); ++} ++ ++static void smsc75xx_init_mac_address(struct usbnet *dev) ++{ ++ /* try reading mac address from EEPROM */ ++ if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, ++ dev->net->dev_addr) == 0) { ++ if (is_valid_ether_addr(dev->net->dev_addr)) { ++ /* eeprom values are valid so use them */ ++ netif_dbg(dev, ifup, dev->net, ++ "MAC address read from EEPROM\n"); ++ return; ++ } ++ } ++ ++ /* no eeprom, or eeprom values are invalid. generate random MAC */ ++ eth_hw_addr_random(dev->net); ++ netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); ++} ++ ++static int smsc75xx_set_mac_address(struct usbnet *dev) ++{ ++ u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 | ++ dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24; ++ u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8; ++ ++ int ret = smsc75xx_write_reg(dev, RX_ADDRH, addr_hi); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write RX_ADDRH: %d\n", ret); ++ return ret; ++ } ++ ++ ret = smsc75xx_write_reg(dev, RX_ADDRL, addr_lo); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write RX_ADDRL: %d\n", ret); ++ return ret; ++ } ++ ++ addr_hi |= ADDR_FILTX_FB_VALID; ++ ret = smsc75xx_write_reg(dev, ADDR_FILTX, addr_hi); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write ADDR_FILTX: %d\n", ret); ++ return ret; ++ } ++ ++ ret = smsc75xx_write_reg(dev, ADDR_FILTX + 4, addr_lo); ++ if (ret < 0) ++ netdev_warn(dev->net, "Failed to write ADDR_FILTX+4: %d\n", ret); ++ ++ return ret; ++} ++ ++static int smsc75xx_phy_initialize(struct usbnet *dev) ++{ ++ int bmcr, ret, timeout = 0; ++ ++ /* Initialize MII structure */ ++ dev->mii.dev = dev->net; ++ dev->mii.mdio_read = smsc75xx_mdio_read; ++ dev->mii.mdio_write = smsc75xx_mdio_write; ++ dev->mii.phy_id_mask = 0x1f; ++ dev->mii.reg_num_mask = 0x1f; ++ dev->mii.supports_gmii = 1; ++ dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID; ++ ++ /* reset phy and wait for reset to complete */ ++ smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); ++ ++ do { ++ msleep(10); ++ bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); ++ if (bmcr < 0) { ++ netdev_warn(dev->net, "Error reading MII_BMCR\n"); ++ return bmcr; ++ } ++ timeout++; ++ } while ((bmcr & BMCR_RESET) && (timeout < 100)); ++ ++ if (timeout >= 100) { ++ netdev_warn(dev->net, "timeout on PHY Reset\n"); ++ return -EIO; ++ } ++ ++ smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ++ ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | ++ ADVERTISE_PAUSE_ASYM); ++ smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000, ++ ADVERTISE_1000FULL); ++ ++ /* read and write to clear phy interrupt status */ ++ ret = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PHY_INT_SRC\n"); ++ return ret; ++ } ++ ++ smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_SRC, 0xffff); ++ ++ smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK, ++ PHY_INT_MASK_DEFAULT); ++ mii_nway_restart(&dev->mii); ++ ++ netif_dbg(dev, ifup, dev->net, "phy initialised successfully\n"); ++ return 0; ++} ++ ++static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size) ++{ ++ int ret = 0; ++ u32 buf; ++ bool rxenabled; ++ ++ ret = smsc75xx_read_reg(dev, MAC_RX, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read MAC_RX: %d\n", ret); ++ return ret; ++ } ++ ++ rxenabled = ((buf & MAC_RX_RXEN) != 0); ++ ++ if (rxenabled) { ++ buf &= ~MAC_RX_RXEN; ++ ret = smsc75xx_write_reg(dev, MAC_RX, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write MAC_RX: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ /* add 4 to size for FCS */ ++ buf &= ~MAC_RX_MAX_SIZE; ++ buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT) & MAC_RX_MAX_SIZE); ++ ++ ret = smsc75xx_write_reg(dev, MAC_RX, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write MAC_RX: %d\n", ret); ++ return ret; ++ } ++ ++ if (rxenabled) { ++ buf |= MAC_RX_RXEN; ++ ret = smsc75xx_write_reg(dev, MAC_RX, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write MAC_RX: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ int ret; ++ ++ if (new_mtu > MAX_SINGLE_PACKET_SIZE) ++ return -EINVAL; ++ ++ ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to set mac rx frame length\n"); ++ return ret; ++ } ++ ++ return usbnet_change_mtu(netdev, new_mtu); ++} ++ ++/* Enable or disable Rx checksum offload engine */ ++static int smsc75xx_set_features(struct net_device *netdev, ++ netdev_features_t features) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); ++ ++ if (features & NETIF_F_RXCSUM) ++ pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM; ++ else ++ pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM); ++ ++ spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); ++ /* it's racing here! */ ++ ++ ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); ++ if (ret < 0) ++ netdev_warn(dev->net, "Error writing RFE_CTL\n"); ++ ++ return ret; ++} ++ ++static int smsc75xx_wait_ready(struct usbnet *dev, int in_pm) ++{ ++ int timeout = 0; ++ ++ do { ++ u32 buf; ++ int ret; ++ ++ ret = __smsc75xx_read_reg(dev, PMT_CTL, &buf, in_pm); ++ ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ if (buf & PMT_CTL_DEV_RDY) ++ return 0; ++ ++ msleep(10); ++ timeout++; ++ } while (timeout < 100); ++ ++ netdev_warn(dev->net, "timeout waiting for device ready\n"); ++ return -EIO; ++} ++ ++static int smsc75xx_reset(struct usbnet *dev) ++{ ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ u32 buf; ++ int ret = 0, timeout; ++ ++ netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset\n"); ++ ++ ret = smsc75xx_wait_ready(dev, 0); ++ if (ret < 0) { ++ netdev_warn(dev->net, "device not ready in smsc75xx_reset\n"); ++ return ret; ++ } ++ ++ ret = smsc75xx_read_reg(dev, HW_CFG, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); ++ return ret; ++ } ++ ++ buf |= HW_CFG_LRST; ++ ++ ret = smsc75xx_write_reg(dev, HW_CFG, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write HW_CFG: %d\n", ret); ++ return ret; ++ } ++ ++ timeout = 0; ++ do { ++ msleep(10); ++ ret = smsc75xx_read_reg(dev, HW_CFG, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); ++ return ret; ++ } ++ timeout++; ++ } while ((buf & HW_CFG_LRST) && (timeout < 100)); ++ ++ if (timeout >= 100) { ++ netdev_warn(dev->net, "timeout on completion of Lite Reset\n"); ++ return -EIO; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "Lite reset complete, resetting PHY\n"); ++ ++ ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ buf |= PMT_CTL_PHY_RST; ++ ++ ret = smsc75xx_write_reg(dev, PMT_CTL, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write PMT_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ timeout = 0; ++ do { ++ msleep(10); ++ ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n", ret); ++ return ret; ++ } ++ timeout++; ++ } while ((buf & PMT_CTL_PHY_RST) && (timeout < 100)); ++ ++ if (timeout >= 100) { ++ netdev_warn(dev->net, "timeout waiting for PHY Reset\n"); ++ return -EIO; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "PHY reset complete\n"); ++ ++ ret = smsc75xx_set_mac_address(dev); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to set mac address\n"); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "MAC Address: %pM\n", ++ dev->net->dev_addr); ++ ++ ret = smsc75xx_read_reg(dev, HW_CFG, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x\n", ++ buf); ++ ++ buf |= HW_CFG_BIR; ++ ++ ret = smsc75xx_write_reg(dev, HW_CFG, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write HW_CFG: %d\n", ret); ++ return ret; ++ } ++ ++ ret = smsc75xx_read_reg(dev, HW_CFG, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after writing HW_CFG_BIR: 0x%08x\n", ++ buf); ++ ++ if (!turbo_mode) { ++ buf = 0; ++ dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; ++ } else if (dev->udev->speed == USB_SPEED_HIGH) { ++ buf = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; ++ dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; ++ } else { ++ buf = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; ++ dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n", ++ (ulong)dev->rx_urb_size); ++ ++ ret = smsc75xx_write_reg(dev, BURST_CAP, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write BURST_CAP: %d\n", ret); ++ return ret; ++ } ++ ++ ret = smsc75xx_read_reg(dev, BURST_CAP, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read BURST_CAP: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, ++ "Read Value from BURST_CAP after writing: 0x%08x\n", buf); ++ ++ ret = smsc75xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write BULK_IN_DLY: %d\n", ret); ++ return ret; ++ } ++ ++ ret = smsc75xx_read_reg(dev, BULK_IN_DLY, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read BULK_IN_DLY: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, ++ "Read Value from BULK_IN_DLY after writing: 0x%08x\n", buf); ++ ++ if (turbo_mode) { ++ ret = smsc75xx_read_reg(dev, HW_CFG, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x\n", buf); ++ ++ buf |= (HW_CFG_MEF | HW_CFG_BCE); ++ ++ ret = smsc75xx_write_reg(dev, HW_CFG, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write HW_CFG: %d\n", ret); ++ return ret; ++ } ++ ++ ret = smsc75xx_read_reg(dev, HW_CFG, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x\n", buf); ++ } ++ ++ /* set FIFO sizes */ ++ buf = (MAX_RX_FIFO_SIZE - 512) / 512; ++ ret = smsc75xx_write_reg(dev, FCT_RX_FIFO_END, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write FCT_RX_FIFO_END: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "FCT_RX_FIFO_END set to 0x%08x\n", buf); ++ ++ buf = (MAX_TX_FIFO_SIZE - 512) / 512; ++ ret = smsc75xx_write_reg(dev, FCT_TX_FIFO_END, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write FCT_TX_FIFO_END: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "FCT_TX_FIFO_END set to 0x%08x\n", buf); ++ ++ ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write INT_STS: %d\n", ret); ++ return ret; ++ } ++ ++ ret = smsc75xx_read_reg(dev, ID_REV, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read ID_REV: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", buf); ++ ++ ret = smsc75xx_read_reg(dev, E2P_CMD, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read E2P_CMD: %d\n", ret); ++ return ret; ++ } ++ ++ /* only set default GPIO/LED settings if no EEPROM is detected */ ++ if (!(buf & E2P_CMD_LOADED)) { ++ ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read LED_GPIO_CFG: %d\n", ret); ++ return ret; ++ } ++ ++ buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL); ++ buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL; ++ ++ ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write LED_GPIO_CFG: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ ret = smsc75xx_write_reg(dev, FLOW, 0); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write FLOW: %d\n", ret); ++ return ret; ++ } ++ ++ ret = smsc75xx_write_reg(dev, FCT_FLOW, 0); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write FCT_FLOW: %d\n", ret); ++ return ret; ++ } ++ ++ /* Don't need rfe_ctl_lock during initialisation */ ++ ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read RFE_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ pdata->rfe_ctl |= RFE_CTL_AB | RFE_CTL_DPF; ++ ++ ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write RFE_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read RFE_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x\n", ++ pdata->rfe_ctl); ++ ++ /* Enable or disable checksum offload engines */ ++ smsc75xx_set_features(dev->net, dev->net->features); ++ ++ smsc75xx_set_multicast(dev->net); ++ ++ ret = smsc75xx_phy_initialize(dev); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to initialize PHY: %d\n", ret); ++ return ret; ++ } ++ ++ ret = smsc75xx_read_reg(dev, INT_EP_CTL, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read INT_EP_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ /* enable PHY interrupts */ ++ buf |= INT_ENP_PHY_INT; ++ ++ ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write INT_EP_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ /* allow mac to detect speed and duplex from phy */ ++ ret = smsc75xx_read_reg(dev, MAC_CR, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read MAC_CR: %d\n", ret); ++ return ret; ++ } ++ ++ buf |= (MAC_CR_ADD | MAC_CR_ASD); ++ ret = smsc75xx_write_reg(dev, MAC_CR, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write MAC_CR: %d\n", ret); ++ return ret; ++ } ++ ++ ret = smsc75xx_read_reg(dev, MAC_TX, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read MAC_TX: %d\n", ret); ++ return ret; ++ } ++ ++ buf |= MAC_TX_TXEN; ++ ++ ret = smsc75xx_write_reg(dev, MAC_TX, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write MAC_TX: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "MAC_TX set to 0x%08x\n", buf); ++ ++ ret = smsc75xx_read_reg(dev, FCT_TX_CTL, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read FCT_TX_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ buf |= FCT_TX_CTL_EN; ++ ++ ret = smsc75xx_write_reg(dev, FCT_TX_CTL, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write FCT_TX_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x\n", buf); ++ ++ ret = smsc75xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to set max rx frame length\n"); ++ return ret; ++ } ++ ++ ret = smsc75xx_read_reg(dev, MAC_RX, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read MAC_RX: %d\n", ret); ++ return ret; ++ } ++ ++ buf |= MAC_RX_RXEN; ++ ++ ret = smsc75xx_write_reg(dev, MAC_RX, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write MAC_RX: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "MAC_RX set to 0x%08x\n", buf); ++ ++ ret = smsc75xx_read_reg(dev, FCT_RX_CTL, &buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read FCT_RX_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ buf |= FCT_RX_CTL_EN; ++ ++ ret = smsc75xx_write_reg(dev, FCT_RX_CTL, buf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write FCT_RX_CTL: %d\n", ret); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "FCT_RX_CTL set to 0x%08x\n", buf); ++ ++ netif_dbg(dev, ifup, dev->net, "smsc75xx_reset, return 0\n"); ++ return 0; ++} ++ ++static const struct net_device_ops smsc75xx_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = smsc75xx_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = smsc75xx_ioctl, ++ .ndo_set_rx_mode = smsc75xx_set_multicast, ++ .ndo_set_features = smsc75xx_set_features, ++}; ++ ++static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ struct smsc75xx_priv *pdata = NULL; ++ int ret; ++ ++ printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n"); ++ ++ ret = usbnet_get_endpoints(dev, intf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "usbnet_get_endpoints failed: %d\n", ret); ++ return ret; ++ } ++ ++ dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv), ++ GFP_KERNEL); ++ ++ pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ if (!pdata) ++ return -ENOMEM; ++ ++ pdata->dev = dev; ++ ++ spin_lock_init(&pdata->rfe_ctl_lock); ++ mutex_init(&pdata->dataport_mutex); ++ ++ INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write); ++ ++ if (DEFAULT_TX_CSUM_ENABLE) ++ dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; ++ ++ if (DEFAULT_RX_CSUM_ENABLE) ++ dev->net->features |= NETIF_F_RXCSUM; ++ ++ dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | ++ NETIF_F_RXCSUM; ++ ++ ret = smsc75xx_wait_ready(dev, 0); ++ if (ret < 0) { ++ netdev_warn(dev->net, "device not ready in smsc75xx_bind\n"); ++ return ret; ++ } ++ ++ smsc75xx_init_mac_address(dev); ++ ++ /* Init all registers */ ++ ret = smsc75xx_reset(dev); ++ if (ret < 0) { ++ netdev_warn(dev->net, "smsc75xx_reset error %d\n", ret); ++ return ret; ++ } ++ ++ dev->net->netdev_ops = &smsc75xx_netdev_ops; ++ dev->net->ethtool_ops = &smsc75xx_ethtool_ops; ++ dev->net->flags |= IFF_MULTICAST; ++ dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; ++ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; ++ return 0; ++} ++ ++static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ if (pdata) { ++ netif_dbg(dev, ifdown, dev->net, "free pdata\n"); ++ kfree(pdata); ++ pdata = NULL; ++ dev->data[0] = 0; ++ } ++} ++ ++static u16 smsc_crc(const u8 *buffer, size_t len) ++{ ++ return bitrev16(crc16(0xFFFF, buffer, len)); ++} ++ ++static int smsc75xx_write_wuff(struct usbnet *dev, int filter, u32 wuf_cfg, ++ u32 wuf_mask1) ++{ ++ int cfg_base = WUF_CFGX + filter * 4; ++ int mask_base = WUF_MASKX + filter * 16; ++ int ret; ++ ++ ret = smsc75xx_write_reg(dev, cfg_base, wuf_cfg); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUF_CFGX\n"); ++ return ret; ++ } ++ ++ ret = smsc75xx_write_reg(dev, mask_base, wuf_mask1); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUF_MASKX\n"); ++ return ret; ++ } ++ ++ ret = smsc75xx_write_reg(dev, mask_base + 4, 0); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUF_MASKX\n"); ++ return ret; ++ } ++ ++ ret = smsc75xx_write_reg(dev, mask_base + 8, 0); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUF_MASKX\n"); ++ return ret; ++ } ++ ++ ret = smsc75xx_write_reg(dev, mask_base + 12, 0); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUF_MASKX\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int smsc75xx_enter_suspend0(struct usbnet *dev) ++{ ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ u32 val; ++ int ret; ++ ++ ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PMT_CTL\n"); ++ return ret; ++ } ++ ++ val &= (~(PMT_CTL_SUS_MODE | PMT_CTL_PHY_RST)); ++ val |= PMT_CTL_SUS_MODE_0 | PMT_CTL_WOL_EN | PMT_CTL_WUPS; ++ ++ ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing PMT_CTL\n"); ++ return ret; ++ } ++ ++ pdata->suspend_flags |= SUSPEND_SUSPEND0; ++ ++ return 0; ++} ++ ++static int smsc75xx_enter_suspend1(struct usbnet *dev) ++{ ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ u32 val; ++ int ret; ++ ++ ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PMT_CTL\n"); ++ return ret; ++ } ++ ++ val &= ~(PMT_CTL_SUS_MODE | PMT_CTL_WUPS | PMT_CTL_PHY_RST); ++ val |= PMT_CTL_SUS_MODE_1; ++ ++ ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing PMT_CTL\n"); ++ return ret; ++ } ++ ++ /* clear wol status, enable energy detection */ ++ val &= ~PMT_CTL_WUPS; ++ val |= (PMT_CTL_WUPS_ED | PMT_CTL_ED_EN); ++ ++ ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing PMT_CTL\n"); ++ return ret; ++ } ++ ++ pdata->suspend_flags |= SUSPEND_SUSPEND1; ++ ++ return 0; ++} ++ ++static int smsc75xx_enter_suspend2(struct usbnet *dev) ++{ ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ u32 val; ++ int ret; ++ ++ ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PMT_CTL\n"); ++ return ret; ++ } ++ ++ val &= ~(PMT_CTL_SUS_MODE | PMT_CTL_WUPS | PMT_CTL_PHY_RST); ++ val |= PMT_CTL_SUS_MODE_2; ++ ++ ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing PMT_CTL\n"); ++ return ret; ++ } ++ ++ pdata->suspend_flags |= SUSPEND_SUSPEND2; ++ ++ return 0; ++} ++ ++static int smsc75xx_enter_suspend3(struct usbnet *dev) ++{ ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ u32 val; ++ int ret; ++ ++ ret = smsc75xx_read_reg_nopm(dev, FCT_RX_CTL, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading FCT_RX_CTL\n"); ++ return ret; ++ } ++ ++ if (val & FCT_RX_CTL_RXUSED) { ++ netdev_dbg(dev->net, "rx fifo not empty in autosuspend\n"); ++ return -EBUSY; ++ } ++ ++ ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PMT_CTL\n"); ++ return ret; ++ } ++ ++ val &= ~(PMT_CTL_SUS_MODE | PMT_CTL_WUPS | PMT_CTL_PHY_RST); ++ val |= PMT_CTL_SUS_MODE_3 | PMT_CTL_RES_CLR_WKP_EN; ++ ++ ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing PMT_CTL\n"); ++ return ret; ++ } ++ ++ /* clear wol status */ ++ val &= ~PMT_CTL_WUPS; ++ val |= PMT_CTL_WUPS_WOL; ++ ++ ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing PMT_CTL\n"); ++ return ret; ++ } ++ ++ pdata->suspend_flags |= SUSPEND_SUSPEND3; ++ ++ return 0; ++} ++ ++static int smsc75xx_enable_phy_wakeup_interrupts(struct usbnet *dev, u16 mask) ++{ ++ struct mii_if_info *mii = &dev->mii; ++ int ret; ++ ++ netdev_dbg(dev->net, "enabling PHY wakeup interrupts\n"); ++ ++ /* read to clear */ ++ ret = smsc75xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_INT_SRC); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PHY_INT_SRC\n"); ++ return ret; ++ } ++ ++ /* enable interrupt source */ ++ ret = smsc75xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_INT_MASK); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PHY_INT_MASK\n"); ++ return ret; ++ } ++ ++ ret |= mask; ++ ++ smsc75xx_mdio_write_nopm(dev->net, mii->phy_id, PHY_INT_MASK, ret); ++ ++ return 0; ++} ++ ++static int smsc75xx_link_ok_nopm(struct usbnet *dev) ++{ ++ struct mii_if_info *mii = &dev->mii; ++ int ret; ++ ++ /* first, a dummy read, needed to latch some MII phys */ ++ ret = smsc75xx_mdio_read_nopm(dev->net, mii->phy_id, MII_BMSR); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading MII_BMSR\n"); ++ return ret; ++ } ++ ++ ret = smsc75xx_mdio_read_nopm(dev->net, mii->phy_id, MII_BMSR); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading MII_BMSR\n"); ++ return ret; ++ } ++ ++ return !!(ret & BMSR_LSTATUS); ++} ++ ++static int smsc75xx_autosuspend(struct usbnet *dev, u32 link_up) ++{ ++ int ret; ++ ++ if (!netif_running(dev->net)) { ++ /* interface is ifconfig down so fully power down hw */ ++ netdev_dbg(dev->net, "autosuspend entering SUSPEND2\n"); ++ return smsc75xx_enter_suspend2(dev); ++ } ++ ++ if (!link_up) { ++ /* link is down so enter EDPD mode */ ++ netdev_dbg(dev->net, "autosuspend entering SUSPEND1\n"); ++ ++ /* enable PHY wakeup events for if cable is attached */ ++ ret = smsc75xx_enable_phy_wakeup_interrupts(dev, ++ PHY_INT_MASK_ANEG_COMP); ++ if (ret < 0) { ++ netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); ++ return ret; ++ } ++ ++ netdev_info(dev->net, "entering SUSPEND1 mode\n"); ++ return smsc75xx_enter_suspend1(dev); ++ } ++ ++ /* enable PHY wakeup events so we remote wakeup if cable is pulled */ ++ ret = smsc75xx_enable_phy_wakeup_interrupts(dev, ++ PHY_INT_MASK_LINK_DOWN); ++ if (ret < 0) { ++ netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); ++ return ret; ++ } ++ ++ netdev_dbg(dev->net, "autosuspend entering SUSPEND3\n"); ++ return smsc75xx_enter_suspend3(dev); ++} ++ ++static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ u32 val, link_up; ++ int ret; ++ ++ ret = usbnet_suspend(intf, message); ++ if (ret < 0) { ++ netdev_warn(dev->net, "usbnet_suspend error\n"); ++ return ret; ++ } ++ ++ if (pdata->suspend_flags) { ++ netdev_warn(dev->net, "error during last resume\n"); ++ pdata->suspend_flags = 0; ++ } ++ ++ /* determine if link is up using only _nopm functions */ ++ link_up = smsc75xx_link_ok_nopm(dev); ++ ++ if (message.event == PM_EVENT_AUTO_SUSPEND) { ++ ret = smsc75xx_autosuspend(dev, link_up); ++ goto done; ++ } ++ ++ /* if we get this far we're not autosuspending */ ++ /* if no wol options set, or if link is down and we're not waking on ++ * PHY activity, enter lowest power SUSPEND2 mode ++ */ ++ if (!(pdata->wolopts & SUPPORTED_WAKE) || ++ !(link_up || (pdata->wolopts & WAKE_PHY))) { ++ netdev_info(dev->net, "entering SUSPEND2 mode\n"); ++ ++ /* disable energy detect (link up) & wake up events */ ++ ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading WUCSR\n"); ++ goto done; ++ } ++ ++ val &= ~(WUCSR_MPEN | WUCSR_WUEN); ++ ++ ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUCSR\n"); ++ goto done; ++ } ++ ++ ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PMT_CTL\n"); ++ goto done; ++ } ++ ++ val &= ~(PMT_CTL_ED_EN | PMT_CTL_WOL_EN); ++ ++ ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing PMT_CTL\n"); ++ goto done; ++ } ++ ++ ret = smsc75xx_enter_suspend2(dev); ++ goto done; ++ } ++ ++ if (pdata->wolopts & WAKE_PHY) { ++ ret = smsc75xx_enable_phy_wakeup_interrupts(dev, ++ (PHY_INT_MASK_ANEG_COMP | PHY_INT_MASK_LINK_DOWN)); ++ if (ret < 0) { ++ netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); ++ goto done; ++ } ++ ++ /* if link is down then configure EDPD and enter SUSPEND1, ++ * otherwise enter SUSPEND0 below ++ */ ++ if (!link_up) { ++ struct mii_if_info *mii = &dev->mii; ++ netdev_info(dev->net, "entering SUSPEND1 mode\n"); ++ ++ /* enable energy detect power-down mode */ ++ ret = smsc75xx_mdio_read_nopm(dev->net, mii->phy_id, ++ PHY_MODE_CTRL_STS); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PHY_MODE_CTRL_STS\n"); ++ goto done; ++ } ++ ++ ret |= MODE_CTRL_STS_EDPWRDOWN; ++ ++ smsc75xx_mdio_write_nopm(dev->net, mii->phy_id, ++ PHY_MODE_CTRL_STS, ret); ++ ++ /* enter SUSPEND1 mode */ ++ ret = smsc75xx_enter_suspend1(dev); ++ goto done; ++ } ++ } ++ ++ if (pdata->wolopts & (WAKE_MCAST | WAKE_ARP)) { ++ int i, filter = 0; ++ ++ /* disable all filters */ ++ for (i = 0; i < WUF_NUM; i++) { ++ ret = smsc75xx_write_reg_nopm(dev, WUF_CFGX + i * 4, 0); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUF_CFGX\n"); ++ goto done; ++ } ++ } ++ ++ if (pdata->wolopts & WAKE_MCAST) { ++ const u8 mcast[] = {0x01, 0x00, 0x5E}; ++ netdev_info(dev->net, "enabling multicast detection\n"); ++ ++ val = WUF_CFGX_EN | WUF_CFGX_ATYPE_MULTICAST ++ | smsc_crc(mcast, 3); ++ ret = smsc75xx_write_wuff(dev, filter++, val, 0x0007); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing wakeup filter\n"); ++ goto done; ++ } ++ } ++ ++ if (pdata->wolopts & WAKE_ARP) { ++ const u8 arp[] = {0x08, 0x06}; ++ netdev_info(dev->net, "enabling ARP detection\n"); ++ ++ val = WUF_CFGX_EN | WUF_CFGX_ATYPE_ALL | (0x0C << 16) ++ | smsc_crc(arp, 2); ++ ret = smsc75xx_write_wuff(dev, filter++, val, 0x0003); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing wakeup filter\n"); ++ goto done; ++ } ++ } ++ ++ /* clear any pending pattern match packet status */ ++ ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading WUCSR\n"); ++ goto done; ++ } ++ ++ val |= WUCSR_WUFR; ++ ++ ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUCSR\n"); ++ goto done; ++ } ++ ++ netdev_info(dev->net, "enabling packet match detection\n"); ++ ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading WUCSR\n"); ++ goto done; ++ } ++ ++ val |= WUCSR_WUEN; ++ ++ ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUCSR\n"); ++ goto done; ++ } ++ } else { ++ netdev_info(dev->net, "disabling packet match detection\n"); ++ ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading WUCSR\n"); ++ goto done; ++ } ++ ++ val &= ~WUCSR_WUEN; ++ ++ ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUCSR\n"); ++ goto done; ++ } ++ } ++ ++ /* disable magic, bcast & unicast wakeup sources */ ++ ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading WUCSR\n"); ++ goto done; ++ } ++ ++ val &= ~(WUCSR_MPEN | WUCSR_BCST_EN | WUCSR_PFDA_EN); ++ ++ ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUCSR\n"); ++ goto done; ++ } ++ ++ if (pdata->wolopts & WAKE_PHY) { ++ netdev_info(dev->net, "enabling PHY wakeup\n"); ++ ++ ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PMT_CTL\n"); ++ goto done; ++ } ++ ++ /* clear wol status, enable energy detection */ ++ val &= ~PMT_CTL_WUPS; ++ val |= (PMT_CTL_WUPS_ED | PMT_CTL_ED_EN); ++ ++ ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing PMT_CTL\n"); ++ goto done; ++ } ++ } ++ ++ if (pdata->wolopts & WAKE_MAGIC) { ++ netdev_info(dev->net, "enabling magic packet wakeup\n"); ++ ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading WUCSR\n"); ++ goto done; ++ } ++ ++ /* clear any pending magic packet status */ ++ val |= WUCSR_MPR | WUCSR_MPEN; ++ ++ ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUCSR\n"); ++ goto done; ++ } ++ } ++ ++ if (pdata->wolopts & WAKE_BCAST) { ++ netdev_info(dev->net, "enabling broadcast detection\n"); ++ ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading WUCSR\n"); ++ goto done; ++ } ++ ++ val |= WUCSR_BCAST_FR | WUCSR_BCST_EN; ++ ++ ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUCSR\n"); ++ goto done; ++ } ++ } ++ ++ if (pdata->wolopts & WAKE_UCAST) { ++ netdev_info(dev->net, "enabling unicast detection\n"); ++ ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading WUCSR\n"); ++ goto done; ++ } ++ ++ val |= WUCSR_WUFR | WUCSR_PFDA_EN; ++ ++ ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUCSR\n"); ++ goto done; ++ } ++ } ++ ++ /* enable receiver to enable frame reception */ ++ ret = smsc75xx_read_reg_nopm(dev, MAC_RX, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read MAC_RX: %d\n", ret); ++ goto done; ++ } ++ ++ val |= MAC_RX_RXEN; ++ ++ ret = smsc75xx_write_reg_nopm(dev, MAC_RX, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to write MAC_RX: %d\n", ret); ++ goto done; ++ } ++ ++ /* some wol options are enabled, so enter SUSPEND0 */ ++ netdev_info(dev->net, "entering SUSPEND0 mode\n"); ++ ret = smsc75xx_enter_suspend0(dev); ++ ++done: ++ /* ++ * TODO: resume() might need to handle the suspend failure ++ * in system sleep ++ */ ++ if (ret && PMSG_IS_AUTO(message)) ++ usbnet_resume(intf); ++ return ret; ++} ++ ++static int smsc75xx_resume(struct usb_interface *intf) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); ++ u8 suspend_flags = pdata->suspend_flags; ++ int ret; ++ u32 val; ++ ++ netdev_dbg(dev->net, "resume suspend_flags=0x%02x\n", suspend_flags); ++ ++ /* do this first to ensure it's cleared even in error case */ ++ pdata->suspend_flags = 0; ++ ++ if (suspend_flags & SUSPEND_ALLMODES) { ++ /* Disable wakeup sources */ ++ ret = smsc75xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading WUCSR\n"); ++ return ret; ++ } ++ ++ val &= ~(WUCSR_WUEN | WUCSR_MPEN | WUCSR_PFDA_EN ++ | WUCSR_BCST_EN); ++ ++ ret = smsc75xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing WUCSR\n"); ++ return ret; ++ } ++ ++ /* clear wake-up status */ ++ ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PMT_CTL\n"); ++ return ret; ++ } ++ ++ val &= ~PMT_CTL_WOL_EN; ++ val |= PMT_CTL_WUPS; ++ ++ ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing PMT_CTL\n"); ++ return ret; ++ } ++ } ++ ++ if (suspend_flags & SUSPEND_SUSPEND2) { ++ netdev_info(dev->net, "resuming from SUSPEND2\n"); ++ ++ ret = smsc75xx_read_reg_nopm(dev, PMT_CTL, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading PMT_CTL\n"); ++ return ret; ++ } ++ ++ val |= PMT_CTL_PHY_PWRUP; ++ ++ ret = smsc75xx_write_reg_nopm(dev, PMT_CTL, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing PMT_CTL\n"); ++ return ret; ++ } ++ } ++ ++ ret = smsc75xx_wait_ready(dev, 1); ++ if (ret < 0) { ++ netdev_warn(dev->net, "device not ready in smsc75xx_resume\n"); ++ return ret; ++ } ++ ++ return usbnet_resume(intf); ++} ++ ++static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb, ++ u32 rx_cmd_a, u32 rx_cmd_b) ++{ ++ if (!(dev->net->features & NETIF_F_RXCSUM) || ++ unlikely(rx_cmd_a & RX_CMD_A_LCSM)) { ++ skb->ip_summed = CHECKSUM_NONE; ++ } else { ++ skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT)); ++ skb->ip_summed = CHECKSUM_COMPLETE; ++ } ++} ++ ++static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ ++ while (skb->len > 0) { ++ u32 rx_cmd_a, rx_cmd_b, align_count, size; ++ struct sk_buff *ax_skb; ++ unsigned char *packet; ++ ++ memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a)); ++ le32_to_cpus(&rx_cmd_a); ++ skb_pull(skb, 4); ++ ++ memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b)); ++ le32_to_cpus(&rx_cmd_b); ++ skb_pull(skb, 4 + RXW_PADDING); ++ ++ packet = skb->data; ++ ++ /* get the packet length */ ++ size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING; ++ align_count = (4 - ((size + RXW_PADDING) % 4)) % 4; ++ ++ if (unlikely(rx_cmd_a & RX_CMD_A_RED)) { ++ netif_dbg(dev, rx_err, dev->net, ++ "Error rx_cmd_a=0x%08x\n", rx_cmd_a); ++ dev->net->stats.rx_errors++; ++ dev->net->stats.rx_dropped++; ++ ++ if (rx_cmd_a & RX_CMD_A_FCS) ++ dev->net->stats.rx_crc_errors++; ++ else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT)) ++ dev->net->stats.rx_frame_errors++; ++ } else { ++ /* MAX_SINGLE_PACKET_SIZE + 4(CRC) + 2(COE) + 4(Vlan) */ ++ if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12))) { ++ netif_dbg(dev, rx_err, dev->net, ++ "size err rx_cmd_a=0x%08x\n", ++ rx_cmd_a); ++ return 0; ++ } ++ ++ /* last frame in this batch */ ++ if (skb->len == size) { ++ smsc75xx_rx_csum_offload(dev, skb, rx_cmd_a, ++ rx_cmd_b); ++ ++ skb_trim(skb, skb->len - 4); /* remove fcs */ ++ skb->truesize = size + sizeof(struct sk_buff); ++ ++ return 1; ++ } ++ ++ ax_skb = skb_clone(skb, GFP_ATOMIC); ++ if (unlikely(!ax_skb)) { ++ netdev_warn(dev->net, "Error allocating skb\n"); ++ return 0; ++ } ++ ++ ax_skb->len = size; ++ ax_skb->data = packet; ++ skb_set_tail_pointer(ax_skb, size); ++ ++ smsc75xx_rx_csum_offload(dev, ax_skb, rx_cmd_a, ++ rx_cmd_b); ++ ++ skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ ++ ax_skb->truesize = size + sizeof(struct sk_buff); ++ ++ usbnet_skb_return(dev, ax_skb); ++ } ++ ++ skb_pull(skb, size); ++ ++ /* padding bytes before the next frame starts */ ++ if (skb->len) ++ skb_pull(skb, align_count); ++ } ++ ++ if (unlikely(skb->len < 0)) { ++ netdev_warn(dev->net, "invalid rx length<0 %d\n", skb->len); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev, ++ struct sk_buff *skb, gfp_t flags) ++{ ++ u32 tx_cmd_a, tx_cmd_b; ++ ++ if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) { ++ struct sk_buff *skb2 = ++ skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags); ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ if (!skb) ++ return NULL; ++ } ++ ++ tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS; ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) ++ tx_cmd_a |= TX_CMD_A_IPE | TX_CMD_A_TPE; ++ ++ if (skb_is_gso(skb)) { ++ u16 mss = max(skb_shinfo(skb)->gso_size, TX_MSS_MIN); ++ tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT) & TX_CMD_B_MSS; ++ ++ tx_cmd_a |= TX_CMD_A_LSO; ++ } else { ++ tx_cmd_b = 0; ++ } ++ ++ skb_push(skb, 4); ++ cpu_to_le32s(&tx_cmd_b); ++ memcpy(skb->data, &tx_cmd_b, 4); ++ ++ skb_push(skb, 4); ++ cpu_to_le32s(&tx_cmd_a); ++ memcpy(skb->data, &tx_cmd_a, 4); ++ ++ return skb; ++} ++ ++static int smsc75xx_manage_power(struct usbnet *dev, int on) ++{ ++ dev->intf->needs_remote_wakeup = on; ++ return 0; ++} ++ ++static const struct driver_info smsc75xx_info = { ++ .description = "smsc75xx USB 2.0 Gigabit Ethernet", ++ .bind = smsc75xx_bind, ++ .unbind = smsc75xx_unbind, ++ .link_reset = smsc75xx_link_reset, ++ .reset = smsc75xx_reset, ++ .rx_fixup = smsc75xx_rx_fixup, ++ .tx_fixup = smsc75xx_tx_fixup, ++ .status = smsc75xx_status, ++ .manage_power = smsc75xx_manage_power, ++ .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR, ++}; ++ ++static const struct usb_device_id products[] = { ++ { ++ /* SMSC7500 USB Gigabit Ethernet Device */ ++ USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7500), ++ .driver_info = (unsigned long) &smsc75xx_info, ++ }, ++ { ++ /* SMSC7500 USB Gigabit Ethernet Device */ ++ USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7505), ++ .driver_info = (unsigned long) &smsc75xx_info, ++ }, ++ { }, /* END */ ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver smsc75xx_driver = { ++ .name = SMSC_CHIPNAME, ++ .id_table = products, ++ .probe = usbnet_probe, ++ .suspend = smsc75xx_suspend, ++ .resume = smsc75xx_resume, ++ .reset_resume = smsc75xx_resume, ++ .disconnect = usbnet_disconnect, ++ .disable_hub_initiated_lpm = 1, ++ .supports_autosuspend = 1, ++}; ++ ++module_usb_driver(smsc75xx_driver); ++ ++MODULE_AUTHOR("Nancy Lin"); ++MODULE_AUTHOR("Steve Glendinning steve.glendinning@shawell.net"); ++MODULE_DESCRIPTION("SMSC75XX USB 2.0 Gigabit Ethernet Devices"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/smsc75xx.h backports-3.18.1-1/drivers/net/usb/smsc75xx.h +--- backports-3.18.1-1.org/drivers/net/usb/smsc75xx.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/smsc75xx.h 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,421 @@ ++ /*************************************************************************** ++ * ++ * Copyright (C) 2007-2010 SMSC ++ * ++ * 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 http://www.gnu.org/licenses/. ++ * ++ *****************************************************************************/ ++ ++#ifndef _SMSC75XX_H ++#define _SMSC75XX_H ++ ++/* Tx command words */ ++#define TX_CMD_A_LSO (0x08000000) ++#define TX_CMD_A_IPE (0x04000000) ++#define TX_CMD_A_TPE (0x02000000) ++#define TX_CMD_A_IVTG (0x01000000) ++#define TX_CMD_A_RVTG (0x00800000) ++#define TX_CMD_A_FCS (0x00400000) ++#define TX_CMD_A_LEN (0x000FFFFF) ++ ++#define TX_CMD_B_MSS (0x3FFF0000) ++#define TX_CMD_B_MSS_SHIFT (16) ++#define TX_MSS_MIN ((u16)8) ++#define TX_CMD_B_VTAG (0x0000FFFF) ++ ++/* Rx command words */ ++#define RX_CMD_A_ICE (0x80000000) ++#define RX_CMD_A_TCE (0x40000000) ++#define RX_CMD_A_IPV (0x20000000) ++#define RX_CMD_A_PID (0x18000000) ++#define RX_CMD_A_PID_NIP (0x00000000) ++#define RX_CMD_A_PID_TCP (0x08000000) ++#define RX_CMD_A_PID_UDP (0x10000000) ++#define RX_CMD_A_PID_PP (0x18000000) ++#define RX_CMD_A_PFF (0x04000000) ++#define RX_CMD_A_BAM (0x02000000) ++#define RX_CMD_A_MAM (0x01000000) ++#define RX_CMD_A_FVTG (0x00800000) ++#define RX_CMD_A_RED (0x00400000) ++#define RX_CMD_A_RWT (0x00200000) ++#define RX_CMD_A_RUNT (0x00100000) ++#define RX_CMD_A_LONG (0x00080000) ++#define RX_CMD_A_RXE (0x00040000) ++#define RX_CMD_A_DRB (0x00020000) ++#define RX_CMD_A_FCS (0x00010000) ++#define RX_CMD_A_UAM (0x00008000) ++#define RX_CMD_A_LCSM (0x00004000) ++#define RX_CMD_A_LEN (0x00003FFF) ++ ++#define RX_CMD_B_CSUM (0xFFFF0000) ++#define RX_CMD_B_CSUM_SHIFT (16) ++#define RX_CMD_B_VTAG (0x0000FFFF) ++ ++/* SCSRs */ ++#define ID_REV (0x0000) ++ ++#define FPGA_REV (0x0004) ++ ++#define BOND_CTL (0x0008) ++ ++#define INT_STS (0x000C) ++#define INT_STS_RDFO_INT (0x00400000) ++#define INT_STS_TXE_INT (0x00200000) ++#define INT_STS_MACRTO_INT (0x00100000) ++#define INT_STS_TX_DIS_INT (0x00080000) ++#define INT_STS_RX_DIS_INT (0x00040000) ++#define INT_STS_PHY_INT_ (0x00020000) ++#define INT_STS_MAC_ERR_INT (0x00008000) ++#define INT_STS_TDFU (0x00004000) ++#define INT_STS_TDFO (0x00002000) ++#define INT_STS_GPIOS (0x00000FFF) ++#define INT_STS_CLEAR_ALL (0xFFFFFFFF) ++ ++#define HW_CFG (0x0010) ++#define HW_CFG_SMDET_STS (0x00008000) ++#define HW_CFG_SMDET_EN (0x00004000) ++#define HW_CFG_EEM (0x00002000) ++#define HW_CFG_RST_PROTECT (0x00001000) ++#define HW_CFG_PORT_SWAP (0x00000800) ++#define HW_CFG_PHY_BOOST (0x00000600) ++#define HW_CFG_PHY_BOOST_NORMAL (0x00000000) ++#define HW_CFG_PHY_BOOST_4 (0x00002000) ++#define HW_CFG_PHY_BOOST_8 (0x00004000) ++#define HW_CFG_PHY_BOOST_12 (0x00006000) ++#define HW_CFG_LEDB (0x00000100) ++#define HW_CFG_BIR (0x00000080) ++#define HW_CFG_SBP (0x00000040) ++#define HW_CFG_IME (0x00000020) ++#define HW_CFG_MEF (0x00000010) ++#define HW_CFG_ETC (0x00000008) ++#define HW_CFG_BCE (0x00000004) ++#define HW_CFG_LRST (0x00000002) ++#define HW_CFG_SRST (0x00000001) ++ ++#define PMT_CTL (0x0014) ++#define PMT_CTL_PHY_PWRUP (0x00000400) ++#define PMT_CTL_RES_CLR_WKP_EN (0x00000100) ++#define PMT_CTL_DEV_RDY (0x00000080) ++#define PMT_CTL_SUS_MODE (0x00000060) ++#define PMT_CTL_SUS_MODE_0 (0x00000000) ++#define PMT_CTL_SUS_MODE_1 (0x00000020) ++#define PMT_CTL_SUS_MODE_2 (0x00000040) ++#define PMT_CTL_SUS_MODE_3 (0x00000060) ++#define PMT_CTL_PHY_RST (0x00000010) ++#define PMT_CTL_WOL_EN (0x00000008) ++#define PMT_CTL_ED_EN (0x00000004) ++#define PMT_CTL_WUPS (0x00000003) ++#define PMT_CTL_WUPS_NO (0x00000000) ++#define PMT_CTL_WUPS_ED (0x00000001) ++#define PMT_CTL_WUPS_WOL (0x00000002) ++#define PMT_CTL_WUPS_MULTI (0x00000003) ++ ++#define LED_GPIO_CFG (0x0018) ++#define LED_GPIO_CFG_LED2_FUN_SEL (0x80000000) ++#define LED_GPIO_CFG_LED10_FUN_SEL (0x40000000) ++#define LED_GPIO_CFG_LEDGPIO_EN (0x0000F000) ++#define LED_GPIO_CFG_LEDGPIO_EN_0 (0x00001000) ++#define LED_GPIO_CFG_LEDGPIO_EN_1 (0x00002000) ++#define LED_GPIO_CFG_LEDGPIO_EN_2 (0x00004000) ++#define LED_GPIO_CFG_LEDGPIO_EN_3 (0x00008000) ++#define LED_GPIO_CFG_GPBUF (0x00000F00) ++#define LED_GPIO_CFG_GPBUF_0 (0x00000100) ++#define LED_GPIO_CFG_GPBUF_1 (0x00000200) ++#define LED_GPIO_CFG_GPBUF_2 (0x00000400) ++#define LED_GPIO_CFG_GPBUF_3 (0x00000800) ++#define LED_GPIO_CFG_GPDIR (0x000000F0) ++#define LED_GPIO_CFG_GPDIR_0 (0x00000010) ++#define LED_GPIO_CFG_GPDIR_1 (0x00000020) ++#define LED_GPIO_CFG_GPDIR_2 (0x00000040) ++#define LED_GPIO_CFG_GPDIR_3 (0x00000080) ++#define LED_GPIO_CFG_GPDATA (0x0000000F) ++#define LED_GPIO_CFG_GPDATA_0 (0x00000001) ++#define LED_GPIO_CFG_GPDATA_1 (0x00000002) ++#define LED_GPIO_CFG_GPDATA_2 (0x00000004) ++#define LED_GPIO_CFG_GPDATA_3 (0x00000008) ++ ++#define GPIO_CFG (0x001C) ++#define GPIO_CFG_SHIFT (24) ++#define GPIO_CFG_GPEN (0xFF000000) ++#define GPIO_CFG_GPBUF (0x00FF0000) ++#define GPIO_CFG_GPDIR (0x0000FF00) ++#define GPIO_CFG_GPDATA (0x000000FF) ++ ++#define GPIO_WAKE (0x0020) ++#define GPIO_WAKE_PHY_LINKUP_EN (0x80000000) ++#define GPIO_WAKE_POL (0x0FFF0000) ++#define GPIO_WAKE_POL_SHIFT (16) ++#define GPIO_WAKE_WK (0x00000FFF) ++ ++#define DP_SEL (0x0024) ++#define DP_SEL_DPRDY (0x80000000) ++#define DP_SEL_RSEL (0x0000000F) ++#define DP_SEL_URX (0x00000000) ++#define DP_SEL_VHF (0x00000001) ++#define DP_SEL_VHF_HASH_LEN (16) ++#define DP_SEL_VHF_VLAN_LEN (128) ++#define DP_SEL_LSO_HEAD (0x00000002) ++#define DP_SEL_FCT_RX (0x00000003) ++#define DP_SEL_FCT_TX (0x00000004) ++#define DP_SEL_DESCRIPTOR (0x00000005) ++#define DP_SEL_WOL (0x00000006) ++ ++#define DP_CMD (0x0028) ++#define DP_CMD_WRITE (0x01) ++#define DP_CMD_READ (0x00) ++ ++#define DP_ADDR (0x002C) ++ ++#define DP_DATA (0x0030) ++ ++#define BURST_CAP (0x0034) ++#define BURST_CAP_MASK (0x0000000F) ++ ++#define INT_EP_CTL (0x0038) ++#define INT_EP_CTL_INTEP_ON (0x80000000) ++#define INT_EP_CTL_RDFO_EN (0x00400000) ++#define INT_EP_CTL_TXE_EN (0x00200000) ++#define INT_EP_CTL_MACROTO_EN (0x00100000) ++#define INT_EP_CTL_TX_DIS_EN (0x00080000) ++#define INT_EP_CTL_RX_DIS_EN (0x00040000) ++#define INT_EP_CTL_PHY_EN_ (0x00020000) ++#define INT_EP_CTL_MAC_ERR_EN (0x00008000) ++#define INT_EP_CTL_TDFU_EN (0x00004000) ++#define INT_EP_CTL_TDFO_EN (0x00002000) ++#define INT_EP_CTL_RX_FIFO_EN (0x00001000) ++#define INT_EP_CTL_GPIOX_EN (0x00000FFF) ++ ++#define BULK_IN_DLY (0x003C) ++#define BULK_IN_DLY_MASK (0xFFFF) ++ ++#define E2P_CMD (0x0040) ++#define E2P_CMD_BUSY (0x80000000) ++#define E2P_CMD_MASK (0x70000000) ++#define E2P_CMD_READ (0x00000000) ++#define E2P_CMD_EWDS (0x10000000) ++#define E2P_CMD_EWEN (0x20000000) ++#define E2P_CMD_WRITE (0x30000000) ++#define E2P_CMD_WRAL (0x40000000) ++#define E2P_CMD_ERASE (0x50000000) ++#define E2P_CMD_ERAL (0x60000000) ++#define E2P_CMD_RELOAD (0x70000000) ++#define E2P_CMD_TIMEOUT (0x00000400) ++#define E2P_CMD_LOADED (0x00000200) ++#define E2P_CMD_ADDR (0x000001FF) ++ ++#define MAX_EEPROM_SIZE (512) ++ ++#define E2P_DATA (0x0044) ++#define E2P_DATA_MASK_ (0x000000FF) ++ ++#define RFE_CTL (0x0060) ++#define RFE_CTL_TCPUDP_CKM (0x00001000) ++#define RFE_CTL_IP_CKM (0x00000800) ++#define RFE_CTL_AB (0x00000400) ++#define RFE_CTL_AM (0x00000200) ++#define RFE_CTL_AU (0x00000100) ++#define RFE_CTL_VS (0x00000080) ++#define RFE_CTL_UF (0x00000040) ++#define RFE_CTL_VF (0x00000020) ++#define RFE_CTL_SPF (0x00000010) ++#define RFE_CTL_MHF (0x00000008) ++#define RFE_CTL_DHF (0x00000004) ++#define RFE_CTL_DPF (0x00000002) ++#define RFE_CTL_RST_RF (0x00000001) ++ ++#define VLAN_TYPE (0x0064) ++#define VLAN_TYPE_MASK (0x0000FFFF) ++ ++#define FCT_RX_CTL (0x0090) ++#define FCT_RX_CTL_EN (0x80000000) ++#define FCT_RX_CTL_RST (0x40000000) ++#define FCT_RX_CTL_SBF (0x02000000) ++#define FCT_RX_CTL_OVERFLOW (0x01000000) ++#define FCT_RX_CTL_FRM_DROP (0x00800000) ++#define FCT_RX_CTL_RX_NOT_EMPTY (0x00400000) ++#define FCT_RX_CTL_RX_EMPTY (0x00200000) ++#define FCT_RX_CTL_RX_DISABLED (0x00100000) ++#define FCT_RX_CTL_RXUSED (0x0000FFFF) ++ ++#define FCT_TX_CTL (0x0094) ++#define FCT_TX_CTL_EN (0x80000000) ++#define FCT_TX_CTL_RST (0x40000000) ++#define FCT_TX_CTL_TX_NOT_EMPTY (0x00400000) ++#define FCT_TX_CTL_TX_EMPTY (0x00200000) ++#define FCT_TX_CTL_TX_DISABLED (0x00100000) ++#define FCT_TX_CTL_TXUSED (0x0000FFFF) ++ ++#define FCT_RX_FIFO_END (0x0098) ++#define FCT_RX_FIFO_END_MASK (0x0000007F) ++ ++#define FCT_TX_FIFO_END (0x009C) ++#define FCT_TX_FIFO_END_MASK (0x0000003F) ++ ++#define FCT_FLOW (0x00A0) ++#define FCT_FLOW_THRESHOLD_OFF (0x00007F00) ++#define FCT_FLOW_THRESHOLD_OFF_SHIFT (8) ++#define FCT_FLOW_THRESHOLD_ON (0x0000007F) ++ ++/* MAC CSRs */ ++#define MAC_CR (0x100) ++#define MAC_CR_ADP (0x00002000) ++#define MAC_CR_ADD (0x00001000) ++#define MAC_CR_ASD (0x00000800) ++#define MAC_CR_INT_LOOP (0x00000400) ++#define MAC_CR_BOLMT (0x000000C0) ++#define MAC_CR_FDPX (0x00000008) ++#define MAC_CR_CFG (0x00000006) ++#define MAC_CR_CFG_10 (0x00000000) ++#define MAC_CR_CFG_100 (0x00000002) ++#define MAC_CR_CFG_1000 (0x00000004) ++#define MAC_CR_RST (0x00000001) ++ ++#define MAC_RX (0x104) ++#define MAC_RX_MAX_SIZE (0x3FFF0000) ++#define MAC_RX_MAX_SIZE_SHIFT (16) ++#define MAC_RX_FCS_STRIP (0x00000010) ++#define MAC_RX_FSE (0x00000004) ++#define MAC_RX_RXD (0x00000002) ++#define MAC_RX_RXEN (0x00000001) ++ ++#define MAC_TX (0x108) ++#define MAC_TX_BFCS (0x00000004) ++#define MAC_TX_TXD (0x00000002) ++#define MAC_TX_TXEN (0x00000001) ++ ++#define FLOW (0x10C) ++#define FLOW_FORCE_FC (0x80000000) ++#define FLOW_TX_FCEN (0x40000000) ++#define FLOW_RX_FCEN (0x20000000) ++#define FLOW_FPF (0x10000000) ++#define FLOW_PAUSE_TIME (0x0000FFFF) ++ ++#define RAND_SEED (0x110) ++#define RAND_SEED_MASK (0x0000FFFF) ++ ++#define ERR_STS (0x114) ++#define ERR_STS_FCS_ERR (0x00000100) ++#define ERR_STS_LFRM_ERR (0x00000080) ++#define ERR_STS_RUNT_ERR (0x00000040) ++#define ERR_STS_COLLISION_ERR (0x00000010) ++#define ERR_STS_ALIGN_ERR (0x00000008) ++#define ERR_STS_URUN_ERR (0x00000004) ++ ++#define RX_ADDRH (0x118) ++#define RX_ADDRH_MASK (0x0000FFFF) ++ ++#define RX_ADDRL (0x11C) ++ ++#define MII_ACCESS (0x120) ++#define MII_ACCESS_PHY_ADDR (0x0000F800) ++#define MII_ACCESS_PHY_ADDR_SHIFT (11) ++#define MII_ACCESS_REG_ADDR (0x000007C0) ++#define MII_ACCESS_REG_ADDR_SHIFT (6) ++#define MII_ACCESS_READ (0x00000000) ++#define MII_ACCESS_WRITE (0x00000002) ++#define MII_ACCESS_BUSY (0x00000001) ++ ++#define MII_DATA (0x124) ++#define MII_DATA_MASK (0x0000FFFF) ++ ++#define WUCSR (0x140) ++#define WUCSR_PFDA_FR (0x00000080) ++#define WUCSR_WUFR (0x00000040) ++#define WUCSR_MPR (0x00000020) ++#define WUCSR_BCAST_FR (0x00000010) ++#define WUCSR_PFDA_EN (0x00000008) ++#define WUCSR_WUEN (0x00000004) ++#define WUCSR_MPEN (0x00000002) ++#define WUCSR_BCST_EN (0x00000001) ++ ++#define WUF_CFGX (0x144) ++#define WUF_CFGX_EN (0x80000000) ++#define WUF_CFGX_ATYPE (0x03000000) ++#define WUF_CFGX_ATYPE_UNICAST (0x00000000) ++#define WUF_CFGX_ATYPE_MULTICAST (0x02000000) ++#define WUF_CFGX_ATYPE_ALL (0x03000000) ++#define WUF_CFGX_PATTERN_OFFSET (0x007F0000) ++#define WUF_CFGX_PATTERN_OFFSET_SHIFT (16) ++#define WUF_CFGX_CRC16 (0x0000FFFF) ++#define WUF_NUM (8) ++ ++#define WUF_MASKX (0x170) ++#define WUF_MASKX_AVALID (0x80000000) ++#define WUF_MASKX_ATYPE (0x40000000) ++ ++#define ADDR_FILTX (0x300) ++#define ADDR_FILTX_FB_VALID (0x80000000) ++#define ADDR_FILTX_FB_TYPE (0x40000000) ++#define ADDR_FILTX_FB_ADDRHI (0x0000FFFF) ++#define ADDR_FILTX_SB_ADDRLO (0xFFFFFFFF) ++ ++#define WUCSR2 (0x500) ++#define WUCSR2_NS_RCD (0x00000040) ++#define WUCSR2_ARP_RCD (0x00000020) ++#define WUCSR2_TCPSYN_RCD (0x00000010) ++#define WUCSR2_NS_OFFLOAD (0x00000004) ++#define WUCSR2_ARP_OFFLOAD (0x00000002) ++#define WUCSR2_TCPSYN_OFFLOAD (0x00000001) ++ ++#define WOL_FIFO_STS (0x504) ++ ++#define IPV6_ADDRX (0x510) ++ ++#define IPV4_ADDRX (0x590) ++ ++ ++/* Vendor-specific PHY Definitions */ ++ ++/* Mode Control/Status Register */ ++#define PHY_MODE_CTRL_STS (17) ++#define MODE_CTRL_STS_EDPWRDOWN ((u16)0x2000) ++#define MODE_CTRL_STS_ENERGYON ((u16)0x0002) ++ ++#define PHY_INT_SRC (29) ++#define PHY_INT_SRC_ENERGY_ON ((u16)0x0080) ++#define PHY_INT_SRC_ANEG_COMP ((u16)0x0040) ++#define PHY_INT_SRC_REMOTE_FAULT ((u16)0x0020) ++#define PHY_INT_SRC_LINK_DOWN ((u16)0x0010) ++#define PHY_INT_SRC_CLEAR_ALL ((u16)0xffff) ++ ++#define PHY_INT_MASK (30) ++#define PHY_INT_MASK_ENERGY_ON ((u16)0x0080) ++#define PHY_INT_MASK_ANEG_COMP ((u16)0x0040) ++#define PHY_INT_MASK_REMOTE_FAULT ((u16)0x0020) ++#define PHY_INT_MASK_LINK_DOWN ((u16)0x0010) ++#define PHY_INT_MASK_DEFAULT (PHY_INT_MASK_ANEG_COMP | \ ++ PHY_INT_MASK_LINK_DOWN) ++ ++#define PHY_SPECIAL (31) ++#define PHY_SPECIAL_SPD ((u16)0x001C) ++#define PHY_SPECIAL_SPD_10HALF ((u16)0x0004) ++#define PHY_SPECIAL_SPD_10FULL ((u16)0x0014) ++#define PHY_SPECIAL_SPD_100HALF ((u16)0x0008) ++#define PHY_SPECIAL_SPD_100FULL ((u16)0x0018) ++ ++/* USB Vendor Requests */ ++#define USB_VENDOR_REQUEST_WRITE_REGISTER 0xA0 ++#define USB_VENDOR_REQUEST_READ_REGISTER 0xA1 ++#define USB_VENDOR_REQUEST_GET_STATS 0xA2 ++ ++/* Interrupt Endpoint status word bitfields */ ++#define INT_ENP_RDFO_INT ((u32)BIT(22)) ++#define INT_ENP_TXE_INT ((u32)BIT(21)) ++#define INT_ENP_TX_DIS_INT ((u32)BIT(19)) ++#define INT_ENP_RX_DIS_INT ((u32)BIT(18)) ++#define INT_ENP_PHY_INT ((u32)BIT(17)) ++#define INT_ENP_MAC_ERR_INT ((u32)BIT(15)) ++#define INT_ENP_RX_FIFO_DATA_INT ((u32)BIT(12)) ++ ++#endif /* _SMSC75XX_H */ +diff -Naur backports-3.18.1-1.org/drivers/net/usb/smsc95xx.c backports-3.18.1-1/drivers/net/usb/smsc95xx.c +--- backports-3.18.1-1.org/drivers/net/usb/smsc95xx.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/smsc95xx.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,2030 @@ ++ /*************************************************************************** ++ * ++ * Copyright (C) 2007-2008 SMSC ++ * ++ * 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 http://www.gnu.org/licenses/. ++ * ++ *****************************************************************************/ ++ ++#include <linux/module.h> ++#include <linux/kmod.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/bitrev.h> ++#include <linux/crc16.h> ++#include <linux/crc32.h> ++#include <linux/usb/usbnet.h> ++#include <linux/slab.h> ++#include "smsc95xx.h" ++ ++#define SMSC_CHIPNAME "smsc95xx" ++#define SMSC_DRIVER_VERSION "1.0.4" ++#define HS_USB_PKT_SIZE (512) ++#define FS_USB_PKT_SIZE (64) ++#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE) ++#define DEFAULT_FS_BURST_CAP_SIZE (6 * 1024 + 33 * FS_USB_PKT_SIZE) ++#define DEFAULT_BULK_IN_DELAY (0x00002000) ++#define MAX_SINGLE_PACKET_SIZE (2048) ++#define LAN95XX_EEPROM_MAGIC (0x9500) ++#define EEPROM_MAC_OFFSET (0x01) ++#define DEFAULT_TX_CSUM_ENABLE (true) ++#define DEFAULT_RX_CSUM_ENABLE (true) ++#define SMSC95XX_INTERNAL_PHY_ID (1) ++#define SMSC95XX_TX_OVERHEAD (8) ++#define SMSC95XX_TX_OVERHEAD_CSUM (12) ++#define SUPPORTED_WAKE (WAKE_PHY | WAKE_UCAST | WAKE_BCAST | \ ++ WAKE_MCAST | WAKE_ARP | WAKE_MAGIC) ++ ++#define FEATURE_8_WAKEUP_FILTERS (0x01) ++#define FEATURE_PHY_NLP_CROSSOVER (0x02) ++#define FEATURE_REMOTE_WAKEUP (0x04) ++ ++#define SUSPEND_SUSPEND0 (0x01) ++#define SUSPEND_SUSPEND1 (0x02) ++#define SUSPEND_SUSPEND2 (0x04) ++#define SUSPEND_SUSPEND3 (0x08) ++#define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \ ++ SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) ++ ++struct smsc95xx_priv { ++ u32 mac_cr; ++ u32 hash_hi; ++ u32 hash_lo; ++ u32 wolopts; ++ spinlock_t mac_cr_lock; ++ u8 features; ++ u8 suspend_flags; ++}; ++ ++static bool turbo_mode = true; ++module_param(turbo_mode, bool, 0644); ++MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); ++ ++static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, ++ u32 *data, int in_pm) ++{ ++ u32 buf; ++ int ret; ++ int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16); ++ ++ BUG_ON(!dev); ++ ++ if (!in_pm) ++ fn = usbnet_read_cmd; ++ else ++ fn = usbnet_read_cmd_nopm; ++ ++ ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN ++ | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ 0, index, &buf, 4); ++ if (unlikely(ret < 0)) ++ netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n", ++ index, ret); ++ ++ le32_to_cpus(&buf); ++ *data = buf; ++ ++ return ret; ++} ++ ++static int __must_check __smsc95xx_write_reg(struct usbnet *dev, u32 index, ++ u32 data, int in_pm) ++{ ++ u32 buf; ++ int ret; ++ int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16); ++ ++ BUG_ON(!dev); ++ ++ if (!in_pm) ++ fn = usbnet_write_cmd; ++ else ++ fn = usbnet_write_cmd_nopm; ++ ++ buf = data; ++ cpu_to_le32s(&buf); ++ ++ ret = fn(dev, USB_VENDOR_REQUEST_WRITE_REGISTER, USB_DIR_OUT ++ | USB_TYPE_VENDOR | USB_RECIP_DEVICE, ++ 0, index, &buf, 4); ++ if (unlikely(ret < 0)) ++ netdev_warn(dev->net, "Failed to write reg index 0x%08x: %d\n", ++ index, ret); ++ ++ return ret; ++} ++ ++static int __must_check smsc95xx_read_reg_nopm(struct usbnet *dev, u32 index, ++ u32 *data) ++{ ++ return __smsc95xx_read_reg(dev, index, data, 1); ++} ++ ++static int __must_check smsc95xx_write_reg_nopm(struct usbnet *dev, u32 index, ++ u32 data) ++{ ++ return __smsc95xx_write_reg(dev, index, data, 1); ++} ++ ++static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index, ++ u32 *data) ++{ ++ return __smsc95xx_read_reg(dev, index, data, 0); ++} ++ ++static int __must_check smsc95xx_write_reg(struct usbnet *dev, u32 index, ++ u32 data) ++{ ++ return __smsc95xx_write_reg(dev, index, data, 0); ++} ++ ++/* Loop until the read is completed with timeout ++ * called with phy_mutex held */ ++static int __must_check __smsc95xx_phy_wait_not_busy(struct usbnet *dev, ++ int in_pm) ++{ ++ unsigned long start_time = jiffies; ++ u32 val; ++ int ret; ++ ++ do { ++ ret = __smsc95xx_read_reg(dev, MII_ADDR, &val, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading MII_ACCESS\n"); ++ return ret; ++ } ++ ++ if (!(val & MII_BUSY_)) ++ return 0; ++ } while (!time_after(jiffies, start_time + HZ)); ++ ++ return -EIO; ++} ++ ++static int __smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx, ++ int in_pm) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ u32 val, addr; ++ int ret; ++ ++ mutex_lock(&dev->phy_mutex); ++ ++ /* confirm MII not busy */ ++ ret = __smsc95xx_phy_wait_not_busy(dev, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "MII is busy in smsc95xx_mdio_read\n"); ++ goto done; ++ } ++ ++ /* set the address, index & direction (read from PHY) */ ++ phy_id &= dev->mii.phy_id_mask; ++ idx &= dev->mii.reg_num_mask; ++ addr = (phy_id << 11) | (idx << 6) | MII_READ_ | MII_BUSY_; ++ ret = __smsc95xx_write_reg(dev, MII_ADDR, addr, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing MII_ADDR\n"); ++ goto done; ++ } ++ ++ ret = __smsc95xx_phy_wait_not_busy(dev, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Timed out reading MII reg %02X\n", idx); ++ goto done; ++ } ++ ++ ret = __smsc95xx_read_reg(dev, MII_DATA, &val, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading MII_DATA\n"); ++ goto done; ++ } ++ ++ ret = (u16)(val & 0xFFFF); ++ ++done: ++ mutex_unlock(&dev->phy_mutex); ++ return ret; ++} ++ ++static void __smsc95xx_mdio_write(struct net_device *netdev, int phy_id, ++ int idx, int regval, int in_pm) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ u32 val, addr; ++ int ret; ++ ++ mutex_lock(&dev->phy_mutex); ++ ++ /* confirm MII not busy */ ++ ret = __smsc95xx_phy_wait_not_busy(dev, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "MII is busy in smsc95xx_mdio_write\n"); ++ goto done; ++ } ++ ++ val = regval; ++ ret = __smsc95xx_write_reg(dev, MII_DATA, val, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing MII_DATA\n"); ++ goto done; ++ } ++ ++ /* set the address, index & direction (write to PHY) */ ++ phy_id &= dev->mii.phy_id_mask; ++ idx &= dev->mii.reg_num_mask; ++ addr = (phy_id << 11) | (idx << 6) | MII_WRITE_ | MII_BUSY_; ++ ret = __smsc95xx_write_reg(dev, MII_ADDR, addr, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing MII_ADDR\n"); ++ goto done; ++ } ++ ++ ret = __smsc95xx_phy_wait_not_busy(dev, in_pm); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Timed out writing MII reg %02X\n", idx); ++ goto done; ++ } ++ ++done: ++ mutex_unlock(&dev->phy_mutex); ++} ++ ++static int smsc95xx_mdio_read_nopm(struct net_device *netdev, int phy_id, ++ int idx) ++{ ++ return __smsc95xx_mdio_read(netdev, phy_id, idx, 1); ++} ++ ++static void smsc95xx_mdio_write_nopm(struct net_device *netdev, int phy_id, ++ int idx, int regval) ++{ ++ __smsc95xx_mdio_write(netdev, phy_id, idx, regval, 1); ++} ++ ++static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx) ++{ ++ return __smsc95xx_mdio_read(netdev, phy_id, idx, 0); ++} ++ ++static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx, ++ int regval) ++{ ++ __smsc95xx_mdio_write(netdev, phy_id, idx, regval, 0); ++} ++ ++static int __must_check smsc95xx_wait_eeprom(struct usbnet *dev) ++{ ++ unsigned long start_time = jiffies; ++ u32 val; ++ int ret; ++ ++ do { ++ ret = smsc95xx_read_reg(dev, E2P_CMD, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading E2P_CMD\n"); ++ return ret; ++ } ++ ++ if (!(val & E2P_CMD_BUSY_) || (val & E2P_CMD_TIMEOUT_)) ++ break; ++ udelay(40); ++ } while (!time_after(jiffies, start_time + HZ)); ++ ++ if (val & (E2P_CMD_TIMEOUT_ | E2P_CMD_BUSY_)) { ++ netdev_warn(dev->net, "EEPROM read operation timeout\n"); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static int __must_check smsc95xx_eeprom_confirm_not_busy(struct usbnet *dev) ++{ ++ unsigned long start_time = jiffies; ++ u32 val; ++ int ret; ++ ++ do { ++ ret = smsc95xx_read_reg(dev, E2P_CMD, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading E2P_CMD\n"); ++ return ret; ++ } ++ ++ if (!(val & E2P_CMD_BUSY_)) ++ return 0; ++ ++ udelay(40); ++ } while (!time_after(jiffies, start_time + HZ)); ++ ++ netdev_warn(dev->net, "EEPROM is busy\n"); ++ return -EIO; ++} ++ ++static int smsc95xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length, ++ u8 *data) ++{ ++ u32 val; ++ int i, ret; ++ ++ BUG_ON(!dev); ++ BUG_ON(!data); ++ ++ ret = smsc95xx_eeprom_confirm_not_busy(dev); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < length; i++) { ++ val = E2P_CMD_BUSY_ | E2P_CMD_READ_ | (offset & E2P_CMD_ADDR_); ++ ret = smsc95xx_write_reg(dev, E2P_CMD, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing E2P_CMD\n"); ++ return ret; ++ } ++ ++ ret = smsc95xx_wait_eeprom(dev); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc95xx_read_reg(dev, E2P_DATA, &val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error reading E2P_DATA\n"); ++ return ret; ++ } ++ ++ data[i] = val & 0xFF; ++ offset++; ++ } ++ ++ return 0; ++} ++ ++static int smsc95xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length, ++ u8 *data) ++{ ++ u32 val; ++ int i, ret; ++ ++ BUG_ON(!dev); ++ BUG_ON(!data); ++ ++ ret = smsc95xx_eeprom_confirm_not_busy(dev); ++ if (ret) ++ return ret; ++ ++ /* Issue write/erase enable command */ ++ val = E2P_CMD_BUSY_ | E2P_CMD_EWEN_; ++ ret = smsc95xx_write_reg(dev, E2P_CMD, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing E2P_DATA\n"); ++ return ret; ++ } ++ ++ ret = smsc95xx_wait_eeprom(dev); ++ if (ret < 0) ++ return ret; ++ ++ for (i = 0; i < length; i++) { ++ ++ /* Fill data register */ ++ val = data[i]; ++ ret = smsc95xx_write_reg(dev, E2P_DATA, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing E2P_DATA\n"); ++ return ret; ++ } ++ ++ /* Send "write" command */ ++ val = E2P_CMD_BUSY_ | E2P_CMD_WRITE_ | (offset & E2P_CMD_ADDR_); ++ ret = smsc95xx_write_reg(dev, E2P_CMD, val); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Error writing E2P_CMD\n"); ++ return ret; ++ } ++ ++ ret = smsc95xx_wait_eeprom(dev); ++ if (ret < 0) ++ return ret; ++ ++ offset++; ++ } ++ ++ return 0; ++} ++ ++static int __must_check smsc95xx_write_reg_async(struct usbnet *dev, u16 index, ++ u32 data) ++{ ++ const u16 size = 4; ++ u32 buf; ++ int ret; ++ ++ buf = data; ++ cpu_to_le32s(&buf); ++ ++ ret = usbnet_write_cmd_async(dev, USB_VENDOR_REQUEST_WRITE_REGISTER, ++ USB_DIR_OUT | USB_TYPE_VENDOR | ++ USB_RECIP_DEVICE, ++ 0, index, &buf, size); ++ if (ret < 0) ++ netdev_warn(dev->net, "Error write async cmd, sts=%d\n", ++ ret); ++ return ret; ++} ++ ++/* returns hash bit number for given MAC address ++ * example: ++ * 01 00 5E 00 00 01 -> returns bit number 31 */ ++static unsigned int smsc95xx_hash(char addr[ETH_ALEN]) ++{ ++ return (ether_crc(ETH_ALEN, addr) >> 26) & 0x3f; ++} ++ ++static void smsc95xx_set_multicast(struct net_device *netdev) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ unsigned long flags; ++ int ret; ++ ++ pdata->hash_hi = 0; ++ pdata->hash_lo = 0; ++ ++ spin_lock_irqsave(&pdata->mac_cr_lock, flags); ++ ++ if (dev->net->flags & IFF_PROMISC) { ++ netif_dbg(dev, drv, dev->net, "promiscuous mode enabled\n"); ++ pdata->mac_cr |= MAC_CR_PRMS_; ++ pdata->mac_cr &= ~(MAC_CR_MCPAS_ | MAC_CR_HPFILT_); ++ } else if (dev->net->flags & IFF_ALLMULTI) { ++ netif_dbg(dev, drv, dev->net, "receive all multicast enabled\n"); ++ pdata->mac_cr |= MAC_CR_MCPAS_; ++ pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_HPFILT_); ++ } else if (!netdev_mc_empty(dev->net)) { ++ struct netdev_hw_addr *ha; ++ ++ pdata->mac_cr |= MAC_CR_HPFILT_; ++ pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_); ++ ++ netdev_for_each_mc_addr(ha, netdev) { ++ u32 bitnum = smsc95xx_hash(ha->addr); ++ u32 mask = 0x01 << (bitnum & 0x1F); ++ if (bitnum & 0x20) ++ pdata->hash_hi |= mask; ++ else ++ pdata->hash_lo |= mask; ++ } ++ ++ netif_dbg(dev, drv, dev->net, "HASHH=0x%08X, HASHL=0x%08X\n", ++ pdata->hash_hi, pdata->hash_lo); ++ } else { ++ netif_dbg(dev, drv, dev->net, "receive own packets only\n"); ++ pdata->mac_cr &= ++ ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_); ++ } ++ ++ spin_unlock_irqrestore(&pdata->mac_cr_lock, flags); ++ ++ /* Initiate async writes, as we can't wait for completion here */ ++ ret = smsc95xx_write_reg_async(dev, HASHH, pdata->hash_hi); ++ if (ret < 0) ++ netdev_warn(dev->net, "failed to initiate async write to HASHH\n"); ++ ++ ret = smsc95xx_write_reg_async(dev, HASHL, pdata->hash_lo); ++ if (ret < 0) ++ netdev_warn(dev->net, "failed to initiate async write to HASHL\n"); ++ ++ ret = smsc95xx_write_reg_async(dev, MAC_CR, pdata->mac_cr); ++ if (ret < 0) ++ netdev_warn(dev->net, "failed to initiate async write to MAC_CR\n"); ++} ++ ++static int smsc95xx_phy_update_flowcontrol(struct usbnet *dev, u8 duplex, ++ u16 lcladv, u16 rmtadv) ++{ ++ u32 flow, afc_cfg = 0; ++ ++ int ret = smsc95xx_read_reg(dev, AFC_CFG, &afc_cfg); ++ if (ret < 0) ++ return ret; ++ ++ if (duplex == DUPLEX_FULL) { ++ u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv); ++ ++ if (cap & FLOW_CTRL_RX) ++ flow = 0xFFFF0002; ++ else ++ flow = 0; ++ ++ if (cap & FLOW_CTRL_TX) ++ afc_cfg |= 0xF; ++ else ++ afc_cfg &= ~0xF; ++ ++ netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s\n", ++ cap & FLOW_CTRL_RX ? "enabled" : "disabled", ++ cap & FLOW_CTRL_TX ? "enabled" : "disabled"); ++ } else { ++ netif_dbg(dev, link, dev->net, "half duplex\n"); ++ flow = 0; ++ afc_cfg |= 0xF; ++ } ++ ++ ret = smsc95xx_write_reg(dev, FLOW, flow); ++ if (ret < 0) ++ return ret; ++ ++ return smsc95xx_write_reg(dev, AFC_CFG, afc_cfg); ++} ++ ++static int smsc95xx_link_reset(struct usbnet *dev) ++{ ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ struct mii_if_info *mii = &dev->mii; ++ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; ++ unsigned long flags; ++ u16 lcladv, rmtadv; ++ int ret; ++ ++ /* clear interrupt status */ ++ ret = smsc95xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc95xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_); ++ if (ret < 0) ++ return ret; ++ ++ mii_check_media(mii, 1, 1); ++ mii_ethtool_gset(&dev->mii, &ecmd); ++ lcladv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE); ++ rmtadv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_LPA); ++ ++ netif_dbg(dev, link, dev->net, ++ "speed: %u duplex: %d lcladv: %04x rmtadv: %04x\n", ++ ethtool_cmd_speed(&ecmd), ecmd.duplex, lcladv, rmtadv); ++ ++ spin_lock_irqsave(&pdata->mac_cr_lock, flags); ++ if (ecmd.duplex != DUPLEX_FULL) { ++ pdata->mac_cr &= ~MAC_CR_FDPX_; ++ pdata->mac_cr |= MAC_CR_RCVOWN_; ++ } else { ++ pdata->mac_cr &= ~MAC_CR_RCVOWN_; ++ pdata->mac_cr |= MAC_CR_FDPX_; ++ } ++ spin_unlock_irqrestore(&pdata->mac_cr_lock, flags); ++ ++ ret = smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc95xx_phy_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv); ++ if (ret < 0) ++ netdev_warn(dev->net, "Error updating PHY flow control\n"); ++ ++ return ret; ++} ++ ++static void smsc95xx_status(struct usbnet *dev, struct urb *urb) ++{ ++ u32 intdata; ++ ++ if (urb->actual_length != 4) { ++ netdev_warn(dev->net, "unexpected urb length %d\n", ++ urb->actual_length); ++ return; ++ } ++ ++ memcpy(&intdata, urb->transfer_buffer, 4); ++ le32_to_cpus(&intdata); ++ ++ netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata); ++ ++ if (intdata & INT_ENP_PHY_INT_) ++ usbnet_defer_kevent(dev, EVENT_LINK_RESET); ++ else ++ netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n", ++ intdata); ++} ++ ++/* Enable or disable Tx & Rx checksum offload engines */ ++static int smsc95xx_set_features(struct net_device *netdev, ++ netdev_features_t features) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ u32 read_buf; ++ int ret; ++ ++ ret = smsc95xx_read_reg(dev, COE_CR, &read_buf); ++ if (ret < 0) ++ return ret; ++ ++ if (features & NETIF_F_HW_CSUM) ++ read_buf |= Tx_COE_EN_; ++ else ++ read_buf &= ~Tx_COE_EN_; ++ ++ if (features & NETIF_F_RXCSUM) ++ read_buf |= Rx_COE_EN_; ++ else ++ read_buf &= ~Rx_COE_EN_; ++ ++ ret = smsc95xx_write_reg(dev, COE_CR, read_buf); ++ if (ret < 0) ++ return ret; ++ ++ netif_dbg(dev, hw, dev->net, "COE_CR = 0x%08x\n", read_buf); ++ return 0; ++} ++ ++static int smsc95xx_ethtool_get_eeprom_len(struct net_device *net) ++{ ++ return MAX_EEPROM_SIZE; ++} ++ ++static int smsc95xx_ethtool_get_eeprom(struct net_device *netdev, ++ struct ethtool_eeprom *ee, u8 *data) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ ++ ee->magic = LAN95XX_EEPROM_MAGIC; ++ ++ return smsc95xx_read_eeprom(dev, ee->offset, ee->len, data); ++} ++ ++static int smsc95xx_ethtool_set_eeprom(struct net_device *netdev, ++ struct ethtool_eeprom *ee, u8 *data) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ ++ if (ee->magic != LAN95XX_EEPROM_MAGIC) { ++ netdev_warn(dev->net, "EEPROM: magic value mismatch, magic = 0x%x\n", ++ ee->magic); ++ return -EINVAL; ++ } ++ ++ return smsc95xx_write_eeprom(dev, ee->offset, ee->len, data); ++} ++ ++static int smsc95xx_ethtool_getregslen(struct net_device *netdev) ++{ ++ /* all smsc95xx registers */ ++ return COE_CR - ID_REV + sizeof(u32); ++} ++ ++static void ++smsc95xx_ethtool_getregs(struct net_device *netdev, struct ethtool_regs *regs, ++ void *buf) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ unsigned int i, j; ++ int retval; ++ u32 *data = buf; ++ ++ retval = smsc95xx_read_reg(dev, ID_REV, ®s->version); ++ if (retval < 0) { ++ netdev_warn(netdev, "REGS: cannot read ID_REV\n"); ++ return; ++ } ++ ++ for (i = ID_REV, j = 0; i <= COE_CR; i += (sizeof(u32)), j++) { ++ retval = smsc95xx_read_reg(dev, i, &data[j]); ++ if (retval < 0) { ++ netdev_warn(netdev, "REGS: cannot read reg[%x]\n", i); ++ return; ++ } ++ } ++} ++ ++static void smsc95xx_ethtool_get_wol(struct net_device *net, ++ struct ethtool_wolinfo *wolinfo) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ ++ wolinfo->supported = SUPPORTED_WAKE; ++ wolinfo->wolopts = pdata->wolopts; ++} ++ ++static int smsc95xx_ethtool_set_wol(struct net_device *net, ++ struct ethtool_wolinfo *wolinfo) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ int ret; ++ ++ pdata->wolopts = wolinfo->wolopts & SUPPORTED_WAKE; ++ ++ ret = device_set_wakeup_enable(&dev->udev->dev, pdata->wolopts); ++ if (ret < 0) ++ netdev_warn(dev->net, "device_set_wakeup_enable error %d\n", ret); ++ ++ return ret; ++} ++ ++static const struct ethtool_ops smsc95xx_ethtool_ops = { ++ .get_link = usbnet_get_link, ++ .nway_reset = usbnet_nway_reset, ++ .get_drvinfo = usbnet_get_drvinfo, ++ .get_msglevel = usbnet_get_msglevel, ++ .set_msglevel = usbnet_set_msglevel, ++ .get_settings = usbnet_get_settings, ++ .set_settings = usbnet_set_settings, ++ .get_eeprom_len = smsc95xx_ethtool_get_eeprom_len, ++ .get_eeprom = smsc95xx_ethtool_get_eeprom, ++ .set_eeprom = smsc95xx_ethtool_set_eeprom, ++ .get_regs_len = smsc95xx_ethtool_getregslen, ++ .get_regs = smsc95xx_ethtool_getregs, ++ .get_wol = smsc95xx_ethtool_get_wol, ++ .set_wol = smsc95xx_ethtool_set_wol, ++}; ++ ++static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ ++ if (!netif_running(netdev)) ++ return -EINVAL; ++ ++ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); ++} ++ ++static void smsc95xx_init_mac_address(struct usbnet *dev) ++{ ++ /* try reading mac address from EEPROM */ ++ if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, ++ dev->net->dev_addr) == 0) { ++ if (is_valid_ether_addr(dev->net->dev_addr)) { ++ /* eeprom values are valid so use them */ ++ netif_dbg(dev, ifup, dev->net, "MAC address read from EEPROM\n"); ++ return; ++ } ++ } ++ ++ /* no eeprom, or eeprom values are invalid. generate random MAC */ ++ eth_hw_addr_random(dev->net); ++ netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n"); ++} ++ ++static int smsc95xx_set_mac_address(struct usbnet *dev) ++{ ++ u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 | ++ dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24; ++ u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8; ++ int ret; ++ ++ ret = smsc95xx_write_reg(dev, ADDRL, addr_lo); ++ if (ret < 0) ++ return ret; ++ ++ return smsc95xx_write_reg(dev, ADDRH, addr_hi); ++} ++ ++/* starts the TX path */ ++static int smsc95xx_start_tx_path(struct usbnet *dev) ++{ ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ unsigned long flags; ++ int ret; ++ ++ /* Enable Tx at MAC */ ++ spin_lock_irqsave(&pdata->mac_cr_lock, flags); ++ pdata->mac_cr |= MAC_CR_TXEN_; ++ spin_unlock_irqrestore(&pdata->mac_cr_lock, flags); ++ ++ ret = smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr); ++ if (ret < 0) ++ return ret; ++ ++ /* Enable Tx at SCSRs */ ++ return smsc95xx_write_reg(dev, TX_CFG, TX_CFG_ON_); ++} ++ ++/* Starts the Receive path */ ++static int smsc95xx_start_rx_path(struct usbnet *dev, int in_pm) ++{ ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&pdata->mac_cr_lock, flags); ++ pdata->mac_cr |= MAC_CR_RXEN_; ++ spin_unlock_irqrestore(&pdata->mac_cr_lock, flags); ++ ++ return __smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr, in_pm); ++} ++ ++static int smsc95xx_phy_initialize(struct usbnet *dev) ++{ ++ int bmcr, ret, timeout = 0; ++ ++ /* Initialize MII structure */ ++ dev->mii.dev = dev->net; ++ dev->mii.mdio_read = smsc95xx_mdio_read; ++ dev->mii.mdio_write = smsc95xx_mdio_write; ++ dev->mii.phy_id_mask = 0x1f; ++ dev->mii.reg_num_mask = 0x1f; ++ dev->mii.phy_id = SMSC95XX_INTERNAL_PHY_ID; ++ ++ /* reset phy and wait for reset to complete */ ++ smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); ++ ++ do { ++ msleep(10); ++ bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); ++ timeout++; ++ } while ((bmcr & BMCR_RESET) && (timeout < 100)); ++ ++ if (timeout >= 100) { ++ netdev_warn(dev->net, "timeout on PHY Reset"); ++ return -EIO; ++ } ++ ++ smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ++ ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | ++ ADVERTISE_PAUSE_ASYM); ++ ++ /* read to clear */ ++ ret = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to read PHY_INT_SRC during init\n"); ++ return ret; ++ } ++ ++ smsc95xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK, ++ PHY_INT_MASK_DEFAULT_); ++ mii_nway_restart(&dev->mii); ++ ++ netif_dbg(dev, ifup, dev->net, "phy initialised successfully\n"); ++ return 0; ++} ++ ++static int smsc95xx_reset(struct usbnet *dev) ++{ ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ u32 read_buf, write_buf, burst_cap; ++ int ret = 0, timeout; ++ ++ netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n"); ++ ++ ret = smsc95xx_write_reg(dev, HW_CFG, HW_CFG_LRST_); ++ if (ret < 0) ++ return ret; ++ ++ timeout = 0; ++ do { ++ msleep(10); ++ ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); ++ if (ret < 0) ++ return ret; ++ timeout++; ++ } while ((read_buf & HW_CFG_LRST_) && (timeout < 100)); ++ ++ if (timeout >= 100) { ++ netdev_warn(dev->net, "timeout waiting for completion of Lite Reset\n"); ++ return ret; ++ } ++ ++ ret = smsc95xx_write_reg(dev, PM_CTRL, PM_CTL_PHY_RST_); ++ if (ret < 0) ++ return ret; ++ ++ timeout = 0; ++ do { ++ msleep(10); ++ ret = smsc95xx_read_reg(dev, PM_CTRL, &read_buf); ++ if (ret < 0) ++ return ret; ++ timeout++; ++ } while ((read_buf & PM_CTL_PHY_RST_) && (timeout < 100)); ++ ++ if (timeout >= 100) { ++ netdev_warn(dev->net, "timeout waiting for PHY Reset\n"); ++ return ret; ++ } ++ ++ ret = smsc95xx_set_mac_address(dev); ++ if (ret < 0) ++ return ret; ++ ++ netif_dbg(dev, ifup, dev->net, "MAC Address: %pM\n", ++ dev->net->dev_addr); ++ ++ ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); ++ if (ret < 0) ++ return ret; ++ ++ netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x\n", ++ read_buf); ++ ++ read_buf |= HW_CFG_BIR_; ++ ++ ret = smsc95xx_write_reg(dev, HW_CFG, read_buf); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); ++ if (ret < 0) ++ return ret; ++ ++ netif_dbg(dev, ifup, dev->net, ++ "Read Value from HW_CFG after writing HW_CFG_BIR_: 0x%08x\n", ++ read_buf); ++ ++ if (!turbo_mode) { ++ burst_cap = 0; ++ dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; ++ } else if (dev->udev->speed == USB_SPEED_HIGH) { ++ burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; ++ dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; ++ } else { ++ burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; ++ dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n", ++ (ulong)dev->rx_urb_size); ++ ++ ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc95xx_read_reg(dev, BURST_CAP, &read_buf); ++ if (ret < 0) ++ return ret; ++ ++ netif_dbg(dev, ifup, dev->net, ++ "Read Value from BURST_CAP after writing: 0x%08x\n", ++ read_buf); ++ ++ ret = smsc95xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc95xx_read_reg(dev, BULK_IN_DLY, &read_buf); ++ if (ret < 0) ++ return ret; ++ ++ netif_dbg(dev, ifup, dev->net, ++ "Read Value from BULK_IN_DLY after writing: 0x%08x\n", ++ read_buf); ++ ++ ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); ++ if (ret < 0) ++ return ret; ++ ++ netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG: 0x%08x\n", ++ read_buf); ++ ++ if (turbo_mode) ++ read_buf |= (HW_CFG_MEF_ | HW_CFG_BCE_); ++ ++ read_buf &= ~HW_CFG_RXDOFF_; ++ ++ /* set Rx data offset=2, Make IP header aligns on word boundary. */ ++ read_buf |= NET_IP_ALIGN << 9; ++ ++ ret = smsc95xx_write_reg(dev, HW_CFG, read_buf); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); ++ if (ret < 0) ++ return ret; ++ ++ netif_dbg(dev, ifup, dev->net, ++ "Read Value from HW_CFG after writing: 0x%08x\n", read_buf); ++ ++ ret = smsc95xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc95xx_read_reg(dev, ID_REV, &read_buf); ++ if (ret < 0) ++ return ret; ++ netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", read_buf); ++ ++ /* Configure GPIO pins as LED outputs */ ++ write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED | ++ LED_GPIO_CFG_FDX_LED; ++ ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf); ++ if (ret < 0) ++ return ret; ++ ++ /* Init Tx */ ++ ret = smsc95xx_write_reg(dev, FLOW, 0); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc95xx_write_reg(dev, AFC_CFG, AFC_CFG_DEFAULT); ++ if (ret < 0) ++ return ret; ++ ++ /* Don't need mac_cr_lock during initialisation */ ++ ret = smsc95xx_read_reg(dev, MAC_CR, &pdata->mac_cr); ++ if (ret < 0) ++ return ret; ++ ++ /* Init Rx */ ++ /* Set Vlan */ ++ ret = smsc95xx_write_reg(dev, VLAN1, (u32)ETH_P_8021Q); ++ if (ret < 0) ++ return ret; ++ ++ /* Enable or disable checksum offload engines */ ++ ret = smsc95xx_set_features(dev->net, dev->net->features); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to set checksum offload features\n"); ++ return ret; ++ } ++ ++ smsc95xx_set_multicast(dev->net); ++ ++ ret = smsc95xx_phy_initialize(dev); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to init PHY\n"); ++ return ret; ++ } ++ ++ ret = smsc95xx_read_reg(dev, INT_EP_CTL, &read_buf); ++ if (ret < 0) ++ return ret; ++ ++ /* enable PHY interrupts */ ++ read_buf |= INT_EP_CTL_PHY_INT_; ++ ++ ret = smsc95xx_write_reg(dev, INT_EP_CTL, read_buf); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc95xx_start_tx_path(dev); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to start TX path\n"); ++ return ret; ++ } ++ ++ ret = smsc95xx_start_rx_path(dev, 0); ++ if (ret < 0) { ++ netdev_warn(dev->net, "Failed to start RX path\n"); ++ return ret; ++ } ++ ++ netif_dbg(dev, ifup, dev->net, "smsc95xx_reset, return 0\n"); ++ return 0; ++} ++ ++static const struct net_device_ops smsc95xx_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = usbnet_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = smsc95xx_ioctl, ++ .ndo_set_rx_mode = smsc95xx_set_multicast, ++ .ndo_set_features = smsc95xx_set_features, ++}; ++ ++static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ struct smsc95xx_priv *pdata = NULL; ++ u32 val; ++ int ret; ++ ++ printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n"); ++ ++ ret = usbnet_get_endpoints(dev, intf); ++ if (ret < 0) { ++ netdev_warn(dev->net, "usbnet_get_endpoints failed: %d\n", ret); ++ return ret; ++ } ++ ++ dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc95xx_priv), ++ GFP_KERNEL); ++ ++ pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ if (!pdata) ++ return -ENOMEM; ++ ++ spin_lock_init(&pdata->mac_cr_lock); ++ ++ if (DEFAULT_TX_CSUM_ENABLE) ++ dev->net->features |= NETIF_F_HW_CSUM; ++ if (DEFAULT_RX_CSUM_ENABLE) ++ dev->net->features |= NETIF_F_RXCSUM; ++ ++ dev->net->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM; ++ ++ smsc95xx_init_mac_address(dev); ++ ++ /* Init all registers */ ++ ret = smsc95xx_reset(dev); ++ ++ /* detect device revision as different features may be available */ ++ ret = smsc95xx_read_reg(dev, ID_REV, &val); ++ if (ret < 0) ++ return ret; ++ val >>= 16; ++ ++ if ((val == ID_REV_CHIP_ID_9500A_) || (val == ID_REV_CHIP_ID_9530_) || ++ (val == ID_REV_CHIP_ID_89530_) || (val == ID_REV_CHIP_ID_9730_)) ++ pdata->features = (FEATURE_8_WAKEUP_FILTERS | ++ FEATURE_PHY_NLP_CROSSOVER | ++ FEATURE_REMOTE_WAKEUP); ++ else if (val == ID_REV_CHIP_ID_9512_) ++ pdata->features = FEATURE_8_WAKEUP_FILTERS; ++ ++ dev->net->netdev_ops = &smsc95xx_netdev_ops; ++ dev->net->ethtool_ops = &smsc95xx_ethtool_ops; ++ dev->net->flags |= IFF_MULTICAST; ++ dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM; ++ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; ++ return 0; ++} ++ ++static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ if (pdata) { ++ netif_dbg(dev, ifdown, dev->net, "free pdata\n"); ++ kfree(pdata); ++ pdata = NULL; ++ dev->data[0] = 0; ++ } ++} ++ ++static u32 smsc_crc(const u8 *buffer, size_t len, int filter) ++{ ++ u32 crc = bitrev16(crc16(0xFFFF, buffer, len)); ++ return crc << ((filter % 2) * 16); ++} ++ ++static int smsc95xx_enable_phy_wakeup_interrupts(struct usbnet *dev, u16 mask) ++{ ++ struct mii_if_info *mii = &dev->mii; ++ int ret; ++ ++ netdev_dbg(dev->net, "enabling PHY wakeup interrupts\n"); ++ ++ /* read to clear */ ++ ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_INT_SRC); ++ if (ret < 0) ++ return ret; ++ ++ /* enable interrupt source */ ++ ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_INT_MASK); ++ if (ret < 0) ++ return ret; ++ ++ ret |= mask; ++ ++ smsc95xx_mdio_write_nopm(dev->net, mii->phy_id, PHY_INT_MASK, ret); ++ ++ return 0; ++} ++ ++static int smsc95xx_link_ok_nopm(struct usbnet *dev) ++{ ++ struct mii_if_info *mii = &dev->mii; ++ int ret; ++ ++ /* first, a dummy read, needed to latch some MII phys */ ++ ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, MII_BMSR); ++ if (ret < 0) ++ return ret; ++ ++ ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, MII_BMSR); ++ if (ret < 0) ++ return ret; ++ ++ return !!(ret & BMSR_LSTATUS); ++} ++ ++static int smsc95xx_enter_suspend0(struct usbnet *dev) ++{ ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ u32 val; ++ int ret; ++ ++ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); ++ if (ret < 0) ++ return ret; ++ ++ val &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_)); ++ val |= PM_CTL_SUS_MODE_0; ++ ++ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); ++ if (ret < 0) ++ return ret; ++ ++ /* clear wol status */ ++ val &= ~PM_CTL_WUPS_; ++ val |= PM_CTL_WUPS_WOL_; ++ ++ /* enable energy detection */ ++ if (pdata->wolopts & WAKE_PHY) ++ val |= PM_CTL_WUPS_ED_; ++ ++ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); ++ if (ret < 0) ++ return ret; ++ ++ /* read back PM_CTRL */ ++ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); ++ if (ret < 0) ++ return ret; ++ ++ pdata->suspend_flags |= SUSPEND_SUSPEND0; ++ ++ return 0; ++} ++ ++static int smsc95xx_enter_suspend1(struct usbnet *dev) ++{ ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ struct mii_if_info *mii = &dev->mii; ++ u32 val; ++ int ret; ++ ++ /* reconfigure link pulse detection timing for ++ * compatibility with non-standard link partners ++ */ ++ if (pdata->features & FEATURE_PHY_NLP_CROSSOVER) ++ smsc95xx_mdio_write_nopm(dev->net, mii->phy_id, PHY_EDPD_CONFIG, ++ PHY_EDPD_CONFIG_DEFAULT); ++ ++ /* enable energy detect power-down mode */ ++ ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_MODE_CTRL_STS); ++ if (ret < 0) ++ return ret; ++ ++ ret |= MODE_CTRL_STS_EDPWRDOWN_; ++ ++ smsc95xx_mdio_write_nopm(dev->net, mii->phy_id, PHY_MODE_CTRL_STS, ret); ++ ++ /* enter SUSPEND1 mode */ ++ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); ++ if (ret < 0) ++ return ret; ++ ++ val &= ~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_); ++ val |= PM_CTL_SUS_MODE_1; ++ ++ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); ++ if (ret < 0) ++ return ret; ++ ++ /* clear wol status, enable energy detection */ ++ val &= ~PM_CTL_WUPS_; ++ val |= (PM_CTL_WUPS_ED_ | PM_CTL_ED_EN_); ++ ++ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); ++ if (ret < 0) ++ return ret; ++ ++ pdata->suspend_flags |= SUSPEND_SUSPEND1; ++ ++ return 0; ++} ++ ++static int smsc95xx_enter_suspend2(struct usbnet *dev) ++{ ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ u32 val; ++ int ret; ++ ++ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); ++ if (ret < 0) ++ return ret; ++ ++ val &= ~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_); ++ val |= PM_CTL_SUS_MODE_2; ++ ++ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); ++ if (ret < 0) ++ return ret; ++ ++ pdata->suspend_flags |= SUSPEND_SUSPEND2; ++ ++ return 0; ++} ++ ++static int smsc95xx_enter_suspend3(struct usbnet *dev) ++{ ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ u32 val; ++ int ret; ++ ++ ret = smsc95xx_read_reg_nopm(dev, RX_FIFO_INF, &val); ++ if (ret < 0) ++ return ret; ++ ++ if (val & 0xFFFF) { ++ netdev_info(dev->net, "rx fifo not empty in autosuspend\n"); ++ return -EBUSY; ++ } ++ ++ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); ++ if (ret < 0) ++ return ret; ++ ++ val &= ~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_); ++ val |= PM_CTL_SUS_MODE_3 | PM_CTL_RES_CLR_WKP_STS; ++ ++ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); ++ if (ret < 0) ++ return ret; ++ ++ /* clear wol status */ ++ val &= ~PM_CTL_WUPS_; ++ val |= PM_CTL_WUPS_WOL_; ++ ++ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); ++ if (ret < 0) ++ return ret; ++ ++ pdata->suspend_flags |= SUSPEND_SUSPEND3; ++ ++ return 0; ++} ++ ++static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up) ++{ ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ int ret; ++ ++ if (!netif_running(dev->net)) { ++ /* interface is ifconfig down so fully power down hw */ ++ netdev_dbg(dev->net, "autosuspend entering SUSPEND2\n"); ++ return smsc95xx_enter_suspend2(dev); ++ } ++ ++ if (!link_up) { ++ /* link is down so enter EDPD mode, but only if device can ++ * reliably resume from it. This check should be redundant ++ * as current FEATURE_REMOTE_WAKEUP parts also support ++ * FEATURE_PHY_NLP_CROSSOVER but it's included for clarity */ ++ if (!(pdata->features & FEATURE_PHY_NLP_CROSSOVER)) { ++ netdev_warn(dev->net, "EDPD not supported\n"); ++ return -EBUSY; ++ } ++ ++ netdev_dbg(dev->net, "autosuspend entering SUSPEND1\n"); ++ ++ /* enable PHY wakeup events for if cable is attached */ ++ ret = smsc95xx_enable_phy_wakeup_interrupts(dev, ++ PHY_INT_MASK_ANEG_COMP_); ++ if (ret < 0) { ++ netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); ++ return ret; ++ } ++ ++ netdev_info(dev->net, "entering SUSPEND1 mode\n"); ++ return smsc95xx_enter_suspend1(dev); ++ } ++ ++ /* enable PHY wakeup events so we remote wakeup if cable is pulled */ ++ ret = smsc95xx_enable_phy_wakeup_interrupts(dev, ++ PHY_INT_MASK_LINK_DOWN_); ++ if (ret < 0) { ++ netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); ++ return ret; ++ } ++ ++ netdev_dbg(dev->net, "autosuspend entering SUSPEND3\n"); ++ return smsc95xx_enter_suspend3(dev); ++} ++ ++static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ u32 val, link_up; ++ int ret; ++ ++ ret = usbnet_suspend(intf, message); ++ if (ret < 0) { ++ netdev_warn(dev->net, "usbnet_suspend error\n"); ++ return ret; ++ } ++ ++ if (pdata->suspend_flags) { ++ netdev_warn(dev->net, "error during last resume\n"); ++ pdata->suspend_flags = 0; ++ } ++ ++ /* determine if link is up using only _nopm functions */ ++ link_up = smsc95xx_link_ok_nopm(dev); ++ ++ if (message.event == PM_EVENT_AUTO_SUSPEND && ++ (pdata->features & FEATURE_REMOTE_WAKEUP)) { ++ ret = smsc95xx_autosuspend(dev, link_up); ++ goto done; ++ } ++ ++ /* if we get this far we're not autosuspending */ ++ /* if no wol options set, or if link is down and we're not waking on ++ * PHY activity, enter lowest power SUSPEND2 mode ++ */ ++ if (!(pdata->wolopts & SUPPORTED_WAKE) || ++ !(link_up || (pdata->wolopts & WAKE_PHY))) { ++ netdev_info(dev->net, "entering SUSPEND2 mode\n"); ++ ++ /* disable energy detect (link up) & wake up events */ ++ ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) ++ goto done; ++ ++ val &= ~(WUCSR_MPEN_ | WUCSR_WAKE_EN_); ++ ++ ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) ++ goto done; ++ ++ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); ++ if (ret < 0) ++ goto done; ++ ++ val &= ~(PM_CTL_ED_EN_ | PM_CTL_WOL_EN_); ++ ++ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); ++ if (ret < 0) ++ goto done; ++ ++ ret = smsc95xx_enter_suspend2(dev); ++ goto done; ++ } ++ ++ if (pdata->wolopts & WAKE_PHY) { ++ ret = smsc95xx_enable_phy_wakeup_interrupts(dev, ++ (PHY_INT_MASK_ANEG_COMP_ | PHY_INT_MASK_LINK_DOWN_)); ++ if (ret < 0) { ++ netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); ++ goto done; ++ } ++ ++ /* if link is down then configure EDPD and enter SUSPEND1, ++ * otherwise enter SUSPEND0 below ++ */ ++ if (!link_up) { ++ netdev_info(dev->net, "entering SUSPEND1 mode\n"); ++ ret = smsc95xx_enter_suspend1(dev); ++ goto done; ++ } ++ } ++ ++ if (pdata->wolopts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST)) { ++ u32 *filter_mask = kzalloc(sizeof(u32) * 32, GFP_KERNEL); ++ u32 command[2]; ++ u32 offset[2]; ++ u32 crc[4]; ++ int wuff_filter_count = ++ (pdata->features & FEATURE_8_WAKEUP_FILTERS) ? ++ LAN9500A_WUFF_NUM : LAN9500_WUFF_NUM; ++ int i, filter = 0; ++ ++ if (!filter_mask) { ++ netdev_warn(dev->net, "Unable to allocate filter_mask\n"); ++ ret = -ENOMEM; ++ goto done; ++ } ++ ++ memset(command, 0, sizeof(command)); ++ memset(offset, 0, sizeof(offset)); ++ memset(crc, 0, sizeof(crc)); ++ ++ if (pdata->wolopts & WAKE_BCAST) { ++ const u8 bcast[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; ++ netdev_info(dev->net, "enabling broadcast detection\n"); ++ filter_mask[filter * 4] = 0x003F; ++ filter_mask[filter * 4 + 1] = 0x00; ++ filter_mask[filter * 4 + 2] = 0x00; ++ filter_mask[filter * 4 + 3] = 0x00; ++ command[filter/4] |= 0x05UL << ((filter % 4) * 8); ++ offset[filter/4] |= 0x00 << ((filter % 4) * 8); ++ crc[filter/2] |= smsc_crc(bcast, 6, filter); ++ filter++; ++ } ++ ++ if (pdata->wolopts & WAKE_MCAST) { ++ const u8 mcast[] = {0x01, 0x00, 0x5E}; ++ netdev_info(dev->net, "enabling multicast detection\n"); ++ filter_mask[filter * 4] = 0x0007; ++ filter_mask[filter * 4 + 1] = 0x00; ++ filter_mask[filter * 4 + 2] = 0x00; ++ filter_mask[filter * 4 + 3] = 0x00; ++ command[filter/4] |= 0x09UL << ((filter % 4) * 8); ++ offset[filter/4] |= 0x00 << ((filter % 4) * 8); ++ crc[filter/2] |= smsc_crc(mcast, 3, filter); ++ filter++; ++ } ++ ++ if (pdata->wolopts & WAKE_ARP) { ++ const u8 arp[] = {0x08, 0x06}; ++ netdev_info(dev->net, "enabling ARP detection\n"); ++ filter_mask[filter * 4] = 0x0003; ++ filter_mask[filter * 4 + 1] = 0x00; ++ filter_mask[filter * 4 + 2] = 0x00; ++ filter_mask[filter * 4 + 3] = 0x00; ++ command[filter/4] |= 0x05UL << ((filter % 4) * 8); ++ offset[filter/4] |= 0x0C << ((filter % 4) * 8); ++ crc[filter/2] |= smsc_crc(arp, 2, filter); ++ filter++; ++ } ++ ++ if (pdata->wolopts & WAKE_UCAST) { ++ netdev_info(dev->net, "enabling unicast detection\n"); ++ filter_mask[filter * 4] = 0x003F; ++ filter_mask[filter * 4 + 1] = 0x00; ++ filter_mask[filter * 4 + 2] = 0x00; ++ filter_mask[filter * 4 + 3] = 0x00; ++ command[filter/4] |= 0x01UL << ((filter % 4) * 8); ++ offset[filter/4] |= 0x00 << ((filter % 4) * 8); ++ crc[filter/2] |= smsc_crc(dev->net->dev_addr, ETH_ALEN, filter); ++ filter++; ++ } ++ ++ for (i = 0; i < (wuff_filter_count * 4); i++) { ++ ret = smsc95xx_write_reg_nopm(dev, WUFF, filter_mask[i]); ++ if (ret < 0) { ++ kfree(filter_mask); ++ goto done; ++ } ++ } ++ kfree(filter_mask); ++ ++ for (i = 0; i < (wuff_filter_count / 4); i++) { ++ ret = smsc95xx_write_reg_nopm(dev, WUFF, command[i]); ++ if (ret < 0) ++ goto done; ++ } ++ ++ for (i = 0; i < (wuff_filter_count / 4); i++) { ++ ret = smsc95xx_write_reg_nopm(dev, WUFF, offset[i]); ++ if (ret < 0) ++ goto done; ++ } ++ ++ for (i = 0; i < (wuff_filter_count / 2); i++) { ++ ret = smsc95xx_write_reg_nopm(dev, WUFF, crc[i]); ++ if (ret < 0) ++ goto done; ++ } ++ ++ /* clear any pending pattern match packet status */ ++ ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) ++ goto done; ++ ++ val |= WUCSR_WUFR_; ++ ++ ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) ++ goto done; ++ } ++ ++ if (pdata->wolopts & WAKE_MAGIC) { ++ /* clear any pending magic packet status */ ++ ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) ++ goto done; ++ ++ val |= WUCSR_MPR_; ++ ++ ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) ++ goto done; ++ } ++ ++ /* enable/disable wakeup sources */ ++ ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) ++ goto done; ++ ++ if (pdata->wolopts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST)) { ++ netdev_info(dev->net, "enabling pattern match wakeup\n"); ++ val |= WUCSR_WAKE_EN_; ++ } else { ++ netdev_info(dev->net, "disabling pattern match wakeup\n"); ++ val &= ~WUCSR_WAKE_EN_; ++ } ++ ++ if (pdata->wolopts & WAKE_MAGIC) { ++ netdev_info(dev->net, "enabling magic packet wakeup\n"); ++ val |= WUCSR_MPEN_; ++ } else { ++ netdev_info(dev->net, "disabling magic packet wakeup\n"); ++ val &= ~WUCSR_MPEN_; ++ } ++ ++ ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) ++ goto done; ++ ++ /* enable wol wakeup source */ ++ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); ++ if (ret < 0) ++ goto done; ++ ++ val |= PM_CTL_WOL_EN_; ++ ++ /* phy energy detect wakeup source */ ++ if (pdata->wolopts & WAKE_PHY) ++ val |= PM_CTL_ED_EN_; ++ ++ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); ++ if (ret < 0) ++ goto done; ++ ++ /* enable receiver to enable frame reception */ ++ smsc95xx_start_rx_path(dev, 1); ++ ++ /* some wol options are enabled, so enter SUSPEND0 */ ++ netdev_info(dev->net, "entering SUSPEND0 mode\n"); ++ ret = smsc95xx_enter_suspend0(dev); ++ ++done: ++ /* ++ * TODO: resume() might need to handle the suspend failure ++ * in system sleep ++ */ ++ if (ret && PMSG_IS_AUTO(message)) ++ usbnet_resume(intf); ++ return ret; ++} ++ ++static int smsc95xx_resume(struct usb_interface *intf) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ u8 suspend_flags = pdata->suspend_flags; ++ int ret; ++ u32 val; ++ ++ BUG_ON(!dev); ++ ++ netdev_dbg(dev->net, "resume suspend_flags=0x%02x\n", suspend_flags); ++ ++ /* do this first to ensure it's cleared even in error case */ ++ pdata->suspend_flags = 0; ++ ++ if (suspend_flags & SUSPEND_ALLMODES) { ++ /* clear wake-up sources */ ++ ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); ++ if (ret < 0) ++ return ret; ++ ++ val &= ~(WUCSR_WAKE_EN_ | WUCSR_MPEN_); ++ ++ ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); ++ if (ret < 0) ++ return ret; ++ ++ /* clear wake-up status */ ++ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); ++ if (ret < 0) ++ return ret; ++ ++ val &= ~PM_CTL_WOL_EN_; ++ val |= PM_CTL_WUPS_; ++ ++ ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); ++ if (ret < 0) ++ return ret; ++ } ++ ++ ret = usbnet_resume(intf); ++ if (ret < 0) ++ netdev_warn(dev->net, "usbnet_resume error\n"); ++ ++ return ret; ++} ++ ++static int smsc95xx_reset_resume(struct usb_interface *intf) ++{ ++ struct usbnet *dev = usb_get_intfdata(intf); ++ int ret; ++ ++ ret = smsc95xx_reset(dev); ++ if (ret < 0) ++ return ret; ++ ++ return smsc95xx_resume(intf); ++} ++ ++static void smsc95xx_rx_csum_offload(struct sk_buff *skb) ++{ ++ skb->csum = *(u16 *)(skb_tail_pointer(skb) - 2); ++ skb->ip_summed = CHECKSUM_COMPLETE; ++ skb_trim(skb, skb->len - 2); ++} ++ ++static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ ++ while (skb->len > 0) { ++ u32 header, align_count; ++ struct sk_buff *ax_skb; ++ unsigned char *packet; ++ u16 size; ++ ++ memcpy(&header, skb->data, sizeof(header)); ++ le32_to_cpus(&header); ++ skb_pull(skb, 4 + NET_IP_ALIGN); ++ packet = skb->data; ++ ++ /* get the packet length */ ++ size = (u16)((header & RX_STS_FL_) >> 16); ++ align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; ++ ++ if (unlikely(header & RX_STS_ES_)) { ++ netif_dbg(dev, rx_err, dev->net, ++ "Error header=0x%08x\n", header); ++ dev->net->stats.rx_errors++; ++ dev->net->stats.rx_dropped++; ++ ++ if (header & RX_STS_CRC_) { ++ dev->net->stats.rx_crc_errors++; ++ } else { ++ if (header & (RX_STS_TL_ | RX_STS_RF_)) ++ dev->net->stats.rx_frame_errors++; ++ ++ if ((header & RX_STS_LE_) && ++ (!(header & RX_STS_FT_))) ++ dev->net->stats.rx_length_errors++; ++ } ++ } else { ++ /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ ++ if (unlikely(size > (ETH_FRAME_LEN + 12))) { ++ netif_dbg(dev, rx_err, dev->net, ++ "size err header=0x%08x\n", header); ++ return 0; ++ } ++ ++ /* last frame in this batch */ ++ if (skb->len == size) { ++ if (dev->net->features & NETIF_F_RXCSUM) ++ smsc95xx_rx_csum_offload(skb); ++ skb_trim(skb, skb->len - 4); /* remove fcs */ ++ skb->truesize = size + sizeof(struct sk_buff); ++ ++ return 1; ++ } ++ ++ ax_skb = skb_clone(skb, GFP_ATOMIC); ++ if (unlikely(!ax_skb)) { ++ netdev_warn(dev->net, "Error allocating skb\n"); ++ return 0; ++ } ++ ++ ax_skb->len = size; ++ ax_skb->data = packet; ++ skb_set_tail_pointer(ax_skb, size); ++ ++ if (dev->net->features & NETIF_F_RXCSUM) ++ smsc95xx_rx_csum_offload(ax_skb); ++ skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ ++ ax_skb->truesize = size + sizeof(struct sk_buff); ++ ++ usbnet_skb_return(dev, ax_skb); ++ } ++ ++ skb_pull(skb, size); ++ ++ /* padding bytes before the next frame starts */ ++ if (skb->len) ++ skb_pull(skb, align_count); ++ } ++ ++ if (unlikely(skb->len < 0)) { ++ netdev_warn(dev->net, "invalid rx length<0 %d\n", skb->len); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb) ++{ ++ u16 low_16 = (u16)skb_checksum_start_offset(skb); ++ u16 high_16 = low_16 + skb->csum_offset; ++ return (high_16 << 16) | low_16; ++} ++ ++static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, ++ struct sk_buff *skb, gfp_t flags) ++{ ++ bool csum = skb->ip_summed == CHECKSUM_PARTIAL; ++ int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD; ++ u32 tx_cmd_a, tx_cmd_b; ++ ++ /* We do not advertise SG, so skbs should be already linearized */ ++ BUG_ON(skb_shinfo(skb)->nr_frags); ++ ++ if (skb_headroom(skb) < overhead) { ++ struct sk_buff *skb2 = skb_copy_expand(skb, ++ overhead, 0, flags); ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ if (!skb) ++ return NULL; ++ } ++ ++ if (csum) { ++ if (skb->len <= 45) { ++ /* workaround - hardware tx checksum does not work ++ * properly with extremely small packets */ ++ long csstart = skb_checksum_start_offset(skb); ++ __wsum calc = csum_partial(skb->data + csstart, ++ skb->len - csstart, 0); ++ *((__sum16 *)(skb->data + csstart ++ + skb->csum_offset)) = csum_fold(calc); ++ ++ csum = false; ++ } else { ++ u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); ++ skb_push(skb, 4); ++ cpu_to_le32s(&csum_preamble); ++ memcpy(skb->data, &csum_preamble, 4); ++ } ++ } ++ ++ skb_push(skb, 4); ++ tx_cmd_b = (u32)(skb->len - 4); ++ if (csum) ++ tx_cmd_b |= TX_CMD_B_CSUM_ENABLE; ++ cpu_to_le32s(&tx_cmd_b); ++ memcpy(skb->data, &tx_cmd_b, 4); ++ ++ skb_push(skb, 4); ++ tx_cmd_a = (u32)(skb->len - 8) | TX_CMD_A_FIRST_SEG_ | ++ TX_CMD_A_LAST_SEG_; ++ cpu_to_le32s(&tx_cmd_a); ++ memcpy(skb->data, &tx_cmd_a, 4); ++ ++ return skb; ++} ++ ++static int smsc95xx_manage_power(struct usbnet *dev, int on) ++{ ++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); ++ ++ dev->intf->needs_remote_wakeup = on; ++ ++ if (pdata->features & FEATURE_REMOTE_WAKEUP) ++ return 0; ++ ++ /* this chip revision isn't capable of remote wakeup */ ++ netdev_info(dev->net, "hardware isn't capable of remote wakeup\n"); ++ ++ if (on) ++ usb_autopm_get_interface_no_resume(dev->intf); ++ else ++ usb_autopm_put_interface(dev->intf); ++ ++ return 0; ++} ++ ++static const struct driver_info smsc95xx_info = { ++ .description = "smsc95xx USB 2.0 Ethernet", ++ .bind = smsc95xx_bind, ++ .unbind = smsc95xx_unbind, ++ .link_reset = smsc95xx_link_reset, ++ .reset = smsc95xx_reset, ++ .rx_fixup = smsc95xx_rx_fixup, ++ .tx_fixup = smsc95xx_tx_fixup, ++ .status = smsc95xx_status, ++ .manage_power = smsc95xx_manage_power, ++ .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR, ++}; ++ ++static const struct usb_device_id products[] = { ++ { ++ /* SMSC9500 USB Ethernet Device */ ++ USB_DEVICE(0x0424, 0x9500), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9505 USB Ethernet Device */ ++ USB_DEVICE(0x0424, 0x9505), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9500A USB Ethernet Device */ ++ USB_DEVICE(0x0424, 0x9E00), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9505A USB Ethernet Device */ ++ USB_DEVICE(0x0424, 0x9E01), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9512/9514 USB Hub & Ethernet Device */ ++ USB_DEVICE(0x0424, 0xec00), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9500 USB Ethernet Device (SAL10) */ ++ USB_DEVICE(0x0424, 0x9900), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9505 USB Ethernet Device (SAL10) */ ++ USB_DEVICE(0x0424, 0x9901), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9500A USB Ethernet Device (SAL10) */ ++ USB_DEVICE(0x0424, 0x9902), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9505A USB Ethernet Device (SAL10) */ ++ USB_DEVICE(0x0424, 0x9903), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9512/9514 USB Hub & Ethernet Device (SAL10) */ ++ USB_DEVICE(0x0424, 0x9904), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9500A USB Ethernet Device (HAL) */ ++ USB_DEVICE(0x0424, 0x9905), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9505A USB Ethernet Device (HAL) */ ++ USB_DEVICE(0x0424, 0x9906), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9500 USB Ethernet Device (Alternate ID) */ ++ USB_DEVICE(0x0424, 0x9907), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9500A USB Ethernet Device (Alternate ID) */ ++ USB_DEVICE(0x0424, 0x9908), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9512/9514 USB Hub & Ethernet Device (Alternate ID) */ ++ USB_DEVICE(0x0424, 0x9909), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC LAN9530 USB Ethernet Device */ ++ USB_DEVICE(0x0424, 0x9530), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC LAN9730 USB Ethernet Device */ ++ USB_DEVICE(0x0424, 0x9730), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC LAN89530 USB Ethernet Device */ ++ USB_DEVICE(0x0424, 0x9E08), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { }, /* END */ ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver smsc95xx_driver = { ++ .name = "smsc95xx", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .suspend = smsc95xx_suspend, ++ .resume = smsc95xx_resume, ++ .reset_resume = smsc95xx_reset_resume, ++ .disconnect = usbnet_disconnect, ++ .disable_hub_initiated_lpm = 1, ++ .supports_autosuspend = 1, ++}; ++ ++module_usb_driver(smsc95xx_driver); ++ ++MODULE_AUTHOR("Nancy Lin"); ++MODULE_AUTHOR("Steve Glendinning steve.glendinning@shawell.net"); ++MODULE_DESCRIPTION("SMSC95XX USB 2.0 Ethernet Devices"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/smsc95xx.h backports-3.18.1-1/drivers/net/usb/smsc95xx.h +--- backports-3.18.1-1.org/drivers/net/usb/smsc95xx.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/smsc95xx.h 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,290 @@ ++ /*************************************************************************** ++ * ++ * Copyright (C) 2007-2008 SMSC ++ * ++ * 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 http://www.gnu.org/licenses/. ++ * ++ *****************************************************************************/ ++ ++#ifndef _SMSC95XX_H ++#define _SMSC95XX_H ++ ++/* Tx command words */ ++#define TX_CMD_A_DATA_OFFSET_ (0x001F0000) ++#define TX_CMD_A_FIRST_SEG_ (0x00002000) ++#define TX_CMD_A_LAST_SEG_ (0x00001000) ++#define TX_CMD_A_BUF_SIZE_ (0x000007FF) ++ ++#define TX_CMD_B_CSUM_ENABLE (0x00004000) ++#define TX_CMD_B_ADD_CRC_DISABLE_ (0x00002000) ++#define TX_CMD_B_DISABLE_PADDING_ (0x00001000) ++#define TX_CMD_B_PKT_BYTE_LENGTH_ (0x000007FF) ++ ++/* Rx status word */ ++#define RX_STS_FF_ (0x40000000) /* Filter Fail */ ++#define RX_STS_FL_ (0x3FFF0000) /* Frame Length */ ++#define RX_STS_ES_ (0x00008000) /* Error Summary */ ++#define RX_STS_BF_ (0x00002000) /* Broadcast Frame */ ++#define RX_STS_LE_ (0x00001000) /* Length Error */ ++#define RX_STS_RF_ (0x00000800) /* Runt Frame */ ++#define RX_STS_MF_ (0x00000400) /* Multicast Frame */ ++#define RX_STS_TL_ (0x00000080) /* Frame too long */ ++#define RX_STS_CS_ (0x00000040) /* Collision Seen */ ++#define RX_STS_FT_ (0x00000020) /* Frame Type */ ++#define RX_STS_RW_ (0x00000010) /* Receive Watchdog */ ++#define RX_STS_ME_ (0x00000008) /* Mii Error */ ++#define RX_STS_DB_ (0x00000004) /* Dribbling */ ++#define RX_STS_CRC_ (0x00000002) /* CRC Error */ ++ ++/* SCSRs */ ++#define ID_REV (0x00) ++#define ID_REV_CHIP_ID_MASK_ (0xFFFF0000) ++#define ID_REV_CHIP_REV_MASK_ (0x0000FFFF) ++#define ID_REV_CHIP_ID_9500_ (0x9500) ++#define ID_REV_CHIP_ID_9500A_ (0x9E00) ++#define ID_REV_CHIP_ID_9512_ (0xEC00) ++#define ID_REV_CHIP_ID_9530_ (0x9530) ++#define ID_REV_CHIP_ID_89530_ (0x9E08) ++#define ID_REV_CHIP_ID_9730_ (0x9730) ++ ++#define INT_STS (0x08) ++#define INT_STS_TX_STOP_ (0x00020000) ++#define INT_STS_RX_STOP_ (0x00010000) ++#define INT_STS_PHY_INT_ (0x00008000) ++#define INT_STS_TXE_ (0x00004000) ++#define INT_STS_TDFU_ (0x00002000) ++#define INT_STS_TDFO_ (0x00001000) ++#define INT_STS_RXDF_ (0x00000800) ++#define INT_STS_GPIOS_ (0x000007FF) ++#define INT_STS_CLEAR_ALL_ (0xFFFFFFFF) ++ ++#define RX_CFG (0x0C) ++#define RX_FIFO_FLUSH_ (0x00000001) ++ ++#define TX_CFG (0x10) ++#define TX_CFG_ON_ (0x00000004) ++#define TX_CFG_STOP_ (0x00000002) ++#define TX_CFG_FIFO_FLUSH_ (0x00000001) ++ ++#define HW_CFG (0x14) ++#define HW_CFG_BIR_ (0x00001000) ++#define HW_CFG_LEDB_ (0x00000800) ++#define HW_CFG_RXDOFF_ (0x00000600) ++#define HW_CFG_DRP_ (0x00000040) ++#define HW_CFG_MEF_ (0x00000020) ++#define HW_CFG_LRST_ (0x00000008) ++#define HW_CFG_PSEL_ (0x00000004) ++#define HW_CFG_BCE_ (0x00000002) ++#define HW_CFG_SRST_ (0x00000001) ++ ++#define RX_FIFO_INF (0x18) ++ ++#define PM_CTRL (0x20) ++#define PM_CTL_RES_CLR_WKP_STS (0x00000200) ++#define PM_CTL_DEV_RDY_ (0x00000080) ++#define PM_CTL_SUS_MODE_ (0x00000060) ++#define PM_CTL_SUS_MODE_0 (0x00000000) ++#define PM_CTL_SUS_MODE_1 (0x00000020) ++#define PM_CTL_SUS_MODE_2 (0x00000040) ++#define PM_CTL_SUS_MODE_3 (0x00000060) ++#define PM_CTL_PHY_RST_ (0x00000010) ++#define PM_CTL_WOL_EN_ (0x00000008) ++#define PM_CTL_ED_EN_ (0x00000004) ++#define PM_CTL_WUPS_ (0x00000003) ++#define PM_CTL_WUPS_NO_ (0x00000000) ++#define PM_CTL_WUPS_ED_ (0x00000001) ++#define PM_CTL_WUPS_WOL_ (0x00000002) ++#define PM_CTL_WUPS_MULTI_ (0x00000003) ++ ++#define LED_GPIO_CFG (0x24) ++#define LED_GPIO_CFG_SPD_LED (0x01000000) ++#define LED_GPIO_CFG_LNK_LED (0x00100000) ++#define LED_GPIO_CFG_FDX_LED (0x00010000) ++ ++#define GPIO_CFG (0x28) ++ ++#define AFC_CFG (0x2C) ++ ++/* Hi watermark = 15.5Kb (~10 mtu pkts) */ ++/* low watermark = 3k (~2 mtu pkts) */ ++/* backpressure duration = ~ 350us */ ++/* Apply FC on any frame. */ ++#define AFC_CFG_DEFAULT (0x00F830A1) ++ ++#define E2P_CMD (0x30) ++#define E2P_CMD_BUSY_ (0x80000000) ++#define E2P_CMD_MASK_ (0x70000000) ++#define E2P_CMD_READ_ (0x00000000) ++#define E2P_CMD_EWDS_ (0x10000000) ++#define E2P_CMD_EWEN_ (0x20000000) ++#define E2P_CMD_WRITE_ (0x30000000) ++#define E2P_CMD_WRAL_ (0x40000000) ++#define E2P_CMD_ERASE_ (0x50000000) ++#define E2P_CMD_ERAL_ (0x60000000) ++#define E2P_CMD_RELOAD_ (0x70000000) ++#define E2P_CMD_TIMEOUT_ (0x00000400) ++#define E2P_CMD_LOADED_ (0x00000200) ++#define E2P_CMD_ADDR_ (0x000001FF) ++ ++#define MAX_EEPROM_SIZE (512) ++ ++#define E2P_DATA (0x34) ++#define E2P_DATA_MASK_ (0x000000FF) ++ ++#define BURST_CAP (0x38) ++ ++#define GPIO_WAKE (0x64) ++ ++#define INT_EP_CTL (0x68) ++#define INT_EP_CTL_INTEP_ (0x80000000) ++#define INT_EP_CTL_MACRTO_ (0x00080000) ++#define INT_EP_CTL_TX_STOP_ (0x00020000) ++#define INT_EP_CTL_RX_STOP_ (0x00010000) ++#define INT_EP_CTL_PHY_INT_ (0x00008000) ++#define INT_EP_CTL_TXE_ (0x00004000) ++#define INT_EP_CTL_TDFU_ (0x00002000) ++#define INT_EP_CTL_TDFO_ (0x00001000) ++#define INT_EP_CTL_RXDF_ (0x00000800) ++#define INT_EP_CTL_GPIOS_ (0x000007FF) ++ ++#define BULK_IN_DLY (0x6C) ++ ++/* MAC CSRs */ ++#define MAC_CR (0x100) ++#define MAC_CR_RXALL_ (0x80000000) ++#define MAC_CR_RCVOWN_ (0x00800000) ++#define MAC_CR_LOOPBK_ (0x00200000) ++#define MAC_CR_FDPX_ (0x00100000) ++#define MAC_CR_MCPAS_ (0x00080000) ++#define MAC_CR_PRMS_ (0x00040000) ++#define MAC_CR_INVFILT_ (0x00020000) ++#define MAC_CR_PASSBAD_ (0x00010000) ++#define MAC_CR_HFILT_ (0x00008000) ++#define MAC_CR_HPFILT_ (0x00002000) ++#define MAC_CR_LCOLL_ (0x00001000) ++#define MAC_CR_BCAST_ (0x00000800) ++#define MAC_CR_DISRTY_ (0x00000400) ++#define MAC_CR_PADSTR_ (0x00000100) ++#define MAC_CR_BOLMT_MASK (0x000000C0) ++#define MAC_CR_DFCHK_ (0x00000020) ++#define MAC_CR_TXEN_ (0x00000008) ++#define MAC_CR_RXEN_ (0x00000004) ++ ++#define ADDRH (0x104) ++ ++#define ADDRL (0x108) ++ ++#define HASHH (0x10C) ++ ++#define HASHL (0x110) ++ ++#define MII_ADDR (0x114) ++#define MII_WRITE_ (0x02) ++#define MII_BUSY_ (0x01) ++#define MII_READ_ (0x00) /* ~of MII Write bit */ ++ ++#define MII_DATA (0x118) ++ ++#define FLOW (0x11C) ++#define FLOW_FCPT_ (0xFFFF0000) ++#define FLOW_FCPASS_ (0x00000004) ++#define FLOW_FCEN_ (0x00000002) ++#define FLOW_FCBSY_ (0x00000001) ++ ++#define VLAN1 (0x120) ++ ++#define VLAN2 (0x124) ++ ++#define WUFF (0x128) ++#define LAN9500_WUFF_NUM (4) ++#define LAN9500A_WUFF_NUM (8) ++ ++#define WUCSR (0x12C) ++#define WUCSR_WFF_PTR_RST_ (0x80000000) ++#define WUCSR_GUE_ (0x00000200) ++#define WUCSR_WUFR_ (0x00000040) ++#define WUCSR_MPR_ (0x00000020) ++#define WUCSR_WAKE_EN_ (0x00000004) ++#define WUCSR_MPEN_ (0x00000002) ++ ++#define COE_CR (0x130) ++#define Tx_COE_EN_ (0x00010000) ++#define Rx_COE_MODE_ (0x00000002) ++#define Rx_COE_EN_ (0x00000001) ++ ++/* Vendor-specific PHY Definitions */ ++ ++/* EDPD NLP / crossover time configuration (LAN9500A only) */ ++#define PHY_EDPD_CONFIG (16) ++#define PHY_EDPD_CONFIG_TX_NLP_EN_ ((u16)0x8000) ++#define PHY_EDPD_CONFIG_TX_NLP_1000_ ((u16)0x0000) ++#define PHY_EDPD_CONFIG_TX_NLP_768_ ((u16)0x2000) ++#define PHY_EDPD_CONFIG_TX_NLP_512_ ((u16)0x4000) ++#define PHY_EDPD_CONFIG_TX_NLP_256_ ((u16)0x6000) ++#define PHY_EDPD_CONFIG_RX_1_NLP_ ((u16)0x1000) ++#define PHY_EDPD_CONFIG_RX_NLP_64_ ((u16)0x0000) ++#define PHY_EDPD_CONFIG_RX_NLP_256_ ((u16)0x0400) ++#define PHY_EDPD_CONFIG_RX_NLP_512_ ((u16)0x0800) ++#define PHY_EDPD_CONFIG_RX_NLP_1000_ ((u16)0x0C00) ++#define PHY_EDPD_CONFIG_EXT_CROSSOVER_ ((u16)0x0001) ++#define PHY_EDPD_CONFIG_DEFAULT (PHY_EDPD_CONFIG_TX_NLP_EN_ | \ ++ PHY_EDPD_CONFIG_TX_NLP_768_ | \ ++ PHY_EDPD_CONFIG_RX_1_NLP_) ++ ++/* Mode Control/Status Register */ ++#define PHY_MODE_CTRL_STS (17) ++#define MODE_CTRL_STS_EDPWRDOWN_ ((u16)0x2000) ++#define MODE_CTRL_STS_ENERGYON_ ((u16)0x0002) ++ ++#define SPECIAL_CTRL_STS (27) ++#define SPECIAL_CTRL_STS_OVRRD_AMDIX_ ((u16)0x8000) ++#define SPECIAL_CTRL_STS_AMDIX_ENABLE_ ((u16)0x4000) ++#define SPECIAL_CTRL_STS_AMDIX_STATE_ ((u16)0x2000) ++ ++#define PHY_INT_SRC (29) ++#define PHY_INT_SRC_ENERGY_ON_ ((u16)0x0080) ++#define PHY_INT_SRC_ANEG_COMP_ ((u16)0x0040) ++#define PHY_INT_SRC_REMOTE_FAULT_ ((u16)0x0020) ++#define PHY_INT_SRC_LINK_DOWN_ ((u16)0x0010) ++ ++#define PHY_INT_MASK (30) ++#define PHY_INT_MASK_ENERGY_ON_ ((u16)0x0080) ++#define PHY_INT_MASK_ANEG_COMP_ ((u16)0x0040) ++#define PHY_INT_MASK_REMOTE_FAULT_ ((u16)0x0020) ++#define PHY_INT_MASK_LINK_DOWN_ ((u16)0x0010) ++#define PHY_INT_MASK_DEFAULT_ (PHY_INT_MASK_ANEG_COMP_ | \ ++ PHY_INT_MASK_LINK_DOWN_) ++ ++#define PHY_SPECIAL (31) ++#define PHY_SPECIAL_SPD_ ((u16)0x001C) ++#define PHY_SPECIAL_SPD_10HALF_ ((u16)0x0004) ++#define PHY_SPECIAL_SPD_10FULL_ ((u16)0x0014) ++#define PHY_SPECIAL_SPD_100HALF_ ((u16)0x0008) ++#define PHY_SPECIAL_SPD_100FULL_ ((u16)0x0018) ++ ++/* USB Vendor Requests */ ++#define USB_VENDOR_REQUEST_WRITE_REGISTER 0xA0 ++#define USB_VENDOR_REQUEST_READ_REGISTER 0xA1 ++#define USB_VENDOR_REQUEST_GET_STATS 0xA2 ++ ++/* Interrupt Endpoint status word bitfields */ ++#define INT_ENP_TX_STOP_ ((u32)BIT(17)) ++#define INT_ENP_RX_STOP_ ((u32)BIT(16)) ++#define INT_ENP_PHY_INT_ ((u32)BIT(15)) ++#define INT_ENP_TXE_ ((u32)BIT(14)) ++#define INT_ENP_TDFU_ ((u32)BIT(13)) ++#define INT_ENP_TDFO_ ((u32)BIT(12)) ++#define INT_ENP_RXDF_ ((u32)BIT(11)) ++ ++#endif /* _SMSC95XX_H */ +diff -Naur backports-3.18.1-1.org/drivers/net/usb/sr9700.c backports-3.18.1-1/drivers/net/usb/sr9700.c +--- backports-3.18.1-1.org/drivers/net/usb/sr9700.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/sr9700.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,559 @@ ++/* ++ * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices ++ * ++ * Author : Liu Junliang liujunliang_ljl@163.com ++ * ++ * Based on dm9601.c ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#include <linux/module.h> ++#include <linux/sched.h> ++#include <linux/stddef.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/crc32.h> ++#include <linux/usb/usbnet.h> ++ ++#include "sr9700.h" ++ ++static int sr_read(struct usbnet *dev, u8 reg, u16 length, void *data) ++{ ++ int err; ++ ++ err = usbnet_read_cmd(dev, SR_RD_REGS, SR_REQ_RD_REG, 0, reg, data, ++ length); ++ if ((err != length) && (err >= 0)) ++ err = -EINVAL; ++ return err; ++} ++ ++static int sr_write(struct usbnet *dev, u8 reg, u16 length, void *data) ++{ ++ int err; ++ ++ err = usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG, 0, reg, data, ++ length); ++ if ((err >= 0) && (err < length)) ++ err = -EINVAL; ++ return err; ++} ++ ++static int sr_read_reg(struct usbnet *dev, u8 reg, u8 *value) ++{ ++ return sr_read(dev, reg, 1, value); ++} ++ ++static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value) ++{ ++ return usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG, ++ value, reg, NULL, 0); ++} ++ ++static void sr_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) ++{ ++ usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG, ++ 0, reg, data, length); ++} ++ ++static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value) ++{ ++ usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG, ++ value, reg, NULL, 0); ++} ++ ++static int wait_phy_eeprom_ready(struct usbnet *dev, int phy) ++{ ++ int i; ++ ++ for (i = 0; i < SR_SHARE_TIMEOUT; i++) { ++ u8 tmp = 0; ++ int ret; ++ ++ udelay(1); ++ ret = sr_read_reg(dev, EPCR, &tmp); ++ if (ret < 0) ++ return ret; ++ ++ /* ready */ ++ if (!(tmp & EPCR_ERRE)) ++ return 0; ++ } ++ ++ netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom"); ++ ++ return -EIO; ++} ++ ++static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg, ++ __le16 *value) ++{ ++ int ret; ++ ++ mutex_lock(&dev->phy_mutex); ++ ++ sr_write_reg(dev, EPAR, phy ? (reg | EPAR_PHY_ADR) : reg); ++ sr_write_reg(dev, EPCR, phy ? (EPCR_EPOS | EPCR_ERPRR) : EPCR_ERPRR); ++ ++ ret = wait_phy_eeprom_ready(dev, phy); ++ if (ret < 0) ++ goto out_unlock; ++ ++ sr_write_reg(dev, EPCR, 0x0); ++ ret = sr_read(dev, EPDR, 2, value); ++ ++ netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n", ++ phy, reg, *value, ret); ++ ++out_unlock: ++ mutex_unlock(&dev->phy_mutex); ++ return ret; ++} ++ ++static int sr_share_write_word(struct usbnet *dev, int phy, u8 reg, ++ __le16 value) ++{ ++ int ret; ++ ++ mutex_lock(&dev->phy_mutex); ++ ++ ret = sr_write(dev, EPDR, 2, &value); ++ if (ret < 0) ++ goto out_unlock; ++ ++ sr_write_reg(dev, EPAR, phy ? (reg | EPAR_PHY_ADR) : reg); ++ sr_write_reg(dev, EPCR, phy ? (EPCR_WEP | EPCR_EPOS | EPCR_ERPRW) : ++ (EPCR_WEP | EPCR_ERPRW)); ++ ++ ret = wait_phy_eeprom_ready(dev, phy); ++ if (ret < 0) ++ goto out_unlock; ++ ++ sr_write_reg(dev, EPCR, 0x0); ++ ++out_unlock: ++ mutex_unlock(&dev->phy_mutex); ++ return ret; ++} ++ ++static int sr_read_eeprom_word(struct usbnet *dev, u8 offset, void *value) ++{ ++ return sr_share_read_word(dev, 0, offset, value); ++} ++ ++static int sr9700_get_eeprom_len(struct net_device *netdev) ++{ ++ return SR_EEPROM_LEN; ++} ++ ++static int sr9700_get_eeprom(struct net_device *netdev, ++ struct ethtool_eeprom *eeprom, u8 *data) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ __le16 *buf = (__le16 *)data; ++ int ret = 0; ++ int i; ++ ++ /* access is 16bit */ ++ if ((eeprom->offset & 0x01) || (eeprom->len & 0x01)) ++ return -EINVAL; ++ ++ for (i = 0; i < eeprom->len / 2; i++) { ++ ret = sr_read_eeprom_word(dev, eeprom->offset / 2 + i, buf + i); ++ if (ret < 0) ++ break; ++ } ++ ++ return ret; ++} ++ ++static int sr_mdio_read(struct net_device *netdev, int phy_id, int loc) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ __le16 res; ++ int rc = 0; ++ ++ if (phy_id) { ++ netdev_dbg(netdev, "Only internal phy supported\n"); ++ return 0; ++ } ++ ++ /* Access NSR_LINKST bit for link status instead of MII_BMSR */ ++ if (loc == MII_BMSR) { ++ u8 value; ++ ++ sr_read_reg(dev, NSR, &value); ++ if (value & NSR_LINKST) ++ rc = 1; ++ } ++ sr_share_read_word(dev, 1, loc, &res); ++ if (rc == 1) ++ res = le16_to_cpu(res) | BMSR_LSTATUS; ++ else ++ res = le16_to_cpu(res) & ~BMSR_LSTATUS; ++ ++ netdev_dbg(netdev, "sr_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", ++ phy_id, loc, res); ++ ++ return res; ++} ++ ++static void sr_mdio_write(struct net_device *netdev, int phy_id, int loc, ++ int val) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ __le16 res = cpu_to_le16(val); ++ ++ if (phy_id) { ++ netdev_dbg(netdev, "Only internal phy supported\n"); ++ return; ++ } ++ ++ netdev_dbg(netdev, "sr_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", ++ phy_id, loc, val); ++ ++ sr_share_write_word(dev, 1, loc, res); ++} ++ ++static u32 sr9700_get_link(struct net_device *netdev) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ u8 value = 0; ++ int rc = 0; ++ ++ /* Get the Link Status directly */ ++ sr_read_reg(dev, NSR, &value); ++ if (value & NSR_LINKST) ++ rc = 1; ++ ++ return rc; ++} ++ ++static int sr9700_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ ++ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); ++} ++ ++static const struct ethtool_ops sr9700_ethtool_ops = { ++ .get_drvinfo = usbnet_get_drvinfo, ++ .get_link = sr9700_get_link, ++ .get_msglevel = usbnet_get_msglevel, ++ .set_msglevel = usbnet_set_msglevel, ++ .get_eeprom_len = sr9700_get_eeprom_len, ++ .get_eeprom = sr9700_get_eeprom, ++ .get_settings = usbnet_get_settings, ++ .set_settings = usbnet_set_settings, ++ .nway_reset = usbnet_nway_reset, ++}; ++ ++static void sr9700_set_multicast(struct net_device *netdev) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ /* We use the 20 byte dev->data for our 8 byte filter buffer ++ * to avoid allocating memory that is tricky to free later ++ */ ++ u8 *hashes = (u8 *)&dev->data; ++ /* rx_ctl setting : enable, disable_long, disable_crc */ ++ u8 rx_ctl = RCR_RXEN | RCR_DIS_CRC | RCR_DIS_LONG; ++ ++ memset(hashes, 0x00, SR_MCAST_SIZE); ++ /* broadcast address */ ++ hashes[SR_MCAST_SIZE - 1] |= SR_MCAST_ADDR_FLAG; ++ if (netdev->flags & IFF_PROMISC) { ++ rx_ctl |= RCR_PRMSC; ++ } else if (netdev->flags & IFF_ALLMULTI || ++ netdev_mc_count(netdev) > SR_MCAST_MAX) { ++ rx_ctl |= RCR_RUNT; ++ } else if (!netdev_mc_empty(netdev)) { ++ struct netdev_hw_addr *ha; ++ ++ netdev_for_each_mc_addr(ha, netdev) { ++ u32 crc = ether_crc(ETH_ALEN, ha->addr) >> 26; ++ hashes[crc >> 3] |= 1 << (crc & 0x7); ++ } ++ } ++ ++ sr_write_async(dev, MAR, SR_MCAST_SIZE, hashes); ++ sr_write_reg_async(dev, RCR, rx_ctl); ++} ++ ++static int sr9700_set_mac_address(struct net_device *netdev, void *p) ++{ ++ struct usbnet *dev = netdev_priv(netdev); ++ struct sockaddr *addr = p; ++ ++ if (!is_valid_ether_addr(addr->sa_data)) { ++ netdev_err(netdev, "not setting invalid mac address %pM\n", ++ addr->sa_data); ++ return -EINVAL; ++ } ++ ++ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); ++ sr_write_async(dev, PAR, 6, netdev->dev_addr); ++ ++ return 0; ++} ++ ++static const struct net_device_ops sr9700_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = usbnet_change_mtu, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = sr9700_ioctl, ++ .ndo_set_rx_mode = sr9700_set_multicast, ++ .ndo_set_mac_address = sr9700_set_mac_address, ++}; ++ ++static int sr9700_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ struct net_device *netdev; ++ struct mii_if_info *mii; ++ int ret; ++ ++ ret = usbnet_get_endpoints(dev, intf); ++ if (ret) ++ goto out; ++ ++ netdev = dev->net; ++ ++ netdev->netdev_ops = &sr9700_netdev_ops; ++ netdev->ethtool_ops = &sr9700_ethtool_ops; ++ netdev->hard_header_len += SR_TX_OVERHEAD; ++ dev->hard_mtu = netdev->mtu + netdev->hard_header_len; ++ /* bulkin buffer is preferably not less than 3K */ ++ dev->rx_urb_size = 3072; ++ ++ mii = &dev->mii; ++ mii->dev = netdev; ++ mii->mdio_read = sr_mdio_read; ++ mii->mdio_write = sr_mdio_write; ++ mii->phy_id_mask = 0x1f; ++ mii->reg_num_mask = 0x1f; ++ ++ sr_write_reg(dev, NCR, NCR_RST); ++ udelay(20); ++ ++ /* read MAC ++ * After Chip Power on, the Chip will reload the MAC from ++ * EEPROM automatically to PAR. In case there is no EEPROM externally, ++ * a default MAC address is stored in PAR for making chip work properly. ++ */ ++ if (sr_read(dev, PAR, ETH_ALEN, netdev->dev_addr) < 0) { ++ netdev_err(netdev, "Error reading MAC address\n"); ++ ret = -ENODEV; ++ goto out; ++ } ++ ++ /* power up and reset phy */ ++ sr_write_reg(dev, PRR, PRR_PHY_RST); ++ /* at least 10ms, here 20ms for safe */ ++ mdelay(20); ++ sr_write_reg(dev, PRR, 0); ++ /* at least 1ms, here 2ms for reading right register */ ++ udelay(2 * 1000); ++ ++ /* receive broadcast packets */ ++ sr9700_set_multicast(netdev); ++ ++ sr_mdio_write(netdev, mii->phy_id, MII_BMCR, BMCR_RESET); ++ sr_mdio_write(netdev, mii->phy_id, MII_ADVERTISE, ADVERTISE_ALL | ++ ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); ++ mii_nway_restart(mii); ++ ++out: ++ return ret; ++} ++ ++static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ struct sk_buff *sr_skb; ++ int len; ++ ++ /* skb content (packets) format : ++ * p0 p1 p2 ...... pm ++ * / \ ++ * / \ ++ * / \ ++ * / \ ++ * p0b0 p0b1 p0b2 p0b3 ...... p0b(n-4) p0b(n-3)...p0bn ++ * ++ * p0 : packet 0 ++ * p0b0 : packet 0 byte 0 ++ * ++ * b0: rx status ++ * b1: packet length (incl crc) low ++ * b2: packet length (incl crc) high ++ * b3..n-4: packet data ++ * bn-3..bn: ethernet packet crc ++ */ ++ if (unlikely(skb->len < SR_RX_OVERHEAD)) { ++ netdev_err(dev->net, "unexpected tiny rx frame\n"); ++ return 0; ++ } ++ ++ /* one skb may contains multiple packets */ ++ while (skb->len > SR_RX_OVERHEAD) { ++ if (skb->data[0] != 0x40) ++ return 0; ++ ++ /* ignore the CRC length */ ++ len = (skb->data[1] | (skb->data[2] << 8)) - 4; ++ ++ if (len > ETH_FRAME_LEN) ++ return 0; ++ ++ /* the last packet of current skb */ ++ if (skb->len == (len + SR_RX_OVERHEAD)) { ++ skb_pull(skb, 3); ++ skb->len = len; ++ skb_set_tail_pointer(skb, len); ++ skb->truesize = len + sizeof(struct sk_buff); ++ return 2; ++ } ++ ++ /* skb_clone is used for address align */ ++ sr_skb = skb_clone(skb, GFP_ATOMIC); ++ if (!sr_skb) ++ return 0; ++ ++ sr_skb->len = len; ++ sr_skb->data = skb->data + 3; ++ skb_set_tail_pointer(sr_skb, len); ++ sr_skb->truesize = len + sizeof(struct sk_buff); ++ usbnet_skb_return(dev, sr_skb); ++ ++ skb_pull(skb, len + SR_RX_OVERHEAD); ++ }; ++ ++ return 0; ++} ++ ++static struct sk_buff *sr9700_tx_fixup(struct usbnet *dev, struct sk_buff *skb, ++ gfp_t flags) ++{ ++ int len; ++ ++ /* SR9700 can only send out one ethernet packet at once. ++ * ++ * b0 b1 b2 b3 ...... b(n-4) b(n-3)...bn ++ * ++ * b0: rx status ++ * b1: packet length (incl crc) low ++ * b2: packet length (incl crc) high ++ * b3..n-4: packet data ++ * bn-3..bn: ethernet packet crc ++ */ ++ ++ len = skb->len; ++ ++ if (skb_headroom(skb) < SR_TX_OVERHEAD) { ++ struct sk_buff *skb2; ++ ++ skb2 = skb_copy_expand(skb, SR_TX_OVERHEAD, 0, flags); ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ if (!skb) ++ return NULL; ++ } ++ ++ __skb_push(skb, SR_TX_OVERHEAD); ++ ++ /* usbnet adds padding if length is a multiple of packet size ++ * if so, adjust length value in header ++ */ ++ if ((skb->len % dev->maxpacket) == 0) ++ len++; ++ ++ skb->data[0] = len; ++ skb->data[1] = len >> 8; ++ ++ return skb; ++} ++ ++static void sr9700_status(struct usbnet *dev, struct urb *urb) ++{ ++ int link; ++ u8 *buf; ++ ++ /* format: ++ b0: net status ++ b1: tx status 1 ++ b2: tx status 2 ++ b3: rx status ++ b4: rx overflow ++ b5: rx count ++ b6: tx count ++ b7: gpr ++ */ ++ ++ if (urb->actual_length < 8) ++ return; ++ ++ buf = urb->transfer_buffer; ++ ++ link = !!(buf[0] & 0x40); ++ if (netif_carrier_ok(dev->net) != link) { ++ usbnet_link_change(dev, link, 1); ++ netdev_dbg(dev->net, "Link Status is: %d\n", link); ++ } ++} ++ ++static int sr9700_link_reset(struct usbnet *dev) ++{ ++ struct ethtool_cmd ecmd; ++ ++ mii_check_media(&dev->mii, 1, 1); ++ mii_ethtool_gset(&dev->mii, &ecmd); ++ ++ netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n", ++ ecmd.speed, ecmd.duplex); ++ ++ return 0; ++} ++ ++static const struct driver_info sr9700_driver_info = { ++ .description = "CoreChip SR9700 USB Ethernet", ++ .flags = FLAG_ETHER, ++ .bind = sr9700_bind, ++ .rx_fixup = sr9700_rx_fixup, ++ .tx_fixup = sr9700_tx_fixup, ++ .status = sr9700_status, ++ .link_reset = sr9700_link_reset, ++ .reset = sr9700_link_reset, ++}; ++ ++static const struct usb_device_id products[] = { ++ { ++ USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */ ++ .driver_info = (unsigned long)&sr9700_driver_info, ++ }, ++ {}, /* END */ ++}; ++ ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver sr9700_usb_driver = { ++ .name = "sr9700", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(sr9700_usb_driver); ++ ++MODULE_AUTHOR("liujl liujunliang_ljl@163.com"); ++MODULE_DESCRIPTION("SR9700 one chip USB 1.1 USB to Ethernet device from http://www.corechip-sz.com/"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/sr9700.h backports-3.18.1-1/drivers/net/usb/sr9700.h +--- backports-3.18.1-1.org/drivers/net/usb/sr9700.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/sr9700.h 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,173 @@ ++/* ++ * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices ++ * ++ * Author : Liu Junliang liujunliang_ljl@163.com ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ */ ++ ++#ifndef _SR9700_H ++#define _SR9700_H ++ ++/* sr9700 spec. register table on Linux platform */ ++ ++/* Network Control Reg */ ++#define NCR 0x00 ++#define NCR_RST (1 << 0) ++#define NCR_LBK (3 << 1) ++#define NCR_FDX (1 << 3) ++#define NCR_WAKEEN (1 << 6) ++/* Network Status Reg */ ++#define NSR 0x01 ++#define NSR_RXRDY (1 << 0) ++#define NSR_RXOV (1 << 1) ++#define NSR_TX1END (1 << 2) ++#define NSR_TX2END (1 << 3) ++#define NSR_TXFULL (1 << 4) ++#define NSR_WAKEST (1 << 5) ++#define NSR_LINKST (1 << 6) ++#define NSR_SPEED (1 << 7) ++/* Tx Control Reg */ ++#define TCR 0x02 ++#define TCR_CRC_DIS (1 << 1) ++#define TCR_PAD_DIS (1 << 2) ++#define TCR_LC_CARE (1 << 3) ++#define TCR_CRS_CARE (1 << 4) ++#define TCR_EXCECM (1 << 5) ++#define TCR_LF_EN (1 << 6) ++/* Tx Status Reg for Packet Index 1 */ ++#define TSR1 0x03 ++#define TSR1_EC (1 << 2) ++#define TSR1_COL (1 << 3) ++#define TSR1_LC (1 << 4) ++#define TSR1_NC (1 << 5) ++#define TSR1_LOC (1 << 6) ++#define TSR1_TLF (1 << 7) ++/* Tx Status Reg for Packet Index 2 */ ++#define TSR2 0x04 ++#define TSR2_EC (1 << 2) ++#define TSR2_COL (1 << 3) ++#define TSR2_LC (1 << 4) ++#define TSR2_NC (1 << 5) ++#define TSR2_LOC (1 << 6) ++#define TSR2_TLF (1 << 7) ++/* Rx Control Reg*/ ++#define RCR 0x05 ++#define RCR_RXEN (1 << 0) ++#define RCR_PRMSC (1 << 1) ++#define RCR_RUNT (1 << 2) ++#define RCR_ALL (1 << 3) ++#define RCR_DIS_CRC (1 << 4) ++#define RCR_DIS_LONG (1 << 5) ++/* Rx Status Reg */ ++#define RSR 0x06 ++#define RSR_AE (1 << 2) ++#define RSR_MF (1 << 6) ++#define RSR_RF (1 << 7) ++/* Rx Overflow Counter Reg */ ++#define ROCR 0x07 ++#define ROCR_ROC (0x7F << 0) ++#define ROCR_RXFU (1 << 7) ++/* Back Pressure Threshold Reg */ ++#define BPTR 0x08 ++#define BPTR_JPT (0x0F << 0) ++#define BPTR_BPHW (0x0F << 4) ++/* Flow Control Threshold Reg */ ++#define FCTR 0x09 ++#define FCTR_LWOT (0x0F << 0) ++#define FCTR_HWOT (0x0F << 4) ++/* rx/tx Flow Control Reg */ ++#define FCR 0x0A ++#define FCR_FLCE (1 << 0) ++#define FCR_BKPA (1 << 4) ++#define FCR_TXPEN (1 << 5) ++#define FCR_TXPF (1 << 6) ++#define FCR_TXP0 (1 << 7) ++/* Eeprom & Phy Control Reg */ ++#define EPCR 0x0B ++#define EPCR_ERRE (1 << 0) ++#define EPCR_ERPRW (1 << 1) ++#define EPCR_ERPRR (1 << 2) ++#define EPCR_EPOS (1 << 3) ++#define EPCR_WEP (1 << 4) ++/* Eeprom & Phy Address Reg */ ++#define EPAR 0x0C ++#define EPAR_EROA (0x3F << 0) ++#define EPAR_PHY_ADR_MASK (0x03 << 6) ++#define EPAR_PHY_ADR (0x01 << 6) ++/* Eeprom & Phy Data Reg */ ++#define EPDR 0x0D /* 0x0D ~ 0x0E for Data Reg Low & High */ ++/* Wakeup Control Reg */ ++#define WCR 0x0F ++#define WCR_MAGICST (1 << 0) ++#define WCR_LINKST (1 << 2) ++#define WCR_MAGICEN (1 << 3) ++#define WCR_LINKEN (1 << 5) ++/* Physical Address Reg */ ++#define PAR 0x10 /* 0x10 ~ 0x15 6 bytes for PAR */ ++/* Multicast Address Reg */ ++#define MAR 0x16 /* 0x16 ~ 0x1D 8 bytes for MAR */ ++/* 0x1e unused */ ++/* Phy Reset Reg */ ++#define PRR 0x1F ++#define PRR_PHY_RST (1 << 0) ++/* Tx sdram Write Pointer Address Low */ ++#define TWPAL 0x20 ++/* Tx sdram Write Pointer Address High */ ++#define TWPAH 0x21 ++/* Tx sdram Read Pointer Address Low */ ++#define TRPAL 0x22 ++/* Tx sdram Read Pointer Address High */ ++#define TRPAH 0x23 ++/* Rx sdram Write Pointer Address Low */ ++#define RWPAL 0x24 ++/* Rx sdram Write Pointer Address High */ ++#define RWPAH 0x25 ++/* Rx sdram Read Pointer Address Low */ ++#define RRPAL 0x26 ++/* Rx sdram Read Pointer Address High */ ++#define RRPAH 0x27 ++/* Vendor ID register */ ++#define VID 0x28 /* 0x28 ~ 0x29 2 bytes for VID */ ++/* Product ID register */ ++#define PID 0x2A /* 0x2A ~ 0x2B 2 bytes for PID */ ++/* CHIP Revision register */ ++#define CHIPR 0x2C ++/* 0x2D --> 0xEF unused */ ++/* USB Device Address */ ++#define USBDA 0xF0 ++#define USBDA_USBFA (0x7F << 0) ++/* RX packet Counter Reg */ ++#define RXC 0xF1 ++/* Tx packet Counter & USB Status Reg */ ++#define TXC_USBS 0xF2 ++#define TXC_USBS_TXC0 (1 << 0) ++#define TXC_USBS_TXC1 (1 << 1) ++#define TXC_USBS_TXC2 (1 << 2) ++#define TXC_USBS_EP1RDY (1 << 5) ++#define TXC_USBS_SUSFLAG (1 << 6) ++#define TXC_USBS_RXFAULT (1 << 7) ++/* USB Control register */ ++#define USBC 0xF4 ++#define USBC_EP3NAK (1 << 4) ++#define USBC_EP3ACK (1 << 5) ++ ++/* Register access commands and flags */ ++#define SR_RD_REGS 0x00 ++#define SR_WR_REGS 0x01 ++#define SR_WR_REG 0x03 ++#define SR_REQ_RD_REG (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) ++#define SR_REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) ++ ++/* parameters */ ++#define SR_SHARE_TIMEOUT 1000 ++#define SR_EEPROM_LEN 256 ++#define SR_MCAST_SIZE 8 ++#define SR_MCAST_ADDR_FLAG 0x80 ++#define SR_MCAST_MAX 64 ++#define SR_TX_OVERHEAD 2 /* 2bytes header */ ++#define SR_RX_OVERHEAD 7 /* 3bytes header + 4crc tail */ ++ ++#endif /* _SR9700_H */ +diff -Naur backports-3.18.1-1.org/drivers/net/usb/sr9800.c backports-3.18.1-1/drivers/net/usb/sr9800.c +--- backports-3.18.1-1.org/drivers/net/usb/sr9800.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/sr9800.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,874 @@ ++/* CoreChip-sz SR9800 one chip USB 2.0 Ethernet Devices ++ * ++ * Author : Liu Junliang liujunliang_ljl@163.com ++ * ++ * Based on asix_common.c, asix_devices.c ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied.* ++ */ ++ ++#include <linux/module.h> ++#include <linux/kmod.h> ++#include <linux/init.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/usb.h> ++#include <linux/crc32.h> ++#include <linux/usb/usbnet.h> ++#include <linux/slab.h> ++#include <linux/if_vlan.h> ++ ++#include "sr9800.h" ++ ++static int sr_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data) ++{ ++ int err; ++ ++ err = usbnet_read_cmd(dev, cmd, SR_REQ_RD_REG, value, index, ++ data, size); ++ if ((err != size) && (err >= 0)) ++ err = -EINVAL; ++ ++ return err; ++} ++ ++static int sr_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data) ++{ ++ int err; ++ ++ err = usbnet_write_cmd(dev, cmd, SR_REQ_WR_REG, value, index, ++ data, size); ++ if ((err != size) && (err >= 0)) ++ err = -EINVAL; ++ ++ return err; ++} ++ ++static void ++sr_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, ++ u16 size, void *data) ++{ ++ usbnet_write_cmd_async(dev, cmd, SR_REQ_WR_REG, value, index, data, ++ size); ++} ++ ++static int sr_rx_fixup(struct usbnet *dev, struct sk_buff *skb) ++{ ++ int offset = 0; ++ ++ /* This check is no longer done by usbnet */ ++ if (skb->len < dev->net->hard_header_len) ++ return 0; ++ ++ while (offset + sizeof(u32) < skb->len) { ++ struct sk_buff *sr_skb; ++ u16 size; ++ u32 header = get_unaligned_le32(skb->data + offset); ++ ++ offset += sizeof(u32); ++ /* get the packet length */ ++ size = (u16) (header & 0x7ff); ++ if (size != ((~header >> 16) & 0x07ff)) { ++ netdev_err(dev->net, "%s : Bad Header Length\n", ++ __func__); ++ return 0; ++ } ++ ++ if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) || ++ (size + offset > skb->len)) { ++ netdev_err(dev->net, "%s : Bad RX Length %d\n", ++ __func__, size); ++ return 0; ++ } ++ sr_skb = netdev_alloc_skb_ip_align(dev->net, size); ++ if (!sr_skb) ++ return 0; ++ ++ skb_put(sr_skb, size); ++ memcpy(sr_skb->data, skb->data + offset, size); ++ usbnet_skb_return(dev, sr_skb); ++ ++ offset += (size + 1) & 0xfffe; ++ } ++ ++ if (skb->len != offset) { ++ netdev_err(dev->net, "%s : Bad SKB Length %d\n", __func__, ++ skb->len); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct sk_buff *sr_tx_fixup(struct usbnet *dev, struct sk_buff *skb, ++ gfp_t flags) ++{ ++ int headroom = skb_headroom(skb); ++ int tailroom = skb_tailroom(skb); ++ u32 padbytes = 0xffff0000; ++ u32 packet_len; ++ int padlen; ++ ++ padlen = ((skb->len + 4) % (dev->maxpacket - 1)) ? 0 : 4; ++ ++ if ((!skb_cloned(skb)) && ((headroom + tailroom) >= (4 + padlen))) { ++ if ((headroom < 4) || (tailroom < padlen)) { ++ skb->data = memmove(skb->head + 4, skb->data, ++ skb->len); ++ skb_set_tail_pointer(skb, skb->len); ++ } ++ } else { ++ struct sk_buff *skb2; ++ skb2 = skb_copy_expand(skb, 4, padlen, flags); ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ if (!skb) ++ return NULL; ++ } ++ ++ skb_push(skb, 4); ++ packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4); ++ cpu_to_le32s(&packet_len); ++ skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); ++ ++ if (padlen) { ++ cpu_to_le32s(&padbytes); ++ memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); ++ skb_put(skb, sizeof(padbytes)); ++ } ++ ++ return skb; ++} ++ ++static void sr_status(struct usbnet *dev, struct urb *urb) ++{ ++ struct sr9800_int_data *event; ++ int link; ++ ++ if (urb->actual_length < 8) ++ return; ++ ++ event = urb->transfer_buffer; ++ link = event->link & 0x01; ++ if (netif_carrier_ok(dev->net) != link) { ++ usbnet_link_change(dev, link, 1); ++ netdev_dbg(dev->net, "Link Status is: %d\n", link); ++ } ++ ++ return; ++} ++ ++static inline int sr_set_sw_mii(struct usbnet *dev) ++{ ++ int ret; ++ ++ ret = sr_write_cmd(dev, SR_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, "Failed to enable software MII access\n"); ++ return ret; ++} ++ ++static inline int sr_set_hw_mii(struct usbnet *dev) ++{ ++ int ret; ++ ++ ret = sr_write_cmd(dev, SR_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, "Failed to enable hardware MII access\n"); ++ return ret; ++} ++ ++static inline int sr_get_phy_addr(struct usbnet *dev) ++{ ++ u8 buf[2]; ++ int ret; ++ ++ ret = sr_read_cmd(dev, SR_CMD_READ_PHY_ID, 0, 0, 2, buf); ++ if (ret < 0) { ++ netdev_err(dev->net, "%s : Error reading PHYID register:%02x\n", ++ __func__, ret); ++ goto out; ++ } ++ netdev_dbg(dev->net, "%s : returning 0x%04x\n", __func__, ++ *((__le16 *)buf)); ++ ++ ret = buf[1]; ++ ++out: ++ return ret; ++} ++ ++static int sr_sw_reset(struct usbnet *dev, u8 flags) ++{ ++ int ret; ++ ++ ret = sr_write_cmd(dev, SR_CMD_SW_RESET, flags, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, "Failed to send software reset:%02x\n", ++ ret); ++ ++ return ret; ++} ++ ++static u16 sr_read_rx_ctl(struct usbnet *dev) ++{ ++ __le16 v; ++ int ret; ++ ++ ret = sr_read_cmd(dev, SR_CMD_READ_RX_CTL, 0, 0, 2, &v); ++ if (ret < 0) { ++ netdev_err(dev->net, "Error reading RX_CTL register:%02x\n", ++ ret); ++ goto out; ++ } ++ ++ ret = le16_to_cpu(v); ++out: ++ return ret; ++} ++ ++static int sr_write_rx_ctl(struct usbnet *dev, u16 mode) ++{ ++ int ret; ++ ++ netdev_dbg(dev->net, "%s : mode = 0x%04x\n", __func__, mode); ++ ret = sr_write_cmd(dev, SR_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, ++ "Failed to write RX_CTL mode to 0x%04x:%02x\n", ++ mode, ret); ++ ++ return ret; ++} ++ ++static u16 sr_read_medium_status(struct usbnet *dev) ++{ ++ __le16 v; ++ int ret; ++ ++ ret = sr_read_cmd(dev, SR_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); ++ if (ret < 0) { ++ netdev_err(dev->net, ++ "Error reading Medium Status register:%02x\n", ret); ++ return ret; /* TODO: callers not checking for error ret */ ++ } ++ ++ return le16_to_cpu(v); ++} ++ ++static int sr_write_medium_mode(struct usbnet *dev, u16 mode) ++{ ++ int ret; ++ ++ netdev_dbg(dev->net, "%s : mode = 0x%04x\n", __func__, mode); ++ ret = sr_write_cmd(dev, SR_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, ++ "Failed to write Medium Mode mode to 0x%04x:%02x\n", ++ mode, ret); ++ return ret; ++} ++ ++static int sr_write_gpio(struct usbnet *dev, u16 value, int sleep) ++{ ++ int ret; ++ ++ netdev_dbg(dev->net, "%s : value = 0x%04x\n", __func__, value); ++ ret = sr_write_cmd(dev, SR_CMD_WRITE_GPIOS, value, 0, 0, NULL); ++ if (ret < 0) ++ netdev_err(dev->net, "Failed to write GPIO value 0x%04x:%02x\n", ++ value, ret); ++ if (sleep) ++ msleep(sleep); ++ ++ return ret; ++} ++ ++/* SR9800 have a 16-bit RX_CTL value */ ++static void sr_set_multicast(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct sr_data *data = (struct sr_data *)&dev->data; ++ u16 rx_ctl = SR_DEFAULT_RX_CTL; ++ ++ if (net->flags & IFF_PROMISC) { ++ rx_ctl |= SR_RX_CTL_PRO; ++ } else if (net->flags & IFF_ALLMULTI || ++ netdev_mc_count(net) > SR_MAX_MCAST) { ++ rx_ctl |= SR_RX_CTL_AMALL; ++ } else if (netdev_mc_empty(net)) { ++ /* just broadcast and directed */ ++ } else { ++ /* We use the 20 byte dev->data ++ * for our 8 byte filter buffer ++ * to avoid allocating memory that ++ * is tricky to free later ++ */ ++ struct netdev_hw_addr *ha; ++ u32 crc_bits; ++ ++ memset(data->multi_filter, 0, SR_MCAST_FILTER_SIZE); ++ ++ /* Build the multicast hash filter. */ ++ netdev_for_each_mc_addr(ha, net) { ++ crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; ++ data->multi_filter[crc_bits >> 3] |= ++ 1 << (crc_bits & 7); ++ } ++ ++ sr_write_cmd_async(dev, SR_CMD_WRITE_MULTI_FILTER, 0, 0, ++ SR_MCAST_FILTER_SIZE, data->multi_filter); ++ ++ rx_ctl |= SR_RX_CTL_AM; ++ } ++ ++ sr_write_cmd_async(dev, SR_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); ++} ++ ++static int sr_mdio_read(struct net_device *net, int phy_id, int loc) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ __le16 res; ++ ++ mutex_lock(&dev->phy_mutex); ++ sr_set_sw_mii(dev); ++ sr_read_cmd(dev, SR_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, &res); ++ sr_set_hw_mii(dev); ++ mutex_unlock(&dev->phy_mutex); ++ ++ netdev_dbg(dev->net, ++ "%s : phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", __func__, ++ phy_id, loc, le16_to_cpu(res)); ++ ++ return le16_to_cpu(res); ++} ++ ++static void ++sr_mdio_write(struct net_device *net, int phy_id, int loc, int val) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ __le16 res = cpu_to_le16(val); ++ ++ netdev_dbg(dev->net, ++ "%s : phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", __func__, ++ phy_id, loc, val); ++ mutex_lock(&dev->phy_mutex); ++ sr_set_sw_mii(dev); ++ sr_write_cmd(dev, SR_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); ++ sr_set_hw_mii(dev); ++ mutex_unlock(&dev->phy_mutex); ++} ++ ++/* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ ++static u32 sr_get_phyid(struct usbnet *dev) ++{ ++ int phy_reg; ++ u32 phy_id; ++ int i; ++ ++ /* Poll for the rare case the FW or phy isn't ready yet. */ ++ for (i = 0; i < 100; i++) { ++ phy_reg = sr_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1); ++ if (phy_reg != 0 && phy_reg != 0xFFFF) ++ break; ++ mdelay(1); ++ } ++ ++ if (phy_reg <= 0 || phy_reg == 0xFFFF) ++ return 0; ++ ++ phy_id = (phy_reg & 0xffff) << 16; ++ ++ phy_reg = sr_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID2); ++ if (phy_reg < 0) ++ return 0; ++ ++ phy_id |= (phy_reg & 0xffff); ++ ++ return phy_id; ++} ++ ++static void ++sr_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ u8 opt; ++ ++ if (sr_read_cmd(dev, SR_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { ++ wolinfo->supported = 0; ++ wolinfo->wolopts = 0; ++ return; ++ } ++ wolinfo->supported = WAKE_PHY | WAKE_MAGIC; ++ wolinfo->wolopts = 0; ++ if (opt & SR_MONITOR_LINK) ++ wolinfo->wolopts |= WAKE_PHY; ++ if (opt & SR_MONITOR_MAGIC) ++ wolinfo->wolopts |= WAKE_MAGIC; ++} ++ ++static int ++sr_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ u8 opt = 0; ++ ++ if (wolinfo->wolopts & WAKE_PHY) ++ opt |= SR_MONITOR_LINK; ++ if (wolinfo->wolopts & WAKE_MAGIC) ++ opt |= SR_MONITOR_MAGIC; ++ ++ if (sr_write_cmd(dev, SR_CMD_WRITE_MONITOR_MODE, ++ opt, 0, 0, NULL) < 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int sr_get_eeprom_len(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct sr_data *data = (struct sr_data *)&dev->data; ++ ++ return data->eeprom_len; ++} ++ ++static int sr_get_eeprom(struct net_device *net, ++ struct ethtool_eeprom *eeprom, u8 *data) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ __le16 *ebuf = (__le16 *)data; ++ int ret; ++ int i; ++ ++ /* Crude hack to ensure that we don't overwrite memory ++ * if an odd length is supplied ++ */ ++ if (eeprom->len % 2) ++ return -EINVAL; ++ ++ eeprom->magic = SR_EEPROM_MAGIC; ++ ++ /* sr9800 returns 2 bytes from eeprom on read */ ++ for (i = 0; i < eeprom->len / 2; i++) { ++ ret = sr_read_cmd(dev, SR_CMD_READ_EEPROM, eeprom->offset + i, ++ 0, 2, &ebuf[i]); ++ if (ret < 0) ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static void sr_get_drvinfo(struct net_device *net, ++ struct ethtool_drvinfo *info) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct sr_data *data = (struct sr_data *)&dev->data; ++ ++ /* Inherit standard device info */ ++ usbnet_get_drvinfo(net, info); ++ strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); ++ strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); ++ info->eedump_len = data->eeprom_len; ++} ++ ++static u32 sr_get_link(struct net_device *net) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ return mii_link_ok(&dev->mii); ++} ++ ++static int sr_ioctl(struct net_device *net, struct ifreq *rq, int cmd) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ ++ return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); ++} ++ ++static int sr_set_mac_address(struct net_device *net, void *p) ++{ ++ struct usbnet *dev = netdev_priv(net); ++ struct sr_data *data = (struct sr_data *)&dev->data; ++ struct sockaddr *addr = p; ++ ++ if (netif_running(net)) ++ return -EBUSY; ++ if (!is_valid_ether_addr(addr->sa_data)) ++ return -EADDRNOTAVAIL; ++ ++ memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); ++ ++ /* We use the 20 byte dev->data ++ * for our 6 byte mac buffer ++ * to avoid allocating memory that ++ * is tricky to free later ++ */ ++ memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); ++ sr_write_cmd_async(dev, SR_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, ++ data->mac_addr); ++ ++ return 0; ++} ++ ++static const struct ethtool_ops sr9800_ethtool_ops = { ++ .get_drvinfo = sr_get_drvinfo, ++ .get_link = sr_get_link, ++ .get_msglevel = usbnet_get_msglevel, ++ .set_msglevel = usbnet_set_msglevel, ++ .get_wol = sr_get_wol, ++ .set_wol = sr_set_wol, ++ .get_eeprom_len = sr_get_eeprom_len, ++ .get_eeprom = sr_get_eeprom, ++ .get_settings = usbnet_get_settings, ++ .set_settings = usbnet_set_settings, ++ .nway_reset = usbnet_nway_reset, ++}; ++ ++static int sr9800_link_reset(struct usbnet *dev) ++{ ++ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; ++ u16 mode; ++ ++ mii_check_media(&dev->mii, 1, 1); ++ mii_ethtool_gset(&dev->mii, &ecmd); ++ mode = SR9800_MEDIUM_DEFAULT; ++ ++ if (ethtool_cmd_speed(&ecmd) != SPEED_100) ++ mode &= ~SR_MEDIUM_PS; ++ ++ if (ecmd.duplex != DUPLEX_FULL) ++ mode &= ~SR_MEDIUM_FD; ++ ++ netdev_dbg(dev->net, "%s : speed: %u duplex: %d mode: 0x%04x\n", ++ __func__, ethtool_cmd_speed(&ecmd), ecmd.duplex, mode); ++ ++ sr_write_medium_mode(dev, mode); ++ ++ return 0; ++} ++ ++ ++static int sr9800_set_default_mode(struct usbnet *dev) ++{ ++ u16 rx_ctl; ++ int ret; ++ ++ sr_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); ++ sr_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ++ ADVERTISE_ALL | ADVERTISE_CSMA); ++ mii_nway_restart(&dev->mii); ++ ++ ret = sr_write_medium_mode(dev, SR9800_MEDIUM_DEFAULT); ++ if (ret < 0) ++ goto out; ++ ++ ret = sr_write_cmd(dev, SR_CMD_WRITE_IPG012, ++ SR9800_IPG0_DEFAULT | SR9800_IPG1_DEFAULT, ++ SR9800_IPG2_DEFAULT, 0, NULL); ++ if (ret < 0) { ++ netdev_dbg(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); ++ goto out; ++ } ++ ++ /* Set RX_CTL to default values with 2k buffer, and enable cactus */ ++ ret = sr_write_rx_ctl(dev, SR_DEFAULT_RX_CTL); ++ if (ret < 0) ++ goto out; ++ ++ rx_ctl = sr_read_rx_ctl(dev); ++ netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", ++ rx_ctl); ++ ++ rx_ctl = sr_read_medium_status(dev); ++ netdev_dbg(dev->net, "Medium Status:0x%04x after all initializations\n", ++ rx_ctl); ++ ++ return 0; ++out: ++ return ret; ++} ++ ++static int sr9800_reset(struct usbnet *dev) ++{ ++ struct sr_data *data = (struct sr_data *)&dev->data; ++ int ret, embd_phy; ++ u16 rx_ctl; ++ ++ ret = sr_write_gpio(dev, ++ SR_GPIO_RSE | SR_GPIO_GPO_2 | SR_GPIO_GPO2EN, 5); ++ if (ret < 0) ++ goto out; ++ ++ embd_phy = ((sr_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); ++ ++ ret = sr_write_cmd(dev, SR_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); ++ if (ret < 0) { ++ netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); ++ goto out; ++ } ++ ++ ret = sr_sw_reset(dev, SR_SWRESET_IPPD | SR_SWRESET_PRL); ++ if (ret < 0) ++ goto out; ++ ++ msleep(150); ++ ++ ret = sr_sw_reset(dev, SR_SWRESET_CLEAR); ++ if (ret < 0) ++ goto out; ++ ++ msleep(150); ++ ++ if (embd_phy) { ++ ret = sr_sw_reset(dev, SR_SWRESET_IPRL); ++ if (ret < 0) ++ goto out; ++ } else { ++ ret = sr_sw_reset(dev, SR_SWRESET_PRTE); ++ if (ret < 0) ++ goto out; ++ } ++ ++ msleep(150); ++ rx_ctl = sr_read_rx_ctl(dev); ++ netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); ++ ret = sr_write_rx_ctl(dev, 0x0000); ++ if (ret < 0) ++ goto out; ++ ++ rx_ctl = sr_read_rx_ctl(dev); ++ netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); ++ ++ ret = sr_sw_reset(dev, SR_SWRESET_PRL); ++ if (ret < 0) ++ goto out; ++ ++ msleep(150); ++ ++ ret = sr_sw_reset(dev, SR_SWRESET_IPRL | SR_SWRESET_PRL); ++ if (ret < 0) ++ goto out; ++ ++ msleep(150); ++ ++ ret = sr9800_set_default_mode(dev); ++ if (ret < 0) ++ goto out; ++ ++ /* Rewrite MAC address */ ++ memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); ++ ret = sr_write_cmd(dev, SR_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, ++ data->mac_addr); ++ if (ret < 0) ++ goto out; ++ ++ return 0; ++ ++out: ++ return ret; ++} ++ ++static const struct net_device_ops sr9800_netdev_ops = { ++ .ndo_open = usbnet_open, ++ .ndo_stop = usbnet_stop, ++ .ndo_start_xmit = usbnet_start_xmit, ++ .ndo_tx_timeout = usbnet_tx_timeout, ++ .ndo_change_mtu = usbnet_change_mtu, ++ .ndo_set_mac_address = sr_set_mac_address, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = sr_ioctl, ++ .ndo_set_rx_mode = sr_set_multicast, ++}; ++ ++static int sr9800_phy_powerup(struct usbnet *dev) ++{ ++ int ret; ++ ++ /* set the embedded Ethernet PHY in power-down state */ ++ ret = sr_sw_reset(dev, SR_SWRESET_IPPD | SR_SWRESET_IPRL); ++ if (ret < 0) { ++ netdev_err(dev->net, "Failed to power down PHY : %d\n", ret); ++ return ret; ++ } ++ msleep(20); ++ ++ /* set the embedded Ethernet PHY in power-up state */ ++ ret = sr_sw_reset(dev, SR_SWRESET_IPRL); ++ if (ret < 0) { ++ netdev_err(dev->net, "Failed to reset PHY: %d\n", ret); ++ return ret; ++ } ++ msleep(600); ++ ++ /* set the embedded Ethernet PHY in reset state */ ++ ret = sr_sw_reset(dev, SR_SWRESET_CLEAR); ++ if (ret < 0) { ++ netdev_err(dev->net, "Failed to power up PHY: %d\n", ret); ++ return ret; ++ } ++ msleep(20); ++ ++ /* set the embedded Ethernet PHY in power-up state */ ++ ret = sr_sw_reset(dev, SR_SWRESET_IPRL); ++ if (ret < 0) { ++ netdev_err(dev->net, "Failed to reset PHY: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ struct sr_data *data = (struct sr_data *)&dev->data; ++ u16 led01_mux, led23_mux; ++ int ret, embd_phy; ++ u32 phyid; ++ u16 rx_ctl; ++ ++ data->eeprom_len = SR9800_EEPROM_LEN; ++ ++ usbnet_get_endpoints(dev, intf); ++ ++ /* LED Setting Rule : ++ * AABB:CCDD ++ * AA : MFA0(LED0) ++ * BB : MFA1(LED1) ++ * CC : MFA2(LED2), Reserved for SR9800 ++ * DD : MFA3(LED3), Reserved for SR9800 ++ */ ++ led01_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_LINK; ++ led23_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_TX_ACTIVE; ++ ret = sr_write_cmd(dev, SR_CMD_LED_MUX, led01_mux, led23_mux, 0, NULL); ++ if (ret < 0) { ++ netdev_err(dev->net, "set LINK LED failed : %d\n", ret); ++ goto out; ++ } ++ ++ /* Get the MAC address */ ++ ret = sr_read_cmd(dev, SR_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, ++ dev->net->dev_addr); ++ if (ret < 0) { ++ netdev_dbg(dev->net, "Failed to read MAC address: %d\n", ret); ++ return ret; ++ } ++ netdev_dbg(dev->net, "mac addr : %pM\n", dev->net->dev_addr); ++ ++ /* Initialize MII structure */ ++ dev->mii.dev = dev->net; ++ dev->mii.mdio_read = sr_mdio_read; ++ dev->mii.mdio_write = sr_mdio_write; ++ dev->mii.phy_id_mask = 0x1f; ++ dev->mii.reg_num_mask = 0x1f; ++ dev->mii.phy_id = sr_get_phy_addr(dev); ++ ++ dev->net->netdev_ops = &sr9800_netdev_ops; ++ dev->net->ethtool_ops = &sr9800_ethtool_ops; ++ ++ embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); ++ /* Reset the PHY to normal operation mode */ ++ ret = sr_write_cmd(dev, SR_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); ++ if (ret < 0) { ++ netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); ++ return ret; ++ } ++ ++ /* Init PHY routine */ ++ ret = sr9800_phy_powerup(dev); ++ if (ret < 0) ++ goto out; ++ ++ rx_ctl = sr_read_rx_ctl(dev); ++ netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); ++ ret = sr_write_rx_ctl(dev, 0x0000); ++ if (ret < 0) ++ goto out; ++ ++ rx_ctl = sr_read_rx_ctl(dev); ++ netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); ++ ++ /* Read PHYID register *AFTER* the PHY was reset properly */ ++ phyid = sr_get_phyid(dev); ++ netdev_dbg(dev->net, "PHYID=0x%08x\n", phyid); ++ ++ /* medium mode setting */ ++ ret = sr9800_set_default_mode(dev); ++ if (ret < 0) ++ goto out; ++ ++ if (dev->udev->speed == USB_SPEED_HIGH) { ++ ret = sr_write_cmd(dev, SR_CMD_BULKIN_SIZE, ++ SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].byte_cnt, ++ SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].threshold, ++ 0, NULL); ++ if (ret < 0) { ++ netdev_err(dev->net, "Reset RX_CTL failed: %d\n", ret); ++ goto out; ++ } ++ dev->rx_urb_size = ++ SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].size; ++ } else { ++ ret = sr_write_cmd(dev, SR_CMD_BULKIN_SIZE, ++ SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].byte_cnt, ++ SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].threshold, ++ 0, NULL); ++ if (ret < 0) { ++ netdev_err(dev->net, "Reset RX_CTL failed: %d\n", ret); ++ goto out; ++ } ++ dev->rx_urb_size = ++ SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].size; ++ } ++ netdev_dbg(dev->net, "%s : setting rx_urb_size with : %zu\n", __func__, ++ dev->rx_urb_size); ++ return 0; ++ ++out: ++ return ret; ++} ++ ++static const struct driver_info sr9800_driver_info = { ++ .description = "CoreChip SR9800 USB 2.0 Ethernet", ++ .bind = sr9800_bind, ++ .status = sr_status, ++ .link_reset = sr9800_link_reset, ++ .reset = sr9800_reset, ++ .flags = DRIVER_FLAG, ++ .rx_fixup = sr_rx_fixup, ++ .tx_fixup = sr_tx_fixup, ++}; ++ ++static const struct usb_device_id products[] = { ++ { ++ USB_DEVICE(0x0fe6, 0x9800), /* SR9800 Device */ ++ .driver_info = (unsigned long) &sr9800_driver_info, ++ }, ++ {}, /* END */ ++}; ++ ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver sr_driver = { ++ .name = DRIVER_NAME, ++ .id_table = products, ++ .probe = usbnet_probe, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disconnect = usbnet_disconnect, ++ .supports_autosuspend = 1, ++}; ++ ++module_usb_driver(sr_driver); ++ ++MODULE_AUTHOR("Liu Junliang <liujunliang_ljl@163.com"); ++MODULE_VERSION(DRIVER_VERSION); ++MODULE_DESCRIPTION("SR9800 USB 2.0 USB2NET Dev : http://www.corechip-sz.com"); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/usb/sr9800.h backports-3.18.1-1/drivers/net/usb/sr9800.h +--- backports-3.18.1-1.org/drivers/net/usb/sr9800.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/sr9800.h 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,202 @@ ++/* CoreChip-sz SR9800 one chip USB 2.0 Ethernet Devices ++ * ++ * Author : Liu Junliang liujunliang_ljl@163.com ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++#ifndef _SR9800_H ++#define _SR9800_H ++ ++/* SR9800 spec. command table on Linux Platform */ ++ ++/* command : Software Station Management Control Reg */ ++#define SR_CMD_SET_SW_MII 0x06 ++/* command : PHY Read Reg */ ++#define SR_CMD_READ_MII_REG 0x07 ++/* command : PHY Write Reg */ ++#define SR_CMD_WRITE_MII_REG 0x08 ++/* command : Hardware Station Management Control Reg */ ++#define SR_CMD_SET_HW_MII 0x0a ++/* command : SROM Read Reg */ ++#define SR_CMD_READ_EEPROM 0x0b ++/* command : SROM Write Reg */ ++#define SR_CMD_WRITE_EEPROM 0x0c ++/* command : SROM Write Enable Reg */ ++#define SR_CMD_WRITE_ENABLE 0x0d ++/* command : SROM Write Disable Reg */ ++#define SR_CMD_WRITE_DISABLE 0x0e ++/* command : RX Control Read Reg */ ++#define SR_CMD_READ_RX_CTL 0x0f ++#define SR_RX_CTL_PRO (1 << 0) ++#define SR_RX_CTL_AMALL (1 << 1) ++#define SR_RX_CTL_SEP (1 << 2) ++#define SR_RX_CTL_AB (1 << 3) ++#define SR_RX_CTL_AM (1 << 4) ++#define SR_RX_CTL_AP (1 << 5) ++#define SR_RX_CTL_ARP (1 << 6) ++#define SR_RX_CTL_SO (1 << 7) ++#define SR_RX_CTL_RH1M (1 << 8) ++#define SR_RX_CTL_RH2M (1 << 9) ++#define SR_RX_CTL_RH3M (1 << 10) ++/* command : RX Control Write Reg */ ++#define SR_CMD_WRITE_RX_CTL 0x10 ++/* command : IPG0/IPG1/IPG2 Control Read Reg */ ++#define SR_CMD_READ_IPG012 0x11 ++/* command : IPG0/IPG1/IPG2 Control Write Reg */ ++#define SR_CMD_WRITE_IPG012 0x12 ++/* command : Node ID Read Reg */ ++#define SR_CMD_READ_NODE_ID 0x13 ++/* command : Node ID Write Reg */ ++#define SR_CMD_WRITE_NODE_ID 0x14 ++/* command : Multicast Filter Array Read Reg */ ++#define SR_CMD_READ_MULTI_FILTER 0x15 ++/* command : Multicast Filter Array Write Reg */ ++#define SR_CMD_WRITE_MULTI_FILTER 0x16 ++/* command : Eth/HomePNA PHY Address Reg */ ++#define SR_CMD_READ_PHY_ID 0x19 ++/* command : Medium Status Read Reg */ ++#define SR_CMD_READ_MEDIUM_STATUS 0x1a ++#define SR_MONITOR_LINK (1 << 1) ++#define SR_MONITOR_MAGIC (1 << 2) ++#define SR_MONITOR_HSFS (1 << 4) ++/* command : Medium Status Write Reg */ ++#define SR_CMD_WRITE_MEDIUM_MODE 0x1b ++#define SR_MEDIUM_GM (1 << 0) ++#define SR_MEDIUM_FD (1 << 1) ++#define SR_MEDIUM_AC (1 << 2) ++#define SR_MEDIUM_ENCK (1 << 3) ++#define SR_MEDIUM_RFC (1 << 4) ++#define SR_MEDIUM_TFC (1 << 5) ++#define SR_MEDIUM_JFE (1 << 6) ++#define SR_MEDIUM_PF (1 << 7) ++#define SR_MEDIUM_RE (1 << 8) ++#define SR_MEDIUM_PS (1 << 9) ++#define SR_MEDIUM_RSV (1 << 10) ++#define SR_MEDIUM_SBP (1 << 11) ++#define SR_MEDIUM_SM (1 << 12) ++/* command : Monitor Mode Status Read Reg */ ++#define SR_CMD_READ_MONITOR_MODE 0x1c ++/* command : Monitor Mode Status Write Reg */ ++#define SR_CMD_WRITE_MONITOR_MODE 0x1d ++/* command : GPIO Status Read Reg */ ++#define SR_CMD_READ_GPIOS 0x1e ++#define SR_GPIO_GPO0EN (1 << 0) /* GPIO0 Output enable */ ++#define SR_GPIO_GPO_0 (1 << 1) /* GPIO0 Output value */ ++#define SR_GPIO_GPO1EN (1 << 2) /* GPIO1 Output enable */ ++#define SR_GPIO_GPO_1 (1 << 3) /* GPIO1 Output value */ ++#define SR_GPIO_GPO2EN (1 << 4) /* GPIO2 Output enable */ ++#define SR_GPIO_GPO_2 (1 << 5) /* GPIO2 Output value */ ++#define SR_GPIO_RESERVED (1 << 6) /* Reserved */ ++#define SR_GPIO_RSE (1 << 7) /* Reload serial EEPROM */ ++/* command : GPIO Status Write Reg */ ++#define SR_CMD_WRITE_GPIOS 0x1f ++/* command : Eth PHY Power and Reset Control Reg */ ++#define SR_CMD_SW_RESET 0x20 ++#define SR_SWRESET_CLEAR 0x00 ++#define SR_SWRESET_RR (1 << 0) ++#define SR_SWRESET_RT (1 << 1) ++#define SR_SWRESET_PRTE (1 << 2) ++#define SR_SWRESET_PRL (1 << 3) ++#define SR_SWRESET_BZ (1 << 4) ++#define SR_SWRESET_IPRL (1 << 5) ++#define SR_SWRESET_IPPD (1 << 6) ++/* command : Software Interface Selection Status Read Reg */ ++#define SR_CMD_SW_PHY_STATUS 0x21 ++/* command : Software Interface Selection Status Write Reg */ ++#define SR_CMD_SW_PHY_SELECT 0x22 ++/* command : BULK in Buffer Size Reg */ ++#define SR_CMD_BULKIN_SIZE 0x2A ++/* command : LED_MUX Control Reg */ ++#define SR_CMD_LED_MUX 0x70 ++#define SR_LED_MUX_TX_ACTIVE (1 << 0) ++#define SR_LED_MUX_RX_ACTIVE (1 << 1) ++#define SR_LED_MUX_COLLISION (1 << 2) ++#define SR_LED_MUX_DUP_COL (1 << 3) ++#define SR_LED_MUX_DUP (1 << 4) ++#define SR_LED_MUX_SPEED (1 << 5) ++#define SR_LED_MUX_LINK_ACTIVE (1 << 6) ++#define SR_LED_MUX_LINK (1 << 7) ++ ++/* Register Access Flags */ ++#define SR_REQ_RD_REG (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) ++#define SR_REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) ++ ++/* Multicast Filter Array size & Max Number */ ++#define SR_MCAST_FILTER_SIZE 8 ++#define SR_MAX_MCAST 64 ++ ++/* IPG0/1/2 Default Value */ ++#define SR9800_IPG0_DEFAULT 0x15 ++#define SR9800_IPG1_DEFAULT 0x0c ++#define SR9800_IPG2_DEFAULT 0x12 ++ ++/* Medium Status Default Mode */ ++#define SR9800_MEDIUM_DEFAULT \ ++ (SR_MEDIUM_FD | SR_MEDIUM_RFC | \ ++ SR_MEDIUM_TFC | SR_MEDIUM_PS | \ ++ SR_MEDIUM_AC | SR_MEDIUM_RE) ++ ++/* RX Control Default Setting */ ++#define SR_DEFAULT_RX_CTL \ ++ (SR_RX_CTL_SO | SR_RX_CTL_AB | SR_RX_CTL_RH1M) ++ ++/* EEPROM Magic Number & EEPROM Size */ ++#define SR_EEPROM_MAGIC 0xdeadbeef ++#define SR9800_EEPROM_LEN 0xff ++ ++/* SR9800 Driver Version and Driver Name */ ++#define DRIVER_VERSION "11-Nov-2013" ++#define DRIVER_NAME "CoreChips" ++#define DRIVER_FLAG \ ++ (FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET) ++ ++/* SR9800 BULKIN Buffer Size */ ++#define SR9800_MAX_BULKIN_2K 0 ++#define SR9800_MAX_BULKIN_4K 1 ++#define SR9800_MAX_BULKIN_6K 2 ++#define SR9800_MAX_BULKIN_8K 3 ++#define SR9800_MAX_BULKIN_16K 4 ++#define SR9800_MAX_BULKIN_20K 5 ++#define SR9800_MAX_BULKIN_24K 6 ++#define SR9800_MAX_BULKIN_32K 7 ++ ++struct {unsigned short size, byte_cnt, threshold; } SR9800_BULKIN_SIZE[] = { ++ /* 2k */ ++ {2048, 0x8000, 0x8001}, ++ /* 4k */ ++ {4096, 0x8100, 0x8147}, ++ /* 6k */ ++ {6144, 0x8200, 0x81EB}, ++ /* 8k */ ++ {8192, 0x8300, 0x83D7}, ++ /* 16 */ ++ {16384, 0x8400, 0x851E}, ++ /* 20k */ ++ {20480, 0x8500, 0x8666}, ++ /* 24k */ ++ {24576, 0x8600, 0x87AE}, ++ /* 32k */ ++ {32768, 0x8700, 0x8A3D}, ++}; ++ ++/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ ++struct sr_data { ++ u8 multi_filter[SR_MCAST_FILTER_SIZE]; ++ u8 mac_addr[ETH_ALEN]; ++ u8 phymode; ++ u8 ledmode; ++ u8 eeprom_len; ++}; ++ ++struct sr9800_int_data { ++ __le16 res1; ++ u8 link; ++ __le16 res2; ++ u8 status; ++ __le16 res3; ++} __packed; ++ ++#endif /* _SR9800_H */ +diff -Naur backports-3.18.1-1.org/drivers/net/usb/zaurus.c backports-3.18.1-1/drivers/net/usb/zaurus.c +--- backports-3.18.1-1.org/drivers/net/usb/zaurus.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/zaurus.c 2014-12-16 18:39:45.000000000 +0100 +@@ -0,0 +1,385 @@ ++/* ++ * Copyright (C) 2002 Pavel Machek pavel@ucw.cz ++ * Copyright (C) 2002-2005 by David Brownell ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++// #define DEBUG // error path messages, extra info ++// #define VERBOSE // more; success messages ++ ++#include <linux/module.h> ++#include <linux/netdevice.h> ++#include <linux/ethtool.h> ++#include <linux/workqueue.h> ++#include <linux/mii.h> ++#include <linux/crc32.h> ++#include <linux/usb.h> ++#include <linux/usb/cdc.h> ++#include <linux/usb/usbnet.h> ++ ++ ++/* ++ * All known Zaurii lie about their standards conformance. At least ++ * the earliest SA-1100 models lie by saying they support CDC Ethernet. ++ * Some later models (especially PXA-25x and PXA-27x based ones) lie ++ * and say they support CDC MDLM (for access to cell phone modems). ++ * ++ * There are non-Zaurus products that use these same protocols too. ++ * ++ * The annoying thing is that at the same time Sharp was developing ++ * that annoying standards-breaking software, the Linux community had ++ * a simple "CDC Subset" working reliably on the same SA-1100 hardware. ++ * That is, the same functionality but not violating standards. ++ * ++ * The CDC Ethernet nonconformance points are troublesome to hosts ++ * with a true CDC Ethernet implementation: ++ * - Framing appends a CRC, which the spec says drivers "must not" do; ++ * - Transfers data in altsetting zero, instead of altsetting 1; ++ * - All these peripherals use the same ethernet address. ++ * ++ * The CDC MDLM nonconformance is less immediately troublesome, since all ++ * MDLM implementations are quasi-proprietary anyway. ++ */ ++ ++static struct sk_buff * ++zaurus_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) ++{ ++ int padlen; ++ struct sk_buff *skb2; ++ ++ padlen = 2; ++ if (!skb_cloned(skb)) { ++ int tailroom = skb_tailroom(skb); ++ if ((padlen + 4) <= tailroom) ++ goto done; ++ } ++ skb2 = skb_copy_expand(skb, 0, 4 + padlen, flags); ++ dev_kfree_skb_any(skb); ++ skb = skb2; ++ if (skb) { ++ u32 fcs; ++done: ++ fcs = crc32_le(~0, skb->data, skb->len); ++ fcs = ~fcs; ++ ++ *skb_put (skb, 1) = fcs & 0xff; ++ *skb_put (skb, 1) = (fcs>> 8) & 0xff; ++ *skb_put (skb, 1) = (fcs>>16) & 0xff; ++ *skb_put (skb, 1) = (fcs>>24) & 0xff; ++ } ++ return skb; ++} ++ ++static int zaurus_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ /* Belcarra's funky framing has other options; mostly ++ * TRAILERS (!) with 4 bytes CRC, and maybe 2 pad bytes. ++ */ ++ dev->net->hard_header_len += 6; ++ dev->rx_urb_size = dev->net->hard_header_len + dev->net->mtu; ++ return usbnet_generic_cdc_bind(dev, intf); ++} ++ ++/* PDA style devices are always connected if present */ ++static int always_connected (struct usbnet *dev) ++{ ++ return 0; ++} ++ ++static const struct driver_info zaurus_sl5x00_info = { ++ .description = "Sharp Zaurus SL-5x00", ++ .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, ++ .check_connect = always_connected, ++ .bind = zaurus_bind, ++ .unbind = usbnet_cdc_unbind, ++ .tx_fixup = zaurus_tx_fixup, ++}; ++#define ZAURUS_STRONGARM_INFO ((unsigned long)&zaurus_sl5x00_info) ++ ++static const struct driver_info zaurus_pxa_info = { ++ .description = "Sharp Zaurus, PXA-2xx based", ++ .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, ++ .check_connect = always_connected, ++ .bind = zaurus_bind, ++ .unbind = usbnet_cdc_unbind, ++ .tx_fixup = zaurus_tx_fixup, ++}; ++#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info) ++ ++static const struct driver_info olympus_mxl_info = { ++ .description = "Olympus R1000", ++ .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, ++ .check_connect = always_connected, ++ .bind = zaurus_bind, ++ .unbind = usbnet_cdc_unbind, ++ .tx_fixup = zaurus_tx_fixup, ++}; ++#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info) ++ ++ ++/* Some more recent products using Lineo/Belcarra code will wrongly claim ++ * CDC MDLM conformance. They aren't conformant: data endpoints live ++ * in the control interface, there's no data interface, and it's not used ++ * to talk to a cell phone radio. But at least we can detect these two ++ * pseudo-classes, rather than growing this product list with entries for ++ * each new nonconformant product (sigh). ++ */ ++static const u8 safe_guid[16] = { ++ 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6, ++ 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f, ++}; ++static const u8 blan_guid[16] = { ++ 0x74, 0xf0, 0x3d, 0xbd, 0x1e, 0xc1, 0x44, 0x70, ++ 0xa3, 0x67, 0x71, 0x34, 0xc9, 0xf5, 0x54, 0x37, ++}; ++ ++static int blan_mdlm_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ u8 *buf = intf->cur_altsetting->extra; ++ int len = intf->cur_altsetting->extralen; ++ struct usb_cdc_mdlm_desc *desc = NULL; ++ struct usb_cdc_mdlm_detail_desc *detail = NULL; ++ ++ while (len > 3) { ++ if (buf [1] != USB_DT_CS_INTERFACE) ++ goto next_desc; ++ ++ /* use bDescriptorSubType, and just verify that we get a ++ * "BLAN" (or "SAFE") descriptor. ++ */ ++ switch (buf [2]) { ++ case USB_CDC_MDLM_TYPE: ++ if (desc) { ++ dev_dbg(&intf->dev, "extra MDLM\n"); ++ goto bad_desc; ++ } ++ desc = (void *) buf; ++ if (desc->bLength != sizeof *desc) { ++ dev_dbg(&intf->dev, "MDLM len %u\n", ++ desc->bLength); ++ goto bad_desc; ++ } ++ /* expect bcdVersion 1.0, ignore */ ++ if (memcmp(&desc->bGUID, blan_guid, 16) && ++ memcmp(&desc->bGUID, safe_guid, 16)) { ++ /* hey, this one might _really_ be MDLM! */ ++ dev_dbg(&intf->dev, "MDLM guid\n"); ++ goto bad_desc; ++ } ++ break; ++ case USB_CDC_MDLM_DETAIL_TYPE: ++ if (detail) { ++ dev_dbg(&intf->dev, "extra MDLM detail\n"); ++ goto bad_desc; ++ } ++ detail = (void *) buf; ++ switch (detail->bGuidDescriptorType) { ++ case 0: /* "SAFE" */ ++ if (detail->bLength != (sizeof *detail + 2)) ++ goto bad_detail; ++ break; ++ case 1: /* "BLAN" */ ++ if (detail->bLength != (sizeof *detail + 3)) ++ goto bad_detail; ++ break; ++ default: ++ goto bad_detail; ++ } ++ ++ /* assuming we either noticed BLAN already, or will ++ * find it soon, there are some data bytes here: ++ * - bmNetworkCapabilities (unused) ++ * - bmDataCapabilities (bits, see below) ++ * - bPad (ignored, for PADAFTER -- BLAN-only) ++ * bits are: ++ * - 0x01 -- Zaurus framing (add CRC) ++ * - 0x02 -- PADBEFORE (CRC includes some padding) ++ * - 0x04 -- PADAFTER (some padding after CRC) ++ * - 0x08 -- "fermat" packet mangling (for hw bugs) ++ * the PADBEFORE appears not to matter; we interop ++ * with devices that use it and those that don't. ++ */ ++ if ((detail->bDetailData[1] & ~0x02) != 0x01) { ++ /* bmDataCapabilities == 0 would be fine too, ++ * but framing is minidriver-coupled for now. ++ */ ++bad_detail: ++ dev_dbg(&intf->dev, ++ "bad MDLM detail, %d %d %d\n", ++ detail->bLength, ++ detail->bDetailData[0], ++ detail->bDetailData[2]); ++ goto bad_desc; ++ } ++ ++ /* same extra framing as for non-BLAN mode */ ++ dev->net->hard_header_len += 6; ++ dev->rx_urb_size = dev->net->hard_header_len ++ + dev->net->mtu; ++ break; ++ } ++next_desc: ++ len -= buf [0]; /* bLength */ ++ buf += buf [0]; ++ } ++ ++ if (!desc || !detail) { ++ dev_dbg(&intf->dev, "missing cdc mdlm %s%sdescriptor\n", ++ desc ? "" : "func ", ++ detail ? "" : "detail "); ++ goto bad_desc; ++ } ++ ++ /* There's probably a CDC Ethernet descriptor there, but we can't ++ * rely on the Ethernet address it provides since not all vendors ++ * bother to make it unique. Likewise there's no point in tracking ++ * of the CDC event notifications. ++ */ ++ return usbnet_get_endpoints(dev, intf); ++ ++bad_desc: ++ dev_info(&dev->udev->dev, "unsupported MDLM descriptors\n"); ++ return -ENODEV; ++} ++ ++static const struct driver_info bogus_mdlm_info = { ++ .description = "pseudo-MDLM (BLAN) device", ++ .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, ++ .check_connect = always_connected, ++ .tx_fixup = zaurus_tx_fixup, ++ .bind = blan_mdlm_bind, ++}; ++ ++static const struct usb_device_id products [] = { ++#define ZAURUS_MASTER_INTERFACE \ ++ .bInterfaceClass = USB_CLASS_COMM, \ ++ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \ ++ .bInterfaceProtocol = USB_CDC_PROTO_NONE ++ ++/* SA-1100 based Sharp Zaurus ("collie"), or compatible. */ ++{ ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8004, ++ ZAURUS_MASTER_INTERFACE, ++ .driver_info = ZAURUS_STRONGARM_INFO, ++}, ++ ++/* PXA-2xx based models are also lying-about-cdc. If you add any ++ * more devices that claim to be CDC Ethernet, make sure they get ++ * added to the blacklist in cdc_ether too. ++ * ++ * NOTE: OpenZaurus versions with 2.6 kernels won't use these entries, ++ * unlike the older ones with 2.4 "embedix" kernels. ++ */ ++{ ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8005, /* A-300 */ ++ ZAURUS_MASTER_INTERFACE, ++ .driver_info = ZAURUS_PXA_INFO, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8006, /* B-500/SL-5600 */ ++ ZAURUS_MASTER_INTERFACE, ++ .driver_info = ZAURUS_PXA_INFO, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x8007, /* C-700 */ ++ ZAURUS_MASTER_INTERFACE, ++ .driver_info = ZAURUS_PXA_INFO, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x9031, /* C-750 C-760 */ ++ ZAURUS_MASTER_INTERFACE, ++ .driver_info = ZAURUS_PXA_INFO, ++}, { ++ /* C-750/C-760/C-860/SL-C3000 PDA in MDLM mode */ ++ USB_DEVICE_AND_INTERFACE_INFO(0x04DD, 0x9031, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), ++ .driver_info = (unsigned long) &bogus_mdlm_info, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ .idProduct = 0x9032, /* SL-6000 */ ++ ZAURUS_MASTER_INTERFACE, ++ .driver_info = ZAURUS_PXA_INFO, ++}, { ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x04DD, ++ /* reported with some C860 units */ ++ .idProduct = 0x9050, /* C-860 */ ++ ZAURUS_MASTER_INTERFACE, ++ .driver_info = ZAURUS_PXA_INFO, ++}, ++{ ++ /* Motorola Rokr E6 */ ++ USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6027, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), ++ .driver_info = (unsigned long) &bogus_mdlm_info, ++}, { ++ /* Motorola MOTOMAGX phones */ ++ USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), ++ .driver_info = (unsigned long) &bogus_mdlm_info, ++}, ++ ++/* Olympus has some models with a Zaurus-compatible option. ++ * R-1000 uses a FreeScale i.MXL cpu (ARMv4T) ++ */ ++{ ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO ++ | USB_DEVICE_ID_MATCH_DEVICE, ++ .idVendor = 0x07B4, ++ .idProduct = 0x0F02, /* R-1000 */ ++ ZAURUS_MASTER_INTERFACE, ++ .driver_info = OLYMPUS_MXL_INFO, ++}, ++ ++/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */ ++{ ++ USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), ++ .driver_info = (unsigned long) &bogus_mdlm_info, ++}, ++ { }, // END ++}; ++MODULE_DEVICE_TABLE(usb, products); ++ ++static struct usb_driver zaurus_driver = { ++ .name = "zaurus", ++ .id_table = products, ++ .probe = usbnet_probe, ++ .disconnect = usbnet_disconnect, ++ .suspend = usbnet_suspend, ++ .resume = usbnet_resume, ++ .disable_hub_initiated_lpm = 1, ++}; ++ ++module_usb_driver(zaurus_driver); ++ ++MODULE_AUTHOR("Pavel Machek, David Brownell"); ++MODULE_DESCRIPTION("Sharp Zaurus PDA, and compatible products"); ++MODULE_LICENSE("GPL"); diff --git a/src/patches/backports-3.18.1-1-grsecurity.patch b/src/patches/backports-3.18.1-1-grsecurity.patch new file mode 100644 index 0000000..711f2e3 --- /dev/null +++ b/src/patches/backports-3.18.1-1-grsecurity.patch @@ -0,0 +1,3806 @@ +diff -Naur backports-3.18.1-1.org/drivers/bluetooth/btwilink.c backports-3.18.1-1/drivers/bluetooth/btwilink.c +--- backports-3.18.1-1.org/drivers/bluetooth/btwilink.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/drivers/bluetooth/btwilink.c 2014-12-28 14:10:09.480888533 +0100 +@@ -288,7 +288,7 @@ + + static int bt_ti_probe(struct platform_device *pdev) + { +- static struct ti_st *hst; ++ struct ti_st *hst; + struct hci_dev *hdev; + int err; + +diff -Naur backports-3.18.1-1.org/drivers/media/dvb-core/dvbdev.c backports-3.18.1-1/drivers/media/dvb-core/dvbdev.c +--- backports-3.18.1-1.org/drivers/media/dvb-core/dvbdev.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/dvb-core/dvbdev.c 2014-12-28 14:10:09.528888772 +0100 +@@ -185,7 +185,7 @@ + const struct dvb_device *template, void *priv, int type) + { + struct dvb_device *dvbdev; +- struct file_operations *dvbdevfops; ++ file_operations_no_const *dvbdevfops; + struct device *clsdev; + int minor; + int id; +diff -Naur backports-3.18.1-1.org/drivers/media/dvb-frontends/af9033.h backports-3.18.1-1/drivers/media/dvb-frontends/af9033.h +--- backports-3.18.1-1.org/drivers/media/dvb-frontends/af9033.h 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/dvb-frontends/af9033.h 2014-12-28 14:10:09.528888772 +0100 +@@ -96,6 +96,6 @@ + int (*pid_filter_ctrl)(struct dvb_frontend *fe, int onoff); + int (*pid_filter)(struct dvb_frontend *fe, int index, u16 pid, + int onoff); +-}; ++} __no_const; + + #endif /* AF9033_H */ +diff -Naur backports-3.18.1-1.org/drivers/media/dvb-frontends/dib3000.h backports-3.18.1-1/drivers/media/dvb-frontends/dib3000.h +--- backports-3.18.1-1.org/drivers/media/dvb-frontends/dib3000.h 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/dvb-frontends/dib3000.h 2014-12-28 14:10:09.528888772 +0100 +@@ -39,7 +39,7 @@ + int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff); + int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff); + int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); +-}; ++} __no_const; + + #if IS_ENABLED(CPTCFG_DVB_DIB3000MB) + extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, +diff -Naur backports-3.18.1-1.org/drivers/media/dvb-frontends/dib7000p.h backports-3.18.1-1/drivers/media/dvb-frontends/dib7000p.h +--- backports-3.18.1-1.org/drivers/media/dvb-frontends/dib7000p.h 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/dvb-frontends/dib7000p.h 2014-12-28 14:10:09.528888772 +0100 +@@ -64,7 +64,7 @@ + int (*get_adc_power)(struct dvb_frontend *fe); + int (*slave_reset)(struct dvb_frontend *fe); + struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg); +-}; ++} __no_const; + + #if IS_ENABLED(CPTCFG_DVB_DIB7000P) + void *dib7000p_attach(struct dib7000p_ops *ops); +diff -Naur backports-3.18.1-1.org/drivers/media/dvb-frontends/dib8000.h backports-3.18.1-1/drivers/media/dvb-frontends/dib8000.h +--- backports-3.18.1-1.org/drivers/media/dvb-frontends/dib8000.h 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/dvb-frontends/dib8000.h 2014-12-28 14:10:09.528888772 +0100 +@@ -61,7 +61,7 @@ + int (*pid_filter_ctrl)(struct dvb_frontend *fe, u8 onoff); + int (*pid_filter)(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff); + struct dvb_frontend *(*init)(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg); +-}; ++} __no_const; + + #if IS_ENABLED(CPTCFG_DVB_DIB8000) + void *dib8000_attach(struct dib8000_ops *ops); +diff -Naur backports-3.18.1-1.org/drivers/media/pci/cx88/cx88-video.c backports-3.18.1-1/drivers/media/pci/cx88/cx88-video.c +--- backports-3.18.1-1.org/drivers/media/pci/cx88/cx88-video.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/pci/cx88/cx88-video.c 2014-12-28 14:10:09.528888772 +0100 +@@ -50,9 +50,9 @@ + + /* ------------------------------------------------------------------ */ + +-static unsigned int video_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; +-static unsigned int vbi_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; +-static unsigned int radio_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; ++static int video_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; ++static int vbi_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; ++static int radio_nr[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; + + module_param_array(video_nr, int, NULL, 0444); + module_param_array(vbi_nr, int, NULL, 0444); +diff -Naur backports-3.18.1-1.org/drivers/media/pci/ivtv/ivtv-driver.c backports-3.18.1-1/drivers/media/pci/ivtv/ivtv-driver.c +--- backports-3.18.1-1.org/drivers/media/pci/ivtv/ivtv-driver.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/pci/ivtv/ivtv-driver.c 2014-12-28 14:10:09.528888772 +0100 +@@ -83,7 +83,7 @@ + MODULE_DEVICE_TABLE(pci,ivtv_pci_tbl); + + /* ivtv instance counter */ +-static atomic_t ivtv_instance = ATOMIC_INIT(0); ++static atomic_unchecked_t ivtv_instance = ATOMIC_INIT(0); + + /* Parameter declarations */ + static int cardtype[IVTV_MAX_CARDS]; +diff -Naur backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-core.c backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-core.c +--- backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-core.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-core.c 2014-12-28 14:10:09.528888772 +0100 +@@ -424,7 +424,7 @@ + + static int solo_sysfs_init(struct solo_dev *solo_dev) + { +- struct bin_attribute *sdram_attr = &solo_dev->sdram_attr; ++ bin_attribute_no_const *sdram_attr = &solo_dev->sdram_attr; + struct device *dev = &solo_dev->dev; + const char *driver; + int i; +diff -Naur backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-g723.c backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-g723.c +--- backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-g723.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-g723.c 2014-12-28 14:10:09.528888772 +0100 +@@ -351,7 +351,7 @@ + + int solo_g723_init(struct solo_dev *solo_dev) + { +- static struct snd_device_ops ops = { NULL }; ++ static struct snd_device_ops ops = { }; + struct snd_card *card; + struct snd_kcontrol_new kctl; + char name[32]; +diff -Naur backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10.h backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10.h +--- backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10.h 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10.h 2014-12-28 14:10:09.532888798 +0100 +@@ -219,7 +219,7 @@ + + /* P2M DMA Engine */ + struct solo_p2m_dev p2m_dev[SOLO_NR_P2M]; +- atomic_t p2m_count; ++ atomic_unchecked_t p2m_count; + int p2m_jiffies; + unsigned int p2m_timeouts; + +diff -Naur backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-p2m.c backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-p2m.c +--- backports-3.18.1-1.org/drivers/media/pci/solo6x10/solo6x10-p2m.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/pci/solo6x10/solo6x10-p2m.c 2014-12-28 14:10:09.532888798 +0100 +@@ -73,7 +73,7 @@ + + /* Get next ID. According to Softlogic, 6110 has problems on !=0 P2M */ + if (solo_dev->type != SOLO_DEV_6110 && multi_p2m) { +- p2m_id = atomic_inc_return(&solo_dev->p2m_count) % SOLO_NR_P2M; ++ p2m_id = atomic_inc_return_unchecked(&solo_dev->p2m_count) % SOLO_NR_P2M; + if (p2m_id < 0) + p2m_id = -p2m_id; + } +diff -Naur backports-3.18.1-1.org/drivers/media/platform/omap/omap_vout.c backports-3.18.1-1/drivers/media/platform/omap/omap_vout.c +--- backports-3.18.1-1.org/drivers/media/platform/omap/omap_vout.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/platform/omap/omap_vout.c 2014-12-28 14:10:09.532888798 +0100 +@@ -63,7 +63,6 @@ + OMAP_VIDEO2, + }; + +-static struct videobuf_queue_ops video_vbq_ops; + /* Variables configurable through module params*/ + static u32 video1_numbuffers = 3; + static u32 video2_numbuffers = 3; +@@ -1012,6 +1011,12 @@ + { + struct videobuf_queue *q; + struct omap_vout_device *vout = NULL; ++ static struct videobuf_queue_ops video_vbq_ops = { ++ .buf_setup = omap_vout_buffer_setup, ++ .buf_prepare = omap_vout_buffer_prepare, ++ .buf_release = omap_vout_buffer_release, ++ .buf_queue = omap_vout_buffer_queue, ++ }; + + vout = video_drvdata(file); + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__); +@@ -1029,10 +1034,6 @@ + vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + q = &vout->vbq; +- video_vbq_ops.buf_setup = omap_vout_buffer_setup; +- video_vbq_ops.buf_prepare = omap_vout_buffer_prepare; +- video_vbq_ops.buf_release = omap_vout_buffer_release; +- video_vbq_ops.buf_queue = omap_vout_buffer_queue; + spin_lock_init(&vout->vbq_lock); + + videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev, +diff -Naur backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_grp_layer.c backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_grp_layer.c +--- backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_grp_layer.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_grp_layer.c 2014-12-28 14:10:09.532888798 +0100 +@@ -235,7 +235,7 @@ + { + struct mxr_layer *layer; + int ret; +- struct mxr_layer_ops ops = { ++ static struct mxr_layer_ops ops = { + .release = mxr_graph_layer_release, + .buffer_set = mxr_graph_buffer_set, + .stream_set = mxr_graph_stream_set, +diff -Naur backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer.h backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer.h +--- backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer.h 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer.h 2014-12-28 14:10:09.532888798 +0100 +@@ -156,7 +156,7 @@ + /** layer index (unique identifier) */ + int idx; + /** callbacks for layer methods */ +- struct mxr_layer_ops ops; ++ struct mxr_layer_ops *ops; + /** format array */ + const struct mxr_format **fmt_array; + /** size of format array */ +diff -Naur backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_reg.c backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_reg.c +--- backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_reg.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_reg.c 2014-12-28 14:10:09.532888798 +0100 +@@ -276,7 +276,7 @@ + layer->update_buf = next; + } + +- layer->ops.buffer_set(layer, layer->update_buf); ++ layer->ops->buffer_set(layer, layer->update_buf); + + if (done && done != layer->shadow_buf) + vb2_buffer_done(&done->vb, VB2_BUF_STATE_DONE); +diff -Naur backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_video.c backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_video.c +--- backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_video.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_video.c 2014-12-28 14:10:09.532888798 +0100 +@@ -210,7 +210,7 @@ + layer->geo.src.height = layer->geo.src.full_height; + + mxr_geometry_dump(mdev, &layer->geo); +- layer->ops.fix_geometry(layer, MXR_GEOMETRY_SINK, 0); ++ layer->ops->fix_geometry(layer, MXR_GEOMETRY_SINK, 0); + mxr_geometry_dump(mdev, &layer->geo); + } + +@@ -228,7 +228,7 @@ + layer->geo.dst.full_width = mbus_fmt.width; + layer->geo.dst.full_height = mbus_fmt.height; + layer->geo.dst.field = mbus_fmt.field; +- layer->ops.fix_geometry(layer, MXR_GEOMETRY_SINK, 0); ++ layer->ops->fix_geometry(layer, MXR_GEOMETRY_SINK, 0); + + mxr_geometry_dump(mdev, &layer->geo); + } +@@ -334,7 +334,7 @@ + /* set source size to highest accepted value */ + geo->src.full_width = max(geo->dst.full_width, pix->width); + geo->src.full_height = max(geo->dst.full_height, pix->height); +- layer->ops.fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0); ++ layer->ops->fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0); + mxr_geometry_dump(mdev, &layer->geo); + /* set cropping to total visible screen */ + geo->src.width = pix->width; +@@ -342,12 +342,12 @@ + geo->src.x_offset = 0; + geo->src.y_offset = 0; + /* assure consistency of geometry */ +- layer->ops.fix_geometry(layer, MXR_GEOMETRY_CROP, MXR_NO_OFFSET); ++ layer->ops->fix_geometry(layer, MXR_GEOMETRY_CROP, MXR_NO_OFFSET); + mxr_geometry_dump(mdev, &layer->geo); + /* set full size to lowest possible value */ + geo->src.full_width = 0; + geo->src.full_height = 0; +- layer->ops.fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0); ++ layer->ops->fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0); + mxr_geometry_dump(mdev, &layer->geo); + + /* returning results */ +@@ -474,7 +474,7 @@ + target->width = s->r.width; + target->height = s->r.height; + +- layer->ops.fix_geometry(layer, stage, s->flags); ++ layer->ops->fix_geometry(layer, stage, s->flags); + + /* retrieve update selection rectangle */ + res.left = target->x_offset; +@@ -954,13 +954,13 @@ + mxr_output_get(mdev); + + mxr_layer_update_output(layer); +- layer->ops.format_set(layer); ++ layer->ops->format_set(layer); + /* enabling layer in hardware */ + spin_lock_irqsave(&layer->enq_slock, flags); + layer->state = MXR_LAYER_STREAMING; + spin_unlock_irqrestore(&layer->enq_slock, flags); + +- layer->ops.stream_set(layer, MXR_ENABLE); ++ layer->ops->stream_set(layer, MXR_ENABLE); + mxr_streamer_get(mdev); + + return 0; +@@ -1030,7 +1030,7 @@ + spin_unlock_irqrestore(&layer->enq_slock, flags); + + /* disabling layer in hardware */ +- layer->ops.stream_set(layer, MXR_DISABLE); ++ layer->ops->stream_set(layer, MXR_DISABLE); + /* remove one streamer */ + mxr_streamer_put(mdev); + /* allow changes in output configuration */ +@@ -1068,8 +1068,8 @@ + + void mxr_layer_release(struct mxr_layer *layer) + { +- if (layer->ops.release) +- layer->ops.release(layer); ++ if (layer->ops->release) ++ layer->ops->release(layer); + } + + void mxr_base_layer_release(struct mxr_layer *layer) +@@ -1095,7 +1095,7 @@ + + layer->mdev = mdev; + layer->idx = idx; +- layer->ops = *ops; ++ layer->ops = ops; + + spin_lock_init(&layer->enq_slock); + INIT_LIST_HEAD(&layer->enq_list); +diff -Naur backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_vp_layer.c backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_vp_layer.c +--- backports-3.18.1-1.org/drivers/media/platform/s5p-tv/mixer_vp_layer.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/platform/s5p-tv/mixer_vp_layer.c 2014-12-28 14:10:09.532888798 +0100 +@@ -206,7 +206,7 @@ + { + struct mxr_layer *layer; + int ret; +- struct mxr_layer_ops ops = { ++ static struct mxr_layer_ops ops = { + .release = mxr_vp_layer_release, + .buffer_set = mxr_vp_buffer_set, + .stream_set = mxr_vp_stream_set, +diff -Naur backports-3.18.1-1.org/drivers/media/radio/radio-cadet.c backports-3.18.1-1/drivers/media/radio/radio-cadet.c +--- backports-3.18.1-1.org/drivers/media/radio/radio-cadet.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/radio/radio-cadet.c 2014-12-28 14:10:09.532888798 +0100 +@@ -333,6 +333,8 @@ + unsigned char readbuf[RDS_BUFFER]; + int i = 0; + ++ if (count > RDS_BUFFER) ++ return -EFAULT; + mutex_lock(&dev->lock); + if (dev->rdsstat == 0) + cadet_start_rds(dev); +@@ -349,8 +351,9 @@ + readbuf[i++] = dev->rdsbuf[dev->rdsout++]; + mutex_unlock(&dev->lock); + +- if (i && copy_to_user(data, readbuf, i)) +- return -EFAULT; ++ if (i > sizeof(readbuf) || (i && copy_to_user(data, readbuf, i))) ++ i = -EFAULT; ++ + return i; + } + +diff -Naur backports-3.18.1-1.org/drivers/media/radio/radio-maxiradio.c backports-3.18.1-1/drivers/media/radio/radio-maxiradio.c +--- backports-3.18.1-1.org/drivers/media/radio/radio-maxiradio.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/radio/radio-maxiradio.c 2014-12-28 14:10:09.532888798 +0100 +@@ -61,7 +61,7 @@ + /* TEA5757 pin mappings */ + static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16; + +-static atomic_t maxiradio_instance = ATOMIC_INIT(0); ++static atomic_unchecked_t maxiradio_instance = ATOMIC_INIT(0); + + #define PCI_VENDOR_ID_GUILLEMOT 0x5046 + #define PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO 0x1001 +diff -Naur backports-3.18.1-1.org/drivers/media/radio/radio-shark2.c backports-3.18.1-1/drivers/media/radio/radio-shark2.c +--- backports-3.18.1-1.org/drivers/media/radio/radio-shark2.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/radio/radio-shark2.c 2014-12-28 14:10:09.532888798 +0100 +@@ -74,7 +74,7 @@ + u8 *transfer_buffer; + }; + +-static atomic_t shark_instance = ATOMIC_INIT(0); ++static atomic_unchecked_t shark_instance = ATOMIC_INIT(0); + + static int shark_write_reg(struct radio_tea5777 *tea, u64 reg) + { +diff -Naur backports-3.18.1-1.org/drivers/media/radio/radio-shark.c backports-3.18.1-1/drivers/media/radio/radio-shark.c +--- backports-3.18.1-1.org/drivers/media/radio/radio-shark.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/radio/radio-shark.c 2014-12-28 14:10:09.532888798 +0100 +@@ -79,7 +79,7 @@ + u32 last_val; + }; + +-static atomic_t shark_instance = ATOMIC_INIT(0); ++static atomic_unchecked_t shark_instance = ATOMIC_INIT(0); + + static void shark_write_val(struct snd_tea575x *tea, u32 val) + { +diff -Naur backports-3.18.1-1.org/drivers/media/radio/radio-si476x.c backports-3.18.1-1/drivers/media/radio/radio-si476x.c +--- backports-3.18.1-1.org/drivers/media/radio/radio-si476x.c 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/radio/radio-si476x.c 2014-12-28 14:10:09.532888798 +0100 +@@ -1445,7 +1445,7 @@ + struct si476x_radio *radio; + struct v4l2_ctrl *ctrl; + +- static atomic_t instance = ATOMIC_INIT(0); ++ static atomic_unchecked_t instance = ATOMIC_INIT(0); + + radio = devm_kzalloc(&pdev->dev, sizeof(*radio), GFP_KERNEL); + if (!radio) +diff -Naur backports-3.18.1-1.org/drivers/media/usb/dvb-usb/cinergyT2-core.c backports-3.18.1-1/drivers/media/usb/dvb-usb/cinergyT2-core.c +--- backports-3.18.1-1.org/drivers/media/usb/dvb-usb/cinergyT2-core.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/usb/dvb-usb/cinergyT2-core.c 2014-12-28 14:10:09.532888798 +0100 +@@ -50,29 +50,73 @@ + + static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable) + { +- char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 }; +- char result[64]; +- return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result, +- sizeof(result), 0); ++ char *buf; ++ char *result; ++ int retval; ++ ++ buf = kmalloc(2, GFP_KERNEL); ++ if (buf == NULL) ++ return -ENOMEM; ++ result = kmalloc(64, GFP_KERNEL); ++ if (result == NULL) { ++ kfree(buf); ++ return -ENOMEM; ++ } ++ ++ buf[0] = CINERGYT2_EP1_CONTROL_STREAM_TRANSFER; ++ buf[1] = enable ? 1 : 0; ++ ++ retval = dvb_usb_generic_rw(adap->dev, buf, 2, result, 64, 0); ++ ++ kfree(buf); ++ kfree(result); ++ return retval; + } + + static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable) + { +- char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 }; +- char state[3]; +- return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0); ++ char *buf; ++ char *state; ++ int retval; ++ ++ buf = kmalloc(2, GFP_KERNEL); ++ if (buf == NULL) ++ return -ENOMEM; ++ state = kmalloc(3, GFP_KERNEL); ++ if (state == NULL) { ++ kfree(buf); ++ return -ENOMEM; ++ } ++ ++ buf[0] = CINERGYT2_EP1_SLEEP_MODE; ++ buf[1] = enable ? 1 : 0; ++ ++ retval = dvb_usb_generic_rw(d, buf, 2, state, 3, 0); ++ ++ kfree(buf); ++ kfree(state); ++ return retval; + } + + static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) + { +- char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION }; +- char state[3]; ++ char *query; ++ char *state; + int ret; ++ query = kmalloc(1, GFP_KERNEL); ++ if (query == NULL) ++ return -ENOMEM; ++ state = kmalloc(3, GFP_KERNEL); ++ if (state == NULL) { ++ kfree(query); ++ return -ENOMEM; ++ } ++ ++ query[0] = CINERGYT2_EP1_GET_FIRMWARE_VERSION; + + adap->fe_adap[0].fe = cinergyt2_fe_attach(adap->dev); + +- ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state, +- sizeof(state), 0); ++ ret = dvb_usb_generic_rw(adap->dev, query, 1, state, 3, 0); + if (ret < 0) { + deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep " + "state info\n"); +@@ -80,7 +124,8 @@ + + /* Copy this pointer as we are gonna need it in the release phase */ + cinergyt2_usb_device = adap->dev; +- ++ kfree(query); ++ kfree(state); + return 0; + } + +@@ -141,12 +186,23 @@ + static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state) + { + struct cinergyt2_state *st = d->priv; +- u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS; ++ u8 *key, *cmd; + int i; + ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -EINVAL; ++ key = kzalloc(5, GFP_KERNEL); ++ if (key == NULL) { ++ kfree(cmd); ++ return -EINVAL; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_RC_EVENTS; ++ + *state = REMOTE_NO_KEY_PRESSED; + +- dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0); ++ dvb_usb_generic_rw(d, cmd, 1, key, 5, 0); + if (key[4] == 0xff) { + /* key repeat */ + st->rc_counter++; +@@ -157,12 +213,12 @@ + *event = d->last_event; + deb_rc("repeat key, event %x\n", + *event); +- return 0; ++ goto out; + } + } + deb_rc("repeated key (non repeatable)\n"); + } +- return 0; ++ goto out; + } + + /* hack to pass checksum on the custom field */ +@@ -174,6 +230,9 @@ + + deb_rc("key: %*ph\n", 5, key); + } ++out: ++ kfree(cmd); ++ kfree(key); + return 0; + } + +diff -Naur backports-3.18.1-1.org/drivers/media/usb/dvb-usb/cinergyT2-fe.c backports-3.18.1-1/drivers/media/usb/dvb-usb/cinergyT2-fe.c +--- backports-3.18.1-1.org/drivers/media/usb/dvb-usb/cinergyT2-fe.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/usb/dvb-usb/cinergyT2-fe.c 2014-12-28 14:10:09.532888798 +0100 +@@ -145,103 +145,176 @@ + fe_status_t *status) + { + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_get_status_msg result; +- u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; ++ struct dvbt_get_status_msg *result; ++ u8 *cmd; + int ret; + +- ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result, +- sizeof(result), 0); ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -ENOMEM; ++ result = kmalloc(sizeof(*result), GFP_KERNEL); ++ if (result == NULL) { ++ kfree(cmd); ++ return -ENOMEM; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS; ++ ++ ret = dvb_usb_generic_rw(state->d, cmd, 1, (u8 *)result, ++ sizeof(*result), 0); + if (ret < 0) +- return ret; ++ goto out; + + *status = 0; + +- if (0xffff - le16_to_cpu(result.gain) > 30) ++ if (0xffff - le16_to_cpu(result->gain) > 30) + *status |= FE_HAS_SIGNAL; +- if (result.lock_bits & (1 << 6)) ++ if (result->lock_bits & (1 << 6)) + *status |= FE_HAS_LOCK; +- if (result.lock_bits & (1 << 5)) ++ if (result->lock_bits & (1 << 5)) + *status |= FE_HAS_SYNC; +- if (result.lock_bits & (1 << 4)) ++ if (result->lock_bits & (1 << 4)) + *status |= FE_HAS_CARRIER; +- if (result.lock_bits & (1 << 1)) ++ if (result->lock_bits & (1 << 1)) + *status |= FE_HAS_VITERBI; + + if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != + (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) + *status &= ~FE_HAS_LOCK; + +- return 0; ++out: ++ kfree(cmd); ++ kfree(result); ++ return ret; + } + + static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber) + { + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_get_status_msg status; +- char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; ++ struct dvbt_get_status_msg *status; ++ char *cmd; + int ret; + +- ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, +- sizeof(status), 0); ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -ENOMEM; ++ status = kmalloc(sizeof(*status), GFP_KERNEL); ++ if (status == NULL) { ++ kfree(cmd); ++ return -ENOMEM; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS; ++ ++ ret = dvb_usb_generic_rw(state->d, cmd, 1, (char *)status, ++ sizeof(*status), 0); + if (ret < 0) +- return ret; ++ goto out; + +- *ber = le32_to_cpu(status.viterbi_error_rate); ++ *ber = le32_to_cpu(status->viterbi_error_rate); ++out: ++ kfree(cmd); ++ kfree(status); + return 0; + } + + static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) + { + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_get_status_msg status; +- u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; ++ struct dvbt_get_status_msg *status; ++ u8 *cmd; + int ret; + +- ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status, +- sizeof(status), 0); ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -ENOMEM; ++ status = kmalloc(sizeof(*status), GFP_KERNEL); ++ if (status == NULL) { ++ kfree(cmd); ++ return -ENOMEM; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS; ++ ++ ret = dvb_usb_generic_rw(state->d, cmd, 1, (u8 *)status, ++ sizeof(*status), 0); + if (ret < 0) { + err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n", + ret); +- return ret; ++ goto out; + } +- *unc = le32_to_cpu(status.uncorrected_block_count); +- return 0; ++ *unc = le32_to_cpu(status->uncorrected_block_count); ++ ++out: ++ kfree(cmd); ++ kfree(status); ++ return ret; + } + + static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe, + u16 *strength) + { + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_get_status_msg status; +- char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; ++ struct dvbt_get_status_msg *status; ++ char *cmd; + int ret; + +- ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, +- sizeof(status), 0); ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -ENOMEM; ++ status = kmalloc(sizeof(*status), GFP_KERNEL); ++ if (status == NULL) { ++ kfree(cmd); ++ return -ENOMEM; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS; ++ ++ ret = dvb_usb_generic_rw(state->d, cmd, 1, (char *)status, ++ sizeof(*status), 0); + if (ret < 0) { + err("cinergyt2_fe_read_signal_strength() Failed!" + " (Error=%d)\n", ret); +- return ret; ++ goto out; + } +- *strength = (0xffff - le16_to_cpu(status.gain)); ++ *strength = (0xffff - le16_to_cpu(status->gain)); ++ ++out: ++ kfree(cmd); ++ kfree(status); + return 0; + } + + static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr) + { + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_get_status_msg status; +- char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; ++ struct dvbt_get_status_msg *status; ++ char *cmd; + int ret; + +- ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, +- sizeof(status), 0); ++ cmd = kmalloc(1, GFP_KERNEL); ++ if (cmd == NULL) ++ return -ENOMEM; ++ status = kmalloc(sizeof(*status), GFP_KERNEL); ++ if (status == NULL) { ++ kfree(cmd); ++ return -ENOMEM; ++ } ++ ++ cmd[0] = CINERGYT2_EP1_GET_TUNER_STATUS; ++ ++ ret = dvb_usb_generic_rw(state->d, cmd, 1, (char *)status, ++ sizeof(*status), 0); + if (ret < 0) { + err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret); +- return ret; ++ goto out; + } +- *snr = (status.snr << 8) | status.snr; +- return 0; ++ *snr = (status->snr << 8) | status->snr; ++ ++out: ++ kfree(cmd); ++ kfree(status); ++ return ret; + } + + static int cinergyt2_fe_init(struct dvb_frontend *fe) +@@ -266,35 +339,46 @@ + { + struct dtv_frontend_properties *fep = &fe->dtv_property_cache; + struct cinergyt2_fe_state *state = fe->demodulator_priv; +- struct dvbt_set_parameters_msg param; +- char result[2]; ++ struct dvbt_set_parameters_msg *param; ++ char *result; + int err; + +- param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; +- param.tps = cpu_to_le16(compute_tps(fep)); +- param.freq = cpu_to_le32(fep->frequency / 1000); +- param.flags = 0; ++ result = kmalloc(2, GFP_KERNEL); ++ if (result == NULL) ++ return -ENOMEM; ++ param = kmalloc(sizeof(*param), GFP_KERNEL); ++ if (param == NULL) { ++ kfree(result); ++ return -ENOMEM; ++ } ++ ++ param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; ++ param->tps = cpu_to_le16(compute_tps(fep)); ++ param->freq = cpu_to_le32(fep->frequency / 1000); ++ param->flags = 0; + + switch (fep->bandwidth_hz) { + default: + case 8000000: +- param.bandwidth = 8; ++ param->bandwidth = 8; + break; + case 7000000: +- param.bandwidth = 7; ++ param->bandwidth = 7; + break; + case 6000000: +- param.bandwidth = 6; ++ param->bandwidth = 6; + break; + } + + err = dvb_usb_generic_rw(state->d, +- (char *)¶m, sizeof(param), +- result, sizeof(result), 0); ++ (char *)param, sizeof(*param), ++ result, 2, 0); + if (err < 0) + err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err); + +- return (err < 0) ? err : 0; ++ kfree(result); ++ kfree(param); ++ return err; + } + + static void cinergyt2_fe_release(struct dvb_frontend *fe) +diff -Naur backports-3.18.1-1.org/drivers/media/usb/dvb-usb/dvb-usb-firmware.c backports-3.18.1-1/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +--- backports-3.18.1-1.org/drivers/media/usb/dvb-usb/dvb-usb-firmware.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/usb/dvb-usb/dvb-usb-firmware.c 2014-12-28 14:10:09.532888798 +0100 +@@ -35,42 +35,57 @@ + + int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type) + { +- struct hexline hx; +- u8 reset; ++ struct hexline *hx; ++ u8 *reset; + int ret,pos=0; + ++ reset = kmalloc(1, GFP_KERNEL); ++ if (reset == NULL) ++ return -ENOMEM; ++ ++ hx = kmalloc(sizeof(struct hexline), GFP_KERNEL); ++ if (hx == NULL) { ++ kfree(reset); ++ return -ENOMEM; ++ } ++ + /* stop the CPU */ +- reset = 1; +- if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) ++ reset[0] = 1; ++ if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,reset,1)) != 1) + err("could not stop the USB controller CPU."); + +- while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) { +- deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk); +- ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len); ++ while ((ret = dvb_usb_get_hexline(fw,hx,&pos)) > 0) { ++ deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx->addr,hx->len,hx->chk); ++ ret = usb_cypress_writemem(udev,hx->addr,hx->data,hx->len); + +- if (ret != hx.len) { ++ if (ret != hx->len) { + err("error while transferring firmware " + "(transferred size: %d, block size: %d)", +- ret,hx.len); ++ ret,hx->len); + ret = -EINVAL; + break; + } + } + if (ret < 0) { + err("firmware download failed at %d with %d",pos,ret); ++ kfree(reset); ++ kfree(hx); + return ret; + } + + if (ret == 0) { + /* restart the CPU */ +- reset = 0; +- if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { ++ reset[0] = 0; ++ if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,reset,1) != 1) { + err("could not restart the USB controller CPU."); + ret = -EINVAL; + } + } else + ret = -EIO; + ++ kfree(reset); ++ kfree(hx); ++ + return ret; + } + EXPORT_SYMBOL(usb_cypress_load_firmware); +diff -Naur backports-3.18.1-1.org/drivers/media/usb/dvb-usb/dw2102.c backports-3.18.1-1/drivers/media/usb/dvb-usb/dw2102.c +--- backports-3.18.1-1.org/drivers/media/usb/dvb-usb/dw2102.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/usb/dvb-usb/dw2102.c 2014-12-28 14:10:09.536888811 +0100 +@@ -118,7 +118,7 @@ + + struct s6x0_state { + int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v); +-}; ++} __no_const; + + /* debug */ + static int dvb_usb_dw2102_debug; +diff -Naur backports-3.18.1-1.org/drivers/media/usb/dvb-usb/technisat-usb2.c backports-3.18.1-1/drivers/media/usb/dvb-usb/technisat-usb2.c +--- backports-3.18.1-1.org/drivers/media/usb/dvb-usb/technisat-usb2.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/usb/dvb-usb/technisat-usb2.c 2014-12-28 14:10:09.536888811 +0100 +@@ -87,8 +87,11 @@ + static int technisat_usb2_i2c_access(struct usb_device *udev, + u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen) + { +- u8 b[64]; +- int ret, actual_length; ++ u8 *b = kmalloc(64, GFP_KERNEL); ++ int ret, actual_length, error = 0; ++ ++ if (b == NULL) ++ return -ENOMEM; + + deb_i2c("i2c-access: %02x, tx: ", device_addr); + debug_dump(tx, txlen, deb_i2c); +@@ -121,7 +124,8 @@ + + if (ret < 0) { + err("i2c-error: out failed %02x = %d", device_addr, ret); +- return -ENODEV; ++ error = -ENODEV; ++ goto out; + } + + ret = usb_bulk_msg(udev, +@@ -129,7 +133,8 @@ + b, 64, &actual_length, 1000); + if (ret < 0) { + err("i2c-error: in failed %02x = %d", device_addr, ret); +- return -ENODEV; ++ error = -ENODEV; ++ goto out; + } + + if (b[0] != I2C_STATUS_OK) { +@@ -137,8 +142,10 @@ + /* handle tuner-i2c-nak */ + if (!(b[0] == I2C_STATUS_NAK && + device_addr == 0x60 +- /* && device_is_technisat_usb2 */)) +- return -ENODEV; ++ /* && device_is_technisat_usb2 */)) { ++ error = -ENODEV; ++ goto out; ++ } + } + + deb_i2c("status: %d, ", b[0]); +@@ -152,7 +159,9 @@ + + deb_i2c("\n"); + +- return 0; ++out: ++ kfree(b); ++ return error; + } + + static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, +@@ -224,14 +233,16 @@ + { + int ret; + +- u8 led[8] = { +- red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST, +- 0 +- }; ++ u8 *led = kzalloc(8, GFP_KERNEL); ++ ++ if (led == NULL) ++ return -ENOMEM; + + if (disable_led_control && state != TECH_LED_OFF) + return 0; + ++ led[0] = red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST; ++ + switch (state) { + case TECH_LED_ON: + led[1] = 0x82; +@@ -263,16 +274,22 @@ + red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST, + USB_TYPE_VENDOR | USB_DIR_OUT, + 0, 0, +- led, sizeof(led), 500); ++ led, 8, 500); + + mutex_unlock(&d->i2c_mutex); ++ ++ kfree(led); ++ + return ret; + } + + static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green) + { + int ret; +- u8 b = 0; ++ u8 *b = kzalloc(1, GFP_KERNEL); ++ ++ if (b == NULL) ++ return -ENOMEM; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; +@@ -281,10 +298,12 @@ + SET_LED_TIMER_DIVIDER_VENDOR_REQUEST, + USB_TYPE_VENDOR | USB_DIR_OUT, + (red << 8) | green, 0, +- &b, 1, 500); ++ b, 1, 500); + + mutex_unlock(&d->i2c_mutex); + ++ kfree(b); ++ + return ret; + } + +@@ -328,7 +347,7 @@ + struct dvb_usb_device_description **desc, int *cold) + { + int ret; +- u8 version[3]; ++ u8 *version = kmalloc(3, GFP_KERNEL); + + /* first select the interface */ + if (usb_set_interface(udev, 0, 1) != 0) +@@ -338,11 +357,14 @@ + + *cold = 0; /* by default do not download a firmware - just in case something is wrong */ + ++ if (version == NULL) ++ return 0; ++ + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + GET_VERSION_INFO_VENDOR_REQUEST, + USB_TYPE_VENDOR | USB_DIR_IN, + 0, 0, +- version, sizeof(version), 500); ++ version, 3, 500); + + if (ret < 0) + *cold = 1; +@@ -351,6 +373,8 @@ + *cold = 0; + } + ++ kfree(version); ++ + return 0; + } + +@@ -591,10 +615,15 @@ + + static int technisat_usb2_get_ir(struct dvb_usb_device *d) + { +- u8 buf[62], *b; ++ u8 *buf, *b; + int ret; + struct ir_raw_event ev; + ++ buf = kmalloc(62, GFP_KERNEL); ++ ++ if (buf == NULL) ++ return -ENOMEM; ++ + buf[0] = GET_IR_DATA_VENDOR_REQUEST; + buf[1] = 0x08; + buf[2] = 0x8f; +@@ -617,16 +646,20 @@ + GET_IR_DATA_VENDOR_REQUEST, + USB_TYPE_VENDOR | USB_DIR_IN, + 0x8080, 0, +- buf, sizeof(buf), 500); ++ buf, 62, 500); + + unlock: + mutex_unlock(&d->i2c_mutex); + +- if (ret < 0) ++ if (ret < 0) { ++ kfree(buf); + return ret; ++ } + +- if (ret == 1) ++ if (ret == 1) { ++ kfree(buf); + return 0; /* no key pressed */ ++ } + + /* decoding */ + b = buf+1; +@@ -653,6 +686,8 @@ + + ir_raw_event_handle(d->rc_dev); + ++ kfree(buf); ++ + return 1; + } + +diff -Naur backports-3.18.1-1.org/drivers/media/v4l2-core/v4l2-device.c backports-3.18.1-1/drivers/media/v4l2-core/v4l2-device.c +--- backports-3.18.1-1.org/drivers/media/v4l2-core/v4l2-device.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/v4l2-core/v4l2-device.c 2014-12-28 14:10:09.536888811 +0100 +@@ -75,9 +75,9 @@ + EXPORT_SYMBOL_GPL(v4l2_device_put); + + int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename, +- atomic_t *instance) ++ atomic_unchecked_t *instance) + { +- int num = atomic_inc_return(instance) - 1; ++ int num = atomic_inc_return_unchecked(instance) - 1; + int len = strlen(basename); + + if (basename[len - 1] >= '0' && basename[len - 1] <= '9') +diff -Naur backports-3.18.1-1.org/drivers/media/v4l2-core/v4l2-ioctl.c backports-3.18.1-1/drivers/media/v4l2-core/v4l2-ioctl.c +--- backports-3.18.1-1.org/drivers/media/v4l2-core/v4l2-ioctl.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/media/v4l2-core/v4l2-ioctl.c 2014-12-28 14:10:09.536888811 +0100 +@@ -2142,7 +2142,8 @@ + struct file *file, void *fh, void *p); + } u; + void (*debug)(const void *arg, bool write_only); +-}; ++} __do_const; ++typedef struct v4l2_ioctl_info __no_const v4l2_ioctl_info_no_const; + + /* This control needs a priority check */ + #define INFO_FL_PRIO (1 << 0) +@@ -2326,7 +2327,7 @@ + struct video_device *vfd = video_devdata(file); + const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; + bool write_only = false; +- struct v4l2_ioctl_info default_info; ++ v4l2_ioctl_info_no_const default_info; + const struct v4l2_ioctl_info *info; + void *fh = file->private_data; + struct v4l2_fh *vfh = NULL; +@@ -2413,7 +2414,7 @@ + ret = -EINVAL; + break; + } +- *user_ptr = (void __user *)buf->m.planes; ++ *user_ptr = (void __force_user *)buf->m.planes; + *kernel_ptr = (void **)&buf->m.planes; + *array_size = sizeof(struct v4l2_plane) * buf->length; + ret = 1; +@@ -2430,7 +2431,7 @@ + ret = -EINVAL; + break; + } +- *user_ptr = (void __user *)edid->edid; ++ *user_ptr = (void __force_user *)edid->edid; + *kernel_ptr = (void **)&edid->edid; + *array_size = edid->blocks * 128; + ret = 1; +@@ -2448,7 +2449,7 @@ + ret = -EINVAL; + break; + } +- *user_ptr = (void __user *)ctrls->controls; ++ *user_ptr = (void __force_user *)ctrls->controls; + *kernel_ptr = (void **)&ctrls->controls; + *array_size = sizeof(struct v4l2_ext_control) + * ctrls->count; +@@ -2549,7 +2550,7 @@ + } + + if (has_array_args) { +- *kernel_ptr = (void __force *)user_ptr; ++ *kernel_ptr = (void __force_kernel *)user_ptr; + if (copy_to_user(user_ptr, mbuf, array_size)) + err = -EFAULT; + goto out_array_args; +diff -Naur backports-3.18.1-1.org/drivers/net/ieee802154/fakehard.c backports-3.18.1-1/drivers/net/ieee802154/fakehard.c +--- backports-3.18.1-1.org/drivers/net/ieee802154/fakehard.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/ieee802154/fakehard.c 2014-12-28 14:10:09.556888909 +0100 +@@ -365,7 +365,7 @@ + phy->transmit_power = 0xbf; + + dev->netdev_ops = &fake_ops; +- dev->ml_priv = &fake_mlme; ++ dev->ml_priv = (void *)&fake_mlme; + + priv = netdev_priv(dev); + priv->phy = phy; +diff -Naur backports-3.18.1-1.org/drivers/net/usb/sierra_net.c backports-3.18.1-1/drivers/net/usb/sierra_net.c +--- backports-3.18.1-1.org/drivers/net/usb/sierra_net.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/usb/sierra_net.c 2014-12-28 14:10:09.560888936 +0100 +@@ -51,7 +51,7 @@ + /* atomic counter partially included in MAC address to make sure 2 devices + * do not end up with the same MAC - concept breaks in case of > 255 ifaces + */ +-static atomic_t iface_counter = ATOMIC_INIT(0); ++static atomic_unchecked_t iface_counter = ATOMIC_INIT(0); + + /* + * SYNC Timer Delay definition used to set the expiry time +@@ -697,7 +697,7 @@ + dev->net->netdev_ops = &sierra_net_device_ops; + + /* change MAC addr to include, ifacenum, and to be unique */ +- dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter); ++ dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return_unchecked(&iface_counter); + dev->net->dev_addr[ETH_ALEN-1] = ifacenum; + + /* we will have to manufacture ethernet headers, prepare template */ +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/at76c50x-usb.c backports-3.18.1-1/drivers/net/wireless/at76c50x-usb.c +--- backports-3.18.1-1.org/drivers/net/wireless/at76c50x-usb.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/at76c50x-usb.c 2014-12-28 14:10:09.560888936 +0100 +@@ -353,7 +353,7 @@ + } + + /* Convert timeout from the DFU status to jiffies */ +-static inline unsigned long at76_get_timeout(struct dfu_status *s) ++static inline unsigned long __intentional_overflow(-1) at76_get_timeout(struct dfu_status *s) + { + return msecs_to_jiffies((s->poll_timeout[2] << 16) + | (s->poll_timeout[1] << 8) +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath10k/htc.c backports-3.18.1-1/drivers/net/wireless/ath/ath10k/htc.c +--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath10k/htc.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/ath/ath10k/htc.c 2014-12-28 14:10:09.560888936 +0100 +@@ -848,7 +848,10 @@ + /* registered target arrival callback from the HIF layer */ + int ath10k_htc_init(struct ath10k *ar) + { +- struct ath10k_hif_cb htc_callbacks; ++ static struct ath10k_hif_cb htc_callbacks = { ++ .rx_completion = ath10k_htc_rx_completion_handler, ++ .tx_completion = ath10k_htc_tx_completion_handler, ++ }; + struct ath10k_htc_ep *ep = NULL; + struct ath10k_htc *htc = &ar->htc; + +@@ -857,8 +860,6 @@ + ath10k_htc_reset_endpoint_states(htc); + + /* setup HIF layer callbacks */ +- htc_callbacks.rx_completion = ath10k_htc_rx_completion_handler; +- htc_callbacks.tx_completion = ath10k_htc_tx_completion_handler; + htc->ar = ar; + + /* Get HIF default pipe for HTC message exchange */ +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath10k/htc.h backports-3.18.1-1/drivers/net/wireless/ath/ath10k/htc.h +--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath10k/htc.h 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/ath/ath10k/htc.h 2014-12-28 14:10:09.560888936 +0100 +@@ -270,13 +270,13 @@ + + struct ath10k_htc_ops { + void (*target_send_suspend_complete)(struct ath10k *ar); +-}; ++} __no_const; + + struct ath10k_htc_ep_ops { + void (*ep_tx_complete)(struct ath10k *, struct sk_buff *); + void (*ep_rx_complete)(struct ath10k *, struct sk_buff *); + void (*ep_tx_credits)(struct ath10k *); +-}; ++} __no_const; + + /* service connection information */ + struct ath10k_htc_svc_conn_req { +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/ar9002_mac.c backports-3.18.1-1/drivers/net/wireless/ath/ath9k/ar9002_mac.c +--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/ar9002_mac.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/ath/ath9k/ar9002_mac.c 2014-12-28 14:10:09.560888936 +0100 +@@ -220,8 +220,8 @@ + ads->ds_txstatus6 = ads->ds_txstatus7 = 0; + ads->ds_txstatus8 = ads->ds_txstatus9 = 0; + +- ACCESS_ONCE(ads->ds_link) = i->link; +- ACCESS_ONCE(ads->ds_data) = i->buf_addr[0]; ++ ACCESS_ONCE_RW(ads->ds_link) = i->link; ++ ACCESS_ONCE_RW(ads->ds_data) = i->buf_addr[0]; + + ctl1 = i->buf_len[0] | (i->is_last ? 0 : AR_TxMore); + ctl6 = SM(i->keytype, AR_EncrType); +@@ -235,26 +235,26 @@ + + if ((i->is_first || i->is_last) && + i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) { +- ACCESS_ONCE(ads->ds_ctl2) = set11nTries(i->rates, 0) ++ ACCESS_ONCE_RW(ads->ds_ctl2) = set11nTries(i->rates, 0) + | set11nTries(i->rates, 1) + | set11nTries(i->rates, 2) + | set11nTries(i->rates, 3) + | (i->dur_update ? AR_DurUpdateEna : 0) + | SM(0, AR_BurstDur); + +- ACCESS_ONCE(ads->ds_ctl3) = set11nRate(i->rates, 0) ++ ACCESS_ONCE_RW(ads->ds_ctl3) = set11nRate(i->rates, 0) + | set11nRate(i->rates, 1) + | set11nRate(i->rates, 2) + | set11nRate(i->rates, 3); + } else { +- ACCESS_ONCE(ads->ds_ctl2) = 0; +- ACCESS_ONCE(ads->ds_ctl3) = 0; ++ ACCESS_ONCE_RW(ads->ds_ctl2) = 0; ++ ACCESS_ONCE_RW(ads->ds_ctl3) = 0; + } + + if (!i->is_first) { +- ACCESS_ONCE(ads->ds_ctl0) = 0; +- ACCESS_ONCE(ads->ds_ctl1) = ctl1; +- ACCESS_ONCE(ads->ds_ctl6) = ctl6; ++ ACCESS_ONCE_RW(ads->ds_ctl0) = 0; ++ ACCESS_ONCE_RW(ads->ds_ctl1) = ctl1; ++ ACCESS_ONCE_RW(ads->ds_ctl6) = ctl6; + return; + } + +@@ -279,7 +279,7 @@ + break; + } + +- ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen) ++ ACCESS_ONCE_RW(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen) + | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) + | SM(i->txpower, AR_XmitPower0) + | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) +@@ -289,27 +289,27 @@ + | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable : + (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)); + +- ACCESS_ONCE(ads->ds_ctl1) = ctl1; +- ACCESS_ONCE(ads->ds_ctl6) = ctl6; ++ ACCESS_ONCE_RW(ads->ds_ctl1) = ctl1; ++ ACCESS_ONCE_RW(ads->ds_ctl6) = ctl6; + + if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST) + return; + +- ACCESS_ONCE(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0) ++ ACCESS_ONCE_RW(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0) + | set11nPktDurRTSCTS(i->rates, 1); + +- ACCESS_ONCE(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2) ++ ACCESS_ONCE_RW(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2) + | set11nPktDurRTSCTS(i->rates, 3); + +- ACCESS_ONCE(ads->ds_ctl7) = set11nRateFlags(i->rates, 0) ++ ACCESS_ONCE_RW(ads->ds_ctl7) = set11nRateFlags(i->rates, 0) + | set11nRateFlags(i->rates, 1) + | set11nRateFlags(i->rates, 2) + | set11nRateFlags(i->rates, 3) + | SM(i->rtscts_rate, AR_RTSCTSRate); + +- ACCESS_ONCE(ads->ds_ctl9) = SM(i->txpower, AR_XmitPower1); +- ACCESS_ONCE(ads->ds_ctl10) = SM(i->txpower, AR_XmitPower2); +- ACCESS_ONCE(ads->ds_ctl11) = SM(i->txpower, AR_XmitPower3); ++ ACCESS_ONCE_RW(ads->ds_ctl9) = SM(i->txpower, AR_XmitPower1); ++ ACCESS_ONCE_RW(ads->ds_ctl10) = SM(i->txpower, AR_XmitPower2); ++ ACCESS_ONCE_RW(ads->ds_ctl11) = SM(i->txpower, AR_XmitPower3); + } + + static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/ar9003_mac.c backports-3.18.1-1/drivers/net/wireless/ath/ath9k/ar9003_mac.c +--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/ar9003_mac.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/ath/ath9k/ar9003_mac.c 2014-12-28 14:10:09.560888936 +0100 +@@ -39,47 +39,47 @@ + (i->qcu << AR_TxQcuNum_S) | desc_len; + + checksum += val; +- ACCESS_ONCE(ads->info) = val; ++ ACCESS_ONCE_RW(ads->info) = val; + + checksum += i->link; +- ACCESS_ONCE(ads->link) = i->link; ++ ACCESS_ONCE_RW(ads->link) = i->link; + + checksum += i->buf_addr[0]; +- ACCESS_ONCE(ads->data0) = i->buf_addr[0]; ++ ACCESS_ONCE_RW(ads->data0) = i->buf_addr[0]; + checksum += i->buf_addr[1]; +- ACCESS_ONCE(ads->data1) = i->buf_addr[1]; ++ ACCESS_ONCE_RW(ads->data1) = i->buf_addr[1]; + checksum += i->buf_addr[2]; +- ACCESS_ONCE(ads->data2) = i->buf_addr[2]; ++ ACCESS_ONCE_RW(ads->data2) = i->buf_addr[2]; + checksum += i->buf_addr[3]; +- ACCESS_ONCE(ads->data3) = i->buf_addr[3]; ++ ACCESS_ONCE_RW(ads->data3) = i->buf_addr[3]; + + checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen); +- ACCESS_ONCE(ads->ctl3) = val; ++ ACCESS_ONCE_RW(ads->ctl3) = val; + checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen); +- ACCESS_ONCE(ads->ctl5) = val; ++ ACCESS_ONCE_RW(ads->ctl5) = val; + checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen); +- ACCESS_ONCE(ads->ctl7) = val; ++ ACCESS_ONCE_RW(ads->ctl7) = val; + checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen); +- ACCESS_ONCE(ads->ctl9) = val; ++ ACCESS_ONCE_RW(ads->ctl9) = val; + + checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff); +- ACCESS_ONCE(ads->ctl10) = checksum; ++ ACCESS_ONCE_RW(ads->ctl10) = checksum; + + if (i->is_first || i->is_last) { +- ACCESS_ONCE(ads->ctl13) = set11nTries(i->rates, 0) ++ ACCESS_ONCE_RW(ads->ctl13) = set11nTries(i->rates, 0) + | set11nTries(i->rates, 1) + | set11nTries(i->rates, 2) + | set11nTries(i->rates, 3) + | (i->dur_update ? AR_DurUpdateEna : 0) + | SM(0, AR_BurstDur); + +- ACCESS_ONCE(ads->ctl14) = set11nRate(i->rates, 0) ++ ACCESS_ONCE_RW(ads->ctl14) = set11nRate(i->rates, 0) + | set11nRate(i->rates, 1) + | set11nRate(i->rates, 2) + | set11nRate(i->rates, 3); + } else { +- ACCESS_ONCE(ads->ctl13) = 0; +- ACCESS_ONCE(ads->ctl14) = 0; ++ ACCESS_ONCE_RW(ads->ctl13) = 0; ++ ACCESS_ONCE_RW(ads->ctl14) = 0; + } + + ads->ctl20 = 0; +@@ -89,17 +89,17 @@ + + ctl17 = SM(i->keytype, AR_EncrType); + if (!i->is_first) { +- ACCESS_ONCE(ads->ctl11) = 0; +- ACCESS_ONCE(ads->ctl12) = i->is_last ? 0 : AR_TxMore; +- ACCESS_ONCE(ads->ctl15) = 0; +- ACCESS_ONCE(ads->ctl16) = 0; +- ACCESS_ONCE(ads->ctl17) = ctl17; +- ACCESS_ONCE(ads->ctl18) = 0; +- ACCESS_ONCE(ads->ctl19) = 0; ++ ACCESS_ONCE_RW(ads->ctl11) = 0; ++ ACCESS_ONCE_RW(ads->ctl12) = i->is_last ? 0 : AR_TxMore; ++ ACCESS_ONCE_RW(ads->ctl15) = 0; ++ ACCESS_ONCE_RW(ads->ctl16) = 0; ++ ACCESS_ONCE_RW(ads->ctl17) = ctl17; ++ ACCESS_ONCE_RW(ads->ctl18) = 0; ++ ACCESS_ONCE_RW(ads->ctl19) = 0; + return; + } + +- ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen) ++ ACCESS_ONCE_RW(ads->ctl11) = (i->pkt_len & AR_FrameLen) + | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) + | SM(i->txpower, AR_XmitPower0) + | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) +@@ -135,26 +135,26 @@ + val = (i->flags & ATH9K_TXDESC_PAPRD) >> ATH9K_TXDESC_PAPRD_S; + ctl12 |= SM(val, AR_PAPRDChainMask); + +- ACCESS_ONCE(ads->ctl12) = ctl12; +- ACCESS_ONCE(ads->ctl17) = ctl17; ++ ACCESS_ONCE_RW(ads->ctl12) = ctl12; ++ ACCESS_ONCE_RW(ads->ctl17) = ctl17; + +- ACCESS_ONCE(ads->ctl15) = set11nPktDurRTSCTS(i->rates, 0) ++ ACCESS_ONCE_RW(ads->ctl15) = set11nPktDurRTSCTS(i->rates, 0) + | set11nPktDurRTSCTS(i->rates, 1); + +- ACCESS_ONCE(ads->ctl16) = set11nPktDurRTSCTS(i->rates, 2) ++ ACCESS_ONCE_RW(ads->ctl16) = set11nPktDurRTSCTS(i->rates, 2) + | set11nPktDurRTSCTS(i->rates, 3); + +- ACCESS_ONCE(ads->ctl18) = set11nRateFlags(i->rates, 0) ++ ACCESS_ONCE_RW(ads->ctl18) = set11nRateFlags(i->rates, 0) + | set11nRateFlags(i->rates, 1) + | set11nRateFlags(i->rates, 2) + | set11nRateFlags(i->rates, 3) + | SM(i->rtscts_rate, AR_RTSCTSRate); + +- ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding; ++ ACCESS_ONCE_RW(ads->ctl19) = AR_Not_Sounding; + +- ACCESS_ONCE(ads->ctl20) = SM(i->txpower, AR_XmitPower1); +- ACCESS_ONCE(ads->ctl21) = SM(i->txpower, AR_XmitPower2); +- ACCESS_ONCE(ads->ctl22) = SM(i->txpower, AR_XmitPower3); ++ ACCESS_ONCE_RW(ads->ctl20) = SM(i->txpower, AR_XmitPower1); ++ ACCESS_ONCE_RW(ads->ctl21) = SM(i->txpower, AR_XmitPower2); ++ ACCESS_ONCE_RW(ads->ctl22) = SM(i->txpower, AR_XmitPower3); + } + + static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads) +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/hw.h backports-3.18.1-1/drivers/net/wireless/ath/ath9k/hw.h +--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/hw.h 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/ath/ath9k/hw.h 2014-12-28 14:10:09.564888946 +0100 +@@ -630,7 +630,7 @@ + + /* ANI */ + void (*ani_cache_ini_regs)(struct ath_hw *ah); +-}; ++} __no_const; + + /** + * struct ath_spec_scan - parameters for Atheros spectral scan +@@ -708,7 +708,7 @@ + #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT + void (*set_bt_ant_diversity)(struct ath_hw *hw, bool enable); + #endif +-}; ++} __no_const; + + struct ath_nf_limits { + s16 max; +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/main.c backports-3.18.1-1/drivers/net/wireless/ath/ath9k/main.c +--- backports-3.18.1-1.org/drivers/net/wireless/ath/ath9k/main.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/ath/ath9k/main.c 2014-12-28 14:24:49.169250593 +0100 +@@ -2454,16 +2454,18 @@ + if (!ath9k_is_chanctx_enabled()) + return; + +- ath9k_ops.hw_scan = ath9k_hw_scan; +- ath9k_ops.cancel_hw_scan = ath9k_cancel_hw_scan; +- ath9k_ops.remain_on_channel = ath9k_remain_on_channel; +- ath9k_ops.cancel_remain_on_channel = ath9k_cancel_remain_on_channel; +- ath9k_ops.add_chanctx = ath9k_add_chanctx; +- ath9k_ops.remove_chanctx = ath9k_remove_chanctx; +- ath9k_ops.change_chanctx = ath9k_change_chanctx; +- ath9k_ops.assign_vif_chanctx = ath9k_assign_vif_chanctx; +- ath9k_ops.unassign_vif_chanctx = ath9k_unassign_vif_chanctx; +- ath9k_ops.mgd_prepare_tx = ath9k_mgd_prepare_tx; ++ pax_open_kernel(); ++ *(void **)&ath9k_ops.hw_scan = ath9k_hw_scan; ++ *(void **)&ath9k_ops.cancel_hw_scan = ath9k_cancel_hw_scan; ++ *(void **)&ath9k_ops.remain_on_channel = ath9k_remain_on_channel; ++ *(void **)&ath9k_ops.cancel_remain_on_channel = ath9k_cancel_remain_on_channel; ++ *(void **)&ath9k_ops.add_chanctx = ath9k_add_chanctx; ++ *(void **)&ath9k_ops.remove_chanctx = ath9k_remove_chanctx; ++ *(void **)&ath9k_ops.change_chanctx = ath9k_change_chanctx; ++ *(void **)&ath9k_ops.assign_vif_chanctx = ath9k_assign_vif_chanctx; ++ *(void **)&ath9k_ops.unassign_vif_chanctx = ath9k_unassign_vif_chanctx; ++ *(void **)&ath9k_ops.mgd_prepare_tx = ath9k_mgd_prepare_tx; ++ pax_close_kernel(); + } + + #endif +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/b43/phy_lp.c backports-3.18.1-1/drivers/net/wireless/b43/phy_lp.c +--- backports-3.18.1-1.org/drivers/net/wireless/b43/phy_lp.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/b43/phy_lp.c 2014-12-28 14:10:09.564888946 +0100 +@@ -2502,7 +2502,7 @@ + { + struct ssb_bus *bus = dev->dev->sdev->bus; + +- static const struct b206x_channel *chandata = NULL; ++ const struct b206x_channel *chandata = NULL; + u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; + u32 freqref, vco_freq, val1, val2, val3, timeout, timeoutref, count; + u16 old_comm15, scale; +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/iwlegacy/3945-mac.c backports-3.18.1-1/drivers/net/wireless/iwlegacy/3945-mac.c +--- backports-3.18.1-1.org/drivers/net/wireless/iwlegacy/3945-mac.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/iwlegacy/3945-mac.c 2014-12-28 14:10:09.564888946 +0100 +@@ -3633,7 +3633,9 @@ + */ + if (il3945_mod_params.disable_hw_scan) { + D_INFO("Disabling hw_scan\n"); +- il3945_mac_ops.hw_scan = NULL; ++ pax_open_kernel(); ++ *(void **)&il3945_mac_ops.hw_scan = NULL; ++ pax_close_kernel(); + } + + D_INFO("*** LOAD DRIVER ***\n"); +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/iwlwifi/dvm/debugfs.c backports-3.18.1-1/drivers/net/wireless/iwlwifi/dvm/debugfs.c +--- backports-3.18.1-1.org/drivers/net/wireless/iwlwifi/dvm/debugfs.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/iwlwifi/dvm/debugfs.c 2014-12-28 14:10:09.564888946 +0100 +@@ -188,7 +188,7 @@ + { + struct iwl_priv *priv = file->private_data; + char buf[64]; +- int buf_size; ++ size_t buf_size; + u32 offset, len; + + memset(buf, 0, sizeof(buf)); +@@ -458,7 +458,7 @@ + struct iwl_priv *priv = file->private_data; + + char buf[8]; +- int buf_size; ++ size_t buf_size; + u32 reset_flag; + + memset(buf, 0, sizeof(buf)); +@@ -539,7 +539,7 @@ + { + struct iwl_priv *priv = file->private_data; + char buf[8]; +- int buf_size; ++ size_t buf_size; + int ht40; + + memset(buf, 0, sizeof(buf)); +@@ -591,7 +591,7 @@ + { + struct iwl_priv *priv = file->private_data; + char buf[8]; +- int buf_size; ++ size_t buf_size; + int value; + + memset(buf, 0, sizeof(buf)); +@@ -683,10 +683,10 @@ + DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); + DEBUGFS_READ_FILE_OPS(current_sleep_command); + +-static const char *fmt_value = " %-30s %10u\n"; +-static const char *fmt_hex = " %-30s 0x%02X\n"; +-static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; +-static const char *fmt_header = ++static const char fmt_value[] = " %-30s %10u\n"; ++static const char fmt_hex[] = " %-30s 0x%02X\n"; ++static const char fmt_table[] = " %-30s %10u %10u %10u %10u\n"; ++static const char fmt_header[] = + "%-32s current cumulative delta max\n"; + + static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) +@@ -1856,7 +1856,7 @@ + { + struct iwl_priv *priv = file->private_data; + char buf[8]; +- int buf_size; ++ size_t buf_size; + int clear; + + memset(buf, 0, sizeof(buf)); +@@ -1901,7 +1901,7 @@ + { + struct iwl_priv *priv = file->private_data; + char buf[8]; +- int buf_size; ++ size_t buf_size; + int trace; + + memset(buf, 0, sizeof(buf)); +@@ -1972,7 +1972,7 @@ + { + struct iwl_priv *priv = file->private_data; + char buf[8]; +- int buf_size; ++ size_t buf_size; + int missed; + + memset(buf, 0, sizeof(buf)); +@@ -2013,7 +2013,7 @@ + + struct iwl_priv *priv = file->private_data; + char buf[8]; +- int buf_size; ++ size_t buf_size; + int plcp; + + memset(buf, 0, sizeof(buf)); +@@ -2073,7 +2073,7 @@ + + struct iwl_priv *priv = file->private_data; + char buf[8]; +- int buf_size; ++ size_t buf_size; + int flush; + + memset(buf, 0, sizeof(buf)); +@@ -2163,7 +2163,7 @@ + + struct iwl_priv *priv = file->private_data; + char buf[8]; +- int buf_size; ++ size_t buf_size; + int rts; + + if (!priv->cfg->ht_params) +@@ -2204,7 +2204,7 @@ + { + struct iwl_priv *priv = file->private_data; + char buf[8]; +- int buf_size; ++ size_t buf_size; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); +@@ -2238,7 +2238,7 @@ + struct iwl_priv *priv = file->private_data; + u32 event_log_flag; + char buf[8]; +- int buf_size; ++ size_t buf_size; + + /* check that the interface is up */ + if (!iwl_is_ready(priv)) +@@ -2292,7 +2292,7 @@ + struct iwl_priv *priv = file->private_data; + char buf[8]; + u32 calib_disabled; +- int buf_size; ++ size_t buf_size; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/iwlwifi/pcie/trans.c backports-3.18.1-1/drivers/net/wireless/iwlwifi/pcie/trans.c +--- backports-3.18.1-1.org/drivers/net/wireless/iwlwifi/pcie/trans.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/iwlwifi/pcie/trans.c 2014-12-28 14:10:09.564888946 +0100 +@@ -1689,7 +1689,7 @@ + struct isr_statistics *isr_stats = &trans_pcie->isr_stats; + + char buf[8]; +- int buf_size; ++ size_t buf_size; + u32 reset_flag; + + memset(buf, 0, sizeof(buf)); +@@ -1710,7 +1710,7 @@ + { + struct iwl_trans *trans = file->private_data; + char buf[8]; +- int buf_size; ++ size_t buf_size; + int csr; + + memset(buf, 0, sizeof(buf)); +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/mac80211_hwsim.c backports-3.18.1-1/drivers/net/wireless/mac80211_hwsim.c +--- backports-3.18.1-1.org/drivers/net/wireless/mac80211_hwsim.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/mac80211_hwsim.c 2014-12-28 14:10:09.568888967 +0100 +@@ -2578,20 +2578,20 @@ + if (channels < 1) + return -EINVAL; + +- mac80211_hwsim_mchan_ops = mac80211_hwsim_ops; +- mac80211_hwsim_mchan_ops.hw_scan = mac80211_hwsim_hw_scan; +- mac80211_hwsim_mchan_ops.cancel_hw_scan = mac80211_hwsim_cancel_hw_scan; +- mac80211_hwsim_mchan_ops.sw_scan_start = NULL; +- mac80211_hwsim_mchan_ops.sw_scan_complete = NULL; +- mac80211_hwsim_mchan_ops.remain_on_channel = mac80211_hwsim_roc; +- mac80211_hwsim_mchan_ops.cancel_remain_on_channel = mac80211_hwsim_croc; +- mac80211_hwsim_mchan_ops.add_chanctx = mac80211_hwsim_add_chanctx; +- mac80211_hwsim_mchan_ops.remove_chanctx = mac80211_hwsim_remove_chanctx; +- mac80211_hwsim_mchan_ops.change_chanctx = mac80211_hwsim_change_chanctx; +- mac80211_hwsim_mchan_ops.assign_vif_chanctx = +- mac80211_hwsim_assign_vif_chanctx; +- mac80211_hwsim_mchan_ops.unassign_vif_chanctx = +- mac80211_hwsim_unassign_vif_chanctx; ++ pax_open_kernel(); ++ memcpy((void *)&mac80211_hwsim_mchan_ops, &mac80211_hwsim_ops, sizeof mac80211_hwsim_mchan_ops); ++ *(void **)&mac80211_hwsim_mchan_ops.hw_scan = mac80211_hwsim_hw_scan; ++ *(void **)&mac80211_hwsim_mchan_ops.cancel_hw_scan = mac80211_hwsim_cancel_hw_scan; ++ *(void **)&mac80211_hwsim_mchan_ops.sw_scan_start = NULL; ++ *(void **)&mac80211_hwsim_mchan_ops.sw_scan_complete = NULL; ++ *(void **)&mac80211_hwsim_mchan_ops.remain_on_channel = mac80211_hwsim_roc; ++ *(void **)&mac80211_hwsim_mchan_ops.cancel_remain_on_channel = mac80211_hwsim_croc; ++ *(void **)&mac80211_hwsim_mchan_ops.add_chanctx = mac80211_hwsim_add_chanctx; ++ *(void **)&mac80211_hwsim_mchan_ops.remove_chanctx = mac80211_hwsim_remove_chanctx; ++ *(void **)&mac80211_hwsim_mchan_ops.change_chanctx = mac80211_hwsim_change_chanctx; ++ *(void **)&mac80211_hwsim_mchan_ops.assign_vif_chanctx = mac80211_hwsim_assign_vif_chanctx; ++ *(void **)&mac80211_hwsim_mchan_ops.unassign_vif_chanctx = mac80211_hwsim_unassign_vif_chanctx; ++ pax_close_kernel(); + + spin_lock_init(&hwsim_radio_lock); + INIT_LIST_HEAD(&hwsim_radios); +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/rndis_wlan.c backports-3.18.1-1/drivers/net/wireless/rndis_wlan.c +--- backports-3.18.1-1.org/drivers/net/wireless/rndis_wlan.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/rndis_wlan.c 2014-12-28 14:10:09.568888967 +0100 +@@ -1236,7 +1236,7 @@ + + netdev_dbg(usbdev->net, "%s(): %i\n", __func__, rts_threshold); + +- if (rts_threshold < 0 || rts_threshold > 2347) ++ if (rts_threshold > 2347) + rts_threshold = 2347; + + tmp = cpu_to_le32(rts_threshold); +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/rt2x00/rt2x00.h backports-3.18.1-1/drivers/net/wireless/rt2x00/rt2x00.h +--- backports-3.18.1-1.org/drivers/net/wireless/rt2x00/rt2x00.h 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/rt2x00/rt2x00.h 2014-12-28 14:10:09.568888967 +0100 +@@ -375,7 +375,7 @@ + * for hardware which doesn't support hardware + * sequence counting. + */ +- atomic_t seqno; ++ atomic_unchecked_t seqno; + }; + + static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/rt2x00/rt2x00queue.c backports-3.18.1-1/drivers/net/wireless/rt2x00/rt2x00queue.c +--- backports-3.18.1-1.org/drivers/net/wireless/rt2x00/rt2x00queue.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/rt2x00/rt2x00queue.c 2014-12-28 14:10:09.568888967 +0100 +@@ -224,9 +224,9 @@ + * sequence counter given by mac80211. + */ + if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) +- seqno = atomic_add_return(0x10, &intf->seqno); ++ seqno = atomic_add_return_unchecked(0x10, &intf->seqno); + else +- seqno = atomic_read(&intf->seqno); ++ seqno = atomic_read_unchecked(&intf->seqno); + + hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); + hdr->seq_ctrl |= cpu_to_le16(seqno); +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ti/wl1251/sdio.c backports-3.18.1-1/drivers/net/wireless/ti/wl1251/sdio.c +--- backports-3.18.1-1.org/drivers/net/wireless/ti/wl1251/sdio.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/ti/wl1251/sdio.c 2014-12-28 14:10:09.568888967 +0100 +@@ -282,13 +282,17 @@ + + irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); + +- wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; +- wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; ++ pax_open_kernel(); ++ *(void **)&wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; ++ *(void **)&wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; ++ pax_close_kernel(); + + wl1251_info("using dedicated interrupt line"); + } else { +- wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq; +- wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq; ++ pax_open_kernel(); ++ *(void **)&wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq; ++ *(void **)&wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq; ++ pax_close_kernel(); + + wl1251_info("using SDIO interrupt"); + } +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ti/wl12xx/main.c backports-3.18.1-1/drivers/net/wireless/ti/wl12xx/main.c +--- backports-3.18.1-1.org/drivers/net/wireless/ti/wl12xx/main.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/ti/wl12xx/main.c 2014-12-28 14:10:09.568888967 +0100 +@@ -656,7 +656,9 @@ + sizeof(wl->conf.mem)); + + /* read data preparation is only needed by wl127x */ +- wl->ops->prepare_read = wl127x_prepare_read; ++ pax_open_kernel(); ++ *(void **)&wl->ops->prepare_read = wl127x_prepare_read; ++ pax_close_kernel(); + + wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, + WL127X_IFTYPE_SR_VER, WL127X_MAJOR_SR_VER, +@@ -681,7 +683,9 @@ + sizeof(wl->conf.mem)); + + /* read data preparation is only needed by wl127x */ +- wl->ops->prepare_read = wl127x_prepare_read; ++ pax_open_kernel(); ++ *(void **)&wl->ops->prepare_read = wl127x_prepare_read; ++ pax_close_kernel(); + + wlcore_set_min_fw_ver(wl, WL127X_CHIP_VER, + WL127X_IFTYPE_SR_VER, WL127X_MAJOR_SR_VER, +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/ti/wl18xx/main.c backports-3.18.1-1/drivers/net/wireless/ti/wl18xx/main.c +--- backports-3.18.1-1.org/drivers/net/wireless/ti/wl18xx/main.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/ti/wl18xx/main.c 2014-12-28 14:10:09.568888967 +0100 +@@ -1916,8 +1916,10 @@ + } + + if (!checksum_param) { +- wl18xx_ops.set_rx_csum = NULL; +- wl18xx_ops.init_vif = NULL; ++ pax_open_kernel(); ++ *(void **)&wl18xx_ops.set_rx_csum = NULL; ++ *(void **)&wl18xx_ops.init_vif = NULL; ++ pax_close_kernel(); + } + + /* Enable 11a Band only if we have 5G antennas */ +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/zd1211rw/zd_usb.c backports-3.18.1-1/drivers/net/wireless/zd1211rw/zd_usb.c +--- backports-3.18.1-1.org/drivers/net/wireless/zd1211rw/zd_usb.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/zd1211rw/zd_usb.c 2014-12-28 14:10:09.568888967 +0100 +@@ -385,7 +385,7 @@ + { + struct zd_usb *usb = urb->context; + struct zd_usb_interrupt *intr = &usb->intr; +- int len; ++ unsigned int len; + u16 int_num; + + ZD_ASSERT(in_interrupt()); +diff -Naur backports-3.18.1-1.org/drivers/nfc/nfcwilink.c backports-3.18.1-1/drivers/nfc/nfcwilink.c +--- backports-3.18.1-1.org/drivers/nfc/nfcwilink.c 2014-12-21 22:37:14.000000000 +0100 ++++ backports-3.18.1-1/drivers/nfc/nfcwilink.c 2014-12-28 14:10:09.568888967 +0100 +@@ -497,7 +497,7 @@ + + static int nfcwilink_probe(struct platform_device *pdev) + { +- static struct nfcwilink *drv; ++ struct nfcwilink *drv; + int rc; + __u32 protocols; + +diff -Naur backports-3.18.1-1.org/include/linux/gracl_compat.h backports-3.18.1-1/include/linux/gracl_compat.h +--- backports-3.18.1-1.org/include/linux/gracl_compat.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/include/linux/gracl_compat.h 2014-12-28 14:10:09.684889542 +0100 +@@ -0,0 +1,156 @@ ++#ifndef GR_ACL_COMPAT_H ++#define GR_ACL_COMPAT_H ++ ++#include <linux/resource.h> ++#include <asm/resource.h> ++ ++struct sprole_pw_compat { ++ compat_uptr_t rolename; ++ unsigned char salt[GR_SALT_LEN]; ++ unsigned char sum[GR_SHA_LEN]; ++}; ++ ++struct gr_hash_struct_compat { ++ compat_uptr_t table; ++ compat_uptr_t nametable; ++ compat_uptr_t first; ++ __u32 table_size; ++ __u32 used_size; ++ int type; ++}; ++ ++struct acl_subject_label_compat { ++ compat_uptr_t filename; ++ compat_ino_t inode; ++ __u32 device; ++ __u32 mode; ++ kernel_cap_t cap_mask; ++ kernel_cap_t cap_lower; ++ kernel_cap_t cap_invert_audit; ++ ++ struct compat_rlimit res[GR_NLIMITS]; ++ __u32 resmask; ++ ++ __u8 user_trans_type; ++ __u8 group_trans_type; ++ compat_uptr_t user_transitions; ++ compat_uptr_t group_transitions; ++ __u16 user_trans_num; ++ __u16 group_trans_num; ++ ++ __u32 sock_families[2]; ++ __u32 ip_proto[8]; ++ __u32 ip_type; ++ compat_uptr_t ips; ++ __u32 ip_num; ++ __u32 inaddr_any_override; ++ ++ __u32 crashes; ++ compat_ulong_t expires; ++ ++ compat_uptr_t parent_subject; ++ compat_uptr_t hash; ++ compat_uptr_t prev; ++ compat_uptr_t next; ++ ++ compat_uptr_t obj_hash; ++ __u32 obj_hash_size; ++ __u16 pax_flags; ++}; ++ ++struct role_allowed_ip_compat { ++ __u32 addr; ++ __u32 netmask; ++ ++ compat_uptr_t prev; ++ compat_uptr_t next; ++}; ++ ++struct role_transition_compat { ++ compat_uptr_t rolename; ++ ++ compat_uptr_t prev; ++ compat_uptr_t next; ++}; ++ ++struct acl_role_label_compat { ++ compat_uptr_t rolename; ++ uid_t uidgid; ++ __u16 roletype; ++ ++ __u16 auth_attempts; ++ compat_ulong_t expires; ++ ++ compat_uptr_t root_label; ++ compat_uptr_t hash; ++ ++ compat_uptr_t prev; ++ compat_uptr_t next; ++ ++ compat_uptr_t transitions; ++ compat_uptr_t allowed_ips; ++ compat_uptr_t domain_children; ++ __u16 domain_child_num; ++ ++ umode_t umask; ++ ++ compat_uptr_t subj_hash; ++ __u32 subj_hash_size; ++}; ++ ++struct user_acl_role_db_compat { ++ compat_uptr_t r_table; ++ __u32 num_pointers; ++ __u32 num_roles; ++ __u32 num_domain_children; ++ __u32 num_subjects; ++ __u32 num_objects; ++}; ++ ++struct acl_object_label_compat { ++ compat_uptr_t filename; ++ compat_ino_t inode; ++ __u32 device; ++ __u32 mode; ++ ++ compat_uptr_t nested; ++ compat_uptr_t globbed; ++ ++ compat_uptr_t prev; ++ compat_uptr_t next; ++}; ++ ++struct acl_ip_label_compat { ++ compat_uptr_t iface; ++ __u32 addr; ++ __u32 netmask; ++ __u16 low, high; ++ __u8 mode; ++ __u32 type; ++ __u32 proto[8]; ++ ++ compat_uptr_t prev; ++ compat_uptr_t next; ++}; ++ ++struct gr_arg_compat { ++ struct user_acl_role_db_compat role_db; ++ unsigned char pw[GR_PW_LEN]; ++ unsigned char salt[GR_SALT_LEN]; ++ unsigned char sum[GR_SHA_LEN]; ++ unsigned char sp_role[GR_SPROLE_LEN]; ++ compat_uptr_t sprole_pws; ++ __u32 segv_device; ++ compat_ino_t segv_inode; ++ uid_t segv_uid; ++ __u16 num_sprole_pws; ++ __u16 mode; ++}; ++ ++struct gr_arg_wrapper_compat { ++ compat_uptr_t arg; ++ __u32 version; ++ __u32 size; ++}; ++ ++#endif +diff -Naur backports-3.18.1-1.org/include/linux/gracl.h backports-3.18.1-1/include/linux/gracl.h +--- backports-3.18.1-1.org/include/linux/gracl.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/include/linux/gracl.h 2014-12-28 14:10:09.684889542 +0100 +@@ -0,0 +1,340 @@ ++#ifndef GR_ACL_H ++#define GR_ACL_H ++ ++#include <linux/grdefs.h> ++#include <linux/resource.h> ++#include <linux/capability.h> ++#include <linux/dcache.h> ++#include <asm/resource.h> ++ ++/* Major status information */ ++ ++#define GR_VERSION "grsecurity 3.0" ++#define GRSECURITY_VERSION 0x3000 ++ ++enum { ++ GR_SHUTDOWN = 0, ++ GR_ENABLE = 1, ++ GR_SPROLE = 2, ++ GR_OLDRELOAD = 3, ++ GR_SEGVMOD = 4, ++ GR_STATUS = 5, ++ GR_UNSPROLE = 6, ++ GR_PASSSET = 7, ++ GR_SPROLEPAM = 8, ++ GR_RELOAD = 9, ++}; ++ ++/* Password setup definitions ++ * kernel/grhash.c */ ++enum { ++ GR_PW_LEN = 128, ++ GR_SALT_LEN = 16, ++ GR_SHA_LEN = 32, ++}; ++ ++enum { ++ GR_SPROLE_LEN = 64, ++}; ++ ++enum { ++ GR_NO_GLOB = 0, ++ GR_REG_GLOB, ++ GR_CREATE_GLOB ++}; ++ ++#define GR_NLIMITS 32 ++ ++/* Begin Data Structures */ ++ ++struct sprole_pw { ++ unsigned char *rolename; ++ unsigned char salt[GR_SALT_LEN]; ++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */ ++}; ++ ++struct name_entry { ++ __u32 key; ++ ino_t inode; ++ dev_t device; ++ char *name; ++ __u16 len; ++ __u8 deleted; ++ struct name_entry *prev; ++ struct name_entry *next; ++}; ++ ++struct inodev_entry { ++ struct name_entry *nentry; ++ struct inodev_entry *prev; ++ struct inodev_entry *next; ++}; ++ ++struct acl_role_db { ++ struct acl_role_label **r_hash; ++ __u32 r_size; ++}; ++ ++struct inodev_db { ++ struct inodev_entry **i_hash; ++ __u32 i_size; ++}; ++ ++struct name_db { ++ struct name_entry **n_hash; ++ __u32 n_size; ++}; ++ ++struct crash_uid { ++ uid_t uid; ++ unsigned long expires; ++}; ++ ++struct gr_hash_struct { ++ void **table; ++ void **nametable; ++ void *first; ++ __u32 table_size; ++ __u32 used_size; ++ int type; ++}; ++ ++/* Userspace Grsecurity ACL data structures */ ++ ++struct acl_subject_label { ++ char *filename; ++ ino_t inode; ++ dev_t device; ++ __u32 mode; ++ kernel_cap_t cap_mask; ++ kernel_cap_t cap_lower; ++ kernel_cap_t cap_invert_audit; ++ ++ struct rlimit res[GR_NLIMITS]; ++ __u32 resmask; ++ ++ __u8 user_trans_type; ++ __u8 group_trans_type; ++ uid_t *user_transitions; ++ gid_t *group_transitions; ++ __u16 user_trans_num; ++ __u16 group_trans_num; ++ ++ __u32 sock_families[2]; ++ __u32 ip_proto[8]; ++ __u32 ip_type; ++ struct acl_ip_label **ips; ++ __u32 ip_num; ++ __u32 inaddr_any_override; ++ ++ __u32 crashes; ++ unsigned long expires; ++ ++ struct acl_subject_label *parent_subject; ++ struct gr_hash_struct *hash; ++ struct acl_subject_label *prev; ++ struct acl_subject_label *next; ++ ++ struct acl_object_label **obj_hash; ++ __u32 obj_hash_size; ++ __u16 pax_flags; ++}; ++ ++struct role_allowed_ip { ++ __u32 addr; ++ __u32 netmask; ++ ++ struct role_allowed_ip *prev; ++ struct role_allowed_ip *next; ++}; ++ ++struct role_transition { ++ char *rolename; ++ ++ struct role_transition *prev; ++ struct role_transition *next; ++}; ++ ++struct acl_role_label { ++ char *rolename; ++ uid_t uidgid; ++ __u16 roletype; ++ ++ __u16 auth_attempts; ++ unsigned long expires; ++ ++ struct acl_subject_label *root_label; ++ struct gr_hash_struct *hash; ++ ++ struct acl_role_label *prev; ++ struct acl_role_label *next; ++ ++ struct role_transition *transitions; ++ struct role_allowed_ip *allowed_ips; ++ uid_t *domain_children; ++ __u16 domain_child_num; ++ ++ umode_t umask; ++ ++ struct acl_subject_label **subj_hash; ++ __u32 subj_hash_size; ++}; ++ ++struct user_acl_role_db { ++ struct acl_role_label **r_table; ++ __u32 num_pointers; /* Number of allocations to track */ ++ __u32 num_roles; /* Number of roles */ ++ __u32 num_domain_children; /* Number of domain children */ ++ __u32 num_subjects; /* Number of subjects */ ++ __u32 num_objects; /* Number of objects */ ++}; ++ ++struct acl_object_label { ++ char *filename; ++ ino_t inode; ++ dev_t device; ++ __u32 mode; ++ ++ struct acl_subject_label *nested; ++ struct acl_object_label *globbed; ++ ++ /* next two structures not used */ ++ ++ struct acl_object_label *prev; ++ struct acl_object_label *next; ++}; ++ ++struct acl_ip_label { ++ char *iface; ++ __u32 addr; ++ __u32 netmask; ++ __u16 low, high; ++ __u8 mode; ++ __u32 type; ++ __u32 proto[8]; ++ ++ /* next two structures not used */ ++ ++ struct acl_ip_label *prev; ++ struct acl_ip_label *next; ++}; ++ ++struct gr_arg { ++ struct user_acl_role_db role_db; ++ unsigned char pw[GR_PW_LEN]; ++ unsigned char salt[GR_SALT_LEN]; ++ unsigned char sum[GR_SHA_LEN]; ++ unsigned char sp_role[GR_SPROLE_LEN]; ++ struct sprole_pw *sprole_pws; ++ dev_t segv_device; ++ ino_t segv_inode; ++ uid_t segv_uid; ++ __u16 num_sprole_pws; ++ __u16 mode; ++}; ++ ++struct gr_arg_wrapper { ++ struct gr_arg *arg; ++ __u32 version; ++ __u32 size; ++}; ++ ++struct subject_map { ++ struct acl_subject_label *user; ++ struct acl_subject_label *kernel; ++ struct subject_map *prev; ++ struct subject_map *next; ++}; ++ ++struct acl_subj_map_db { ++ struct subject_map **s_hash; ++ __u32 s_size; ++}; ++ ++struct gr_policy_state { ++ struct sprole_pw **acl_special_roles; ++ __u16 num_sprole_pws; ++ struct acl_role_label *kernel_role; ++ struct acl_role_label *role_list; ++ struct acl_role_label *default_role; ++ struct acl_role_db acl_role_set; ++ struct acl_subj_map_db subj_map_set; ++ struct name_db name_set; ++ struct inodev_db inodev_set; ++}; ++ ++struct gr_alloc_state { ++ unsigned long alloc_stack_next; ++ unsigned long alloc_stack_size; ++ void **alloc_stack; ++}; ++ ++struct gr_reload_state { ++ struct gr_policy_state oldpolicy; ++ struct gr_alloc_state oldalloc; ++ struct gr_policy_state newpolicy; ++ struct gr_alloc_state newalloc; ++ struct gr_policy_state *oldpolicy_ptr; ++ struct gr_alloc_state *oldalloc_ptr; ++ unsigned char oldmode; ++}; ++ ++/* End Data Structures Section */ ++ ++/* Hash functions generated by empirical testing by Brad Spengler ++ Makes good use of the low bits of the inode. Generally 0-1 times ++ in loop for successful match. 0-3 for unsuccessful match. ++ Shift/add algorithm with modulus of table size and an XOR*/ ++ ++static __inline__ unsigned int ++gr_rhash(const uid_t uid, const __u16 type, const unsigned int sz) ++{ ++ return ((((uid + type) << (16 + type)) ^ uid) % sz); ++} ++ ++ static __inline__ unsigned int ++gr_shash(const struct acl_subject_label *userp, const unsigned int sz) ++{ ++ return ((const unsigned long)userp % sz); ++} ++ ++static __inline__ unsigned int ++gr_fhash(const ino_t ino, const dev_t dev, const unsigned int sz) ++{ ++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz); ++} ++ ++static __inline__ unsigned int ++gr_nhash(const char *name, const __u16 len, const unsigned int sz) ++{ ++ return full_name_hash((const unsigned char *)name, len) % sz; ++} ++ ++#define FOR_EACH_SUBJECT_START(role,subj,iter) \ ++ subj = NULL; \ ++ iter = 0; \ ++ while (iter < role->subj_hash_size) { \ ++ if (subj == NULL) \ ++ subj = role->subj_hash[iter]; \ ++ if (subj == NULL) { \ ++ iter++; \ ++ continue; \ ++ } ++ ++#define FOR_EACH_SUBJECT_END(subj,iter) \ ++ subj = subj->next; \ ++ if (subj == NULL) \ ++ iter++; \ ++ } ++ ++ ++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \ ++ subj = role->hash->first; \ ++ while (subj != NULL) { ++ ++#define FOR_EACH_NESTED_SUBJECT_END(subj) \ ++ subj = subj->next; \ ++ } ++ ++#endif ++ +diff -Naur backports-3.18.1-1.org/include/linux/gralloc.h backports-3.18.1-1/include/linux/gralloc.h +--- backports-3.18.1-1.org/include/linux/gralloc.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/include/linux/gralloc.h 2014-12-28 14:10:09.684889542 +0100 +@@ -0,0 +1,9 @@ ++#ifndef __GRALLOC_H ++#define __GRALLOC_H ++ ++void acl_free_all(void); ++int acl_alloc_stack_init(unsigned long size); ++void *acl_alloc(unsigned long len); ++void *acl_alloc_num(unsigned long num, unsigned long len); ++ ++#endif +diff -Naur backports-3.18.1-1.org/include/linux/grdefs.h backports-3.18.1-1/include/linux/grdefs.h +--- backports-3.18.1-1.org/include/linux/grdefs.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/include/linux/grdefs.h 2014-12-28 14:10:09.688889562 +0100 +@@ -0,0 +1,140 @@ ++#ifndef GRDEFS_H ++#define GRDEFS_H ++ ++/* Begin grsecurity status declarations */ ++ ++enum { ++ GR_READY = 0x01, ++ GR_STATUS_INIT = 0x00 // disabled state ++}; ++ ++/* Begin ACL declarations */ ++ ++/* Role flags */ ++ ++enum { ++ GR_ROLE_USER = 0x0001, ++ GR_ROLE_GROUP = 0x0002, ++ GR_ROLE_DEFAULT = 0x0004, ++ GR_ROLE_SPECIAL = 0x0008, ++ GR_ROLE_AUTH = 0x0010, ++ GR_ROLE_NOPW = 0x0020, ++ GR_ROLE_GOD = 0x0040, ++ GR_ROLE_LEARN = 0x0080, ++ GR_ROLE_TPE = 0x0100, ++ GR_ROLE_DOMAIN = 0x0200, ++ GR_ROLE_PAM = 0x0400, ++ GR_ROLE_PERSIST = 0x0800 ++}; ++ ++/* ACL Subject and Object mode flags */ ++enum { ++ GR_DELETED = 0x80000000 ++}; ++ ++/* ACL Object-only mode flags */ ++enum { ++ GR_READ = 0x00000001, ++ GR_APPEND = 0x00000002, ++ GR_WRITE = 0x00000004, ++ GR_EXEC = 0x00000008, ++ GR_FIND = 0x00000010, ++ GR_INHERIT = 0x00000020, ++ GR_SETID = 0x00000040, ++ GR_CREATE = 0x00000080, ++ GR_DELETE = 0x00000100, ++ GR_LINK = 0x00000200, ++ GR_AUDIT_READ = 0x00000400, ++ GR_AUDIT_APPEND = 0x00000800, ++ GR_AUDIT_WRITE = 0x00001000, ++ GR_AUDIT_EXEC = 0x00002000, ++ GR_AUDIT_FIND = 0x00004000, ++ GR_AUDIT_INHERIT= 0x00008000, ++ GR_AUDIT_SETID = 0x00010000, ++ GR_AUDIT_CREATE = 0x00020000, ++ GR_AUDIT_DELETE = 0x00040000, ++ GR_AUDIT_LINK = 0x00080000, ++ GR_PTRACERD = 0x00100000, ++ GR_NOPTRACE = 0x00200000, ++ GR_SUPPRESS = 0x00400000, ++ GR_NOLEARN = 0x00800000, ++ GR_INIT_TRANSFER= 0x01000000 ++}; ++ ++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \ ++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \ ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK) ++ ++/* ACL subject-only mode flags */ ++enum { ++ GR_KILL = 0x00000001, ++ GR_VIEW = 0x00000002, ++ GR_PROTECTED = 0x00000004, ++ GR_LEARN = 0x00000008, ++ GR_OVERRIDE = 0x00000010, ++ /* just a placeholder, this mode is only used in userspace */ ++ GR_DUMMY = 0x00000020, ++ GR_PROTSHM = 0x00000040, ++ GR_KILLPROC = 0x00000080, ++ GR_KILLIPPROC = 0x00000100, ++ /* just a placeholder, this mode is only used in userspace */ ++ GR_NOTROJAN = 0x00000200, ++ GR_PROTPROCFD = 0x00000400, ++ GR_PROCACCT = 0x00000800, ++ GR_RELAXPTRACE = 0x00001000, ++ //GR_NESTED = 0x00002000, ++ GR_INHERITLEARN = 0x00004000, ++ GR_PROCFIND = 0x00008000, ++ GR_POVERRIDE = 0x00010000, ++ GR_KERNELAUTH = 0x00020000, ++ GR_ATSECURE = 0x00040000, ++ GR_SHMEXEC = 0x00080000 ++}; ++ ++enum { ++ GR_PAX_ENABLE_SEGMEXEC = 0x0001, ++ GR_PAX_ENABLE_PAGEEXEC = 0x0002, ++ GR_PAX_ENABLE_MPROTECT = 0x0004, ++ GR_PAX_ENABLE_RANDMMAP = 0x0008, ++ GR_PAX_ENABLE_EMUTRAMP = 0x0010, ++ GR_PAX_DISABLE_SEGMEXEC = 0x0100, ++ GR_PAX_DISABLE_PAGEEXEC = 0x0200, ++ GR_PAX_DISABLE_MPROTECT = 0x0400, ++ GR_PAX_DISABLE_RANDMMAP = 0x0800, ++ GR_PAX_DISABLE_EMUTRAMP = 0x1000, ++}; ++ ++enum { ++ GR_ID_USER = 0x01, ++ GR_ID_GROUP = 0x02, ++}; ++ ++enum { ++ GR_ID_ALLOW = 0x01, ++ GR_ID_DENY = 0x02, ++}; ++ ++#define GR_CRASH_RES 31 ++#define GR_UIDTABLE_MAX 500 ++ ++/* begin resource learning section */ ++enum { ++ GR_RLIM_CPU_BUMP = 60, ++ GR_RLIM_FSIZE_BUMP = 50000, ++ GR_RLIM_DATA_BUMP = 10000, ++ GR_RLIM_STACK_BUMP = 1000, ++ GR_RLIM_CORE_BUMP = 10000, ++ GR_RLIM_RSS_BUMP = 500000, ++ GR_RLIM_NPROC_BUMP = 1, ++ GR_RLIM_NOFILE_BUMP = 5, ++ GR_RLIM_MEMLOCK_BUMP = 50000, ++ GR_RLIM_AS_BUMP = 500000, ++ GR_RLIM_LOCKS_BUMP = 2, ++ GR_RLIM_SIGPENDING_BUMP = 5, ++ GR_RLIM_MSGQUEUE_BUMP = 10000, ++ GR_RLIM_NICE_BUMP = 1, ++ GR_RLIM_RTPRIO_BUMP = 1, ++ GR_RLIM_RTTIME_BUMP = 1000000 ++}; ++ ++#endif +diff -Naur backports-3.18.1-1.org/include/linux/grinternal.h backports-3.18.1-1/include/linux/grinternal.h +--- backports-3.18.1-1.org/include/linux/grinternal.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/include/linux/grinternal.h 2014-12-28 14:10:09.688889562 +0100 +@@ -0,0 +1,229 @@ ++#ifndef __GRINTERNAL_H ++#define __GRINTERNAL_H ++ ++#ifdef CONFIG_GRKERNSEC ++ ++#include <linux/fs.h> ++#include <linux/mnt_namespace.h> ++#include <linux/nsproxy.h> ++#include <linux/gracl.h> ++#include <linux/grdefs.h> ++#include <linux/grmsg.h> ++ ++void gr_add_learn_entry(const char *fmt, ...) ++ __attribute__ ((format (printf, 1, 2))); ++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode, ++ const struct vfsmount *mnt); ++__u32 gr_check_create(const struct dentry *new_dentry, ++ const struct dentry *parent, ++ const struct vfsmount *mnt, const __u32 mode); ++int gr_check_protected_task(const struct task_struct *task); ++__u32 to_gr_audit(const __u32 reqmode); ++int gr_set_acls(const int type); ++int gr_acl_is_enabled(void); ++char gr_roletype_to_char(void); ++ ++void gr_handle_alertkill(struct task_struct *task); ++char *gr_to_filename(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++char *gr_to_filename1(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++char *gr_to_filename2(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++char *gr_to_filename3(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++ ++extern int grsec_enable_ptrace_readexec; ++extern int grsec_enable_harden_ptrace; ++extern int grsec_enable_link; ++extern int grsec_enable_fifo; ++extern int grsec_enable_execve; ++extern int grsec_enable_shm; ++extern int grsec_enable_execlog; ++extern int grsec_enable_signal; ++extern int grsec_enable_audit_ptrace; ++extern int grsec_enable_forkfail; ++extern int grsec_enable_time; ++extern int grsec_enable_rofs; ++extern int grsec_deny_new_usb; ++extern int grsec_enable_chroot_shmat; ++extern int grsec_enable_chroot_mount; ++extern int grsec_enable_chroot_double; ++extern int grsec_enable_chroot_pivot; ++extern int grsec_enable_chroot_chdir; ++extern int grsec_enable_chroot_chmod; ++extern int grsec_enable_chroot_mknod; ++extern int grsec_enable_chroot_fchdir; ++extern int grsec_enable_chroot_nice; ++extern int grsec_enable_chroot_execlog; ++extern int grsec_enable_chroot_caps; ++extern int grsec_enable_chroot_sysctl; ++extern int grsec_enable_chroot_unix; ++extern int grsec_enable_symlinkown; ++extern kgid_t grsec_symlinkown_gid; ++extern int grsec_enable_tpe; ++extern kgid_t grsec_tpe_gid; ++extern int grsec_enable_tpe_all; ++extern int grsec_enable_tpe_invert; ++extern int grsec_enable_socket_all; ++extern kgid_t grsec_socket_all_gid; ++extern int grsec_enable_socket_client; ++extern kgid_t grsec_socket_client_gid; ++extern int grsec_enable_socket_server; ++extern kgid_t grsec_socket_server_gid; ++extern kgid_t grsec_audit_gid; ++extern int grsec_enable_group; ++extern int grsec_enable_log_rwxmaps; ++extern int grsec_enable_mount; ++extern int grsec_enable_chdir; ++extern int grsec_resource_logging; ++extern int grsec_enable_blackhole; ++extern int grsec_lastack_retries; ++extern int grsec_enable_brute; ++extern int grsec_enable_harden_ipc; ++extern int grsec_lock; ++ ++extern spinlock_t grsec_alert_lock; ++extern unsigned long grsec_alert_wtime; ++extern unsigned long grsec_alert_fyet; ++ ++extern spinlock_t grsec_audit_lock; ++ ++extern rwlock_t grsec_exec_file_lock; ++ ++#define gr_task_fullpath(tsk) ((tsk)->exec_file ? \ ++ gr_to_filename2((tsk)->exec_file->f_path.dentry, \ ++ (tsk)->exec_file->f_path.mnt) : "/") ++ ++#define gr_parent_task_fullpath(tsk) ((tsk)->real_parent->exec_file ? \ ++ gr_to_filename3((tsk)->real_parent->exec_file->f_path.dentry, \ ++ (tsk)->real_parent->exec_file->f_path.mnt) : "/") ++ ++#define gr_task_fullpath0(tsk) ((tsk)->exec_file ? \ ++ gr_to_filename((tsk)->exec_file->f_path.dentry, \ ++ (tsk)->exec_file->f_path.mnt) : "/") ++ ++#define gr_parent_task_fullpath0(tsk) ((tsk)->real_parent->exec_file ? \ ++ gr_to_filename1((tsk)->real_parent->exec_file->f_path.dentry, \ ++ (tsk)->real_parent->exec_file->f_path.mnt) : "/") ++ ++#define proc_is_chrooted(tsk_a) ((tsk_a)->gr_is_chrooted) ++ ++#define have_same_root(tsk_a,tsk_b) ((tsk_a)->gr_chroot_dentry == (tsk_b)->gr_chroot_dentry) ++ ++static inline bool gr_is_same_file(const struct file *file1, const struct file *file2) ++{ ++ if (file1 && file2) { ++ const struct inode *inode1 = file1->f_path.dentry->d_inode; ++ const struct inode *inode2 = file2->f_path.dentry->d_inode; ++ if (inode1->i_ino == inode2->i_ino && inode1->i_sb->s_dev == inode2->i_sb->s_dev) ++ return true; ++ } ++ ++ return false; ++} ++ ++#define GR_CHROOT_CAPS {{ \ ++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \ ++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \ ++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \ ++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \ ++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \ ++ CAP_TO_MASK(CAP_IPC_OWNER) | CAP_TO_MASK(CAP_SETFCAP), \ ++ CAP_TO_MASK(CAP_SYSLOG) | CAP_TO_MASK(CAP_MAC_ADMIN) }} ++ ++#define security_learn(normal_msg,args...) \ ++({ \ ++ read_lock(&grsec_exec_file_lock); \ ++ gr_add_learn_entry(normal_msg "\n", ## args); \ ++ read_unlock(&grsec_exec_file_lock); \ ++}) ++ ++enum { ++ GR_DO_AUDIT, ++ GR_DONT_AUDIT, ++ /* used for non-audit messages that we shouldn't kill the task on */ ++ GR_DONT_AUDIT_GOOD ++}; ++ ++enum { ++ GR_TTYSNIFF, ++ GR_RBAC, ++ GR_RBAC_STR, ++ GR_STR_RBAC, ++ GR_RBAC_MODE2, ++ GR_RBAC_MODE3, ++ GR_FILENAME, ++ GR_SYSCTL_HIDDEN, ++ GR_NOARGS, ++ GR_ONE_INT, ++ GR_ONE_INT_TWO_STR, ++ GR_ONE_STR, ++ GR_STR_INT, ++ GR_TWO_STR_INT, ++ GR_TWO_INT, ++ GR_TWO_U64, ++ GR_THREE_INT, ++ GR_FIVE_INT_TWO_STR, ++ GR_TWO_STR, ++ GR_THREE_STR, ++ GR_FOUR_STR, ++ GR_STR_FILENAME, ++ GR_FILENAME_STR, ++ GR_FILENAME_TWO_INT, ++ GR_FILENAME_TWO_INT_STR, ++ GR_TEXTREL, ++ GR_PTRACE, ++ GR_RESOURCE, ++ GR_CAP, ++ GR_SIG, ++ GR_SIG2, ++ GR_CRASH1, ++ GR_CRASH2, ++ GR_PSACCT, ++ GR_RWXMAP, ++ GR_RWXMAPVMA ++}; ++ ++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str) ++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task) ++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt) ++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str) ++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt) ++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2) ++#define gr_log_fs_rbac_mode3(audit, msg, dentry, mnt, str1, str2, str3) gr_log_varargs(audit, msg, GR_RBAC_MODE3, dentry, mnt, str1, str2, str3) ++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt) ++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS) ++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num) ++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2) ++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str) ++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num) ++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2) ++#define gr_log_two_u64(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_U64, num1, num2) ++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3) ++#define gr_log_int5_str2(audit, msg, num1, num2, str1, str2) gr_log_varargs(audit, msg, GR_FIVE_INT_TWO_STR, num1, num2, str1, str2) ++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2) ++#define gr_log_str2_int(audit, msg, str1, str2, num) gr_log_varargs(audit, msg, GR_TWO_STR_INT, str1, str2, num) ++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3) ++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4) ++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt) ++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str) ++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2) ++#define gr_log_fs_int2_str(audit, msg, dentry, mnt, num1, num2, str) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT_STR, dentry, mnt, num1, num2, str) ++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2) ++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task) ++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2) ++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str) ++#define gr_log_sig_addr(audit, msg, str, addr) gr_log_varargs(audit, msg, GR_SIG, str, addr) ++#define gr_log_sig_task(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG2, task, num) ++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong) ++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1) ++#define gr_log_procacct(audit, msg, task, num1, num2, num3, num4, num5, num6, num7, num8, num9) gr_log_varargs(audit, msg, GR_PSACCT, task, num1, num2, num3, num4, num5, num6, num7, num8, num9) ++#define gr_log_rwxmap(audit, msg, str) gr_log_varargs(audit, msg, GR_RWXMAP, str) ++#define gr_log_rwxmap_vma(audit, msg, str) gr_log_varargs(audit, msg, GR_RWXMAPVMA, str) ++ ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...); ++ ++#endif ++ ++#endif +diff -Naur backports-3.18.1-1.org/include/linux/grmsg.h backports-3.18.1-1/include/linux/grmsg.h +--- backports-3.18.1-1.org/include/linux/grmsg.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/include/linux/grmsg.h 2014-12-28 14:10:09.688889562 +0100 +@@ -0,0 +1,117 @@ ++#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u" ++#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u" ++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " ++#define GR_STOPMOD_MSG "denied modification of module state by " ++#define GR_ROFS_BLOCKWRITE_MSG "denied write to block device %.950s by " ++#define GR_ROFS_MOUNT_MSG "denied writable mount of %.950s by " ++#define GR_IOPERM_MSG "denied use of ioperm() by " ++#define GR_IOPL_MSG "denied use of iopl() by " ++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " ++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by " ++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " ++#define GR_MEM_READWRITE_MSG "denied access of range %Lx -> %Lx in /dev/mem by " ++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " ++#define GR_LEARN_AUDIT_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%lu\t%lu\t%.4095s\t%lu\t%pI4" ++#define GR_ID_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%c\t%d\t%d\t%d\t%pI4" ++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " ++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " ++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " ++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " ++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by " ++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " ++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by " ++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%pI4 %.480s[%.16s:%d], parent %.480s[%.16s:%d] against " ++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " ++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " ++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " ++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " ++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " ++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " ++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " ++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " ++#define GR_UNSAFESHARE_EXEC_ACL_MSG "denied exec with cloned fs of %.950s by " ++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " ++#define GR_EXEC_ACL_MSG "%s execution of %.950s by " ++#define GR_EXEC_TPE_MSG "denied untrusted exec (due to %.70s) of %.950s by " ++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds" ++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds" ++#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by " ++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by " ++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " ++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " ++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " ++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by " ++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by " ++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " ++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by " ++#define GR_CHROOT_FHANDLE_MSG "denied use of file handles inside chroot by " ++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " ++#define GR_SETXATTR_ACL_MSG "%s setting extended attribute of %.950s by " ++#define GR_REMOVEXATTR_ACL_MSG "%s removing extended attribute of %.950s by " ++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " ++#define GR_INITF_ACL_MSG "init_variables() failed %s by " ++#define GR_DISABLED_ACL_MSG "Error loading %s, trying to run kernel with acls disabled. To disable acls at startup use <kernel image name> gracl=off from your boot loader" ++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbage by " ++#define GR_SHUTS_ACL_MSG "shutdown auth success for " ++#define GR_SHUTF_ACL_MSG "shutdown auth failure for " ++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " ++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " ++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " ++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " ++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by " ++#define GR_ENABLEF_ACL_MSG "unable to load %s for " ++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system" ++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by " ++#define GR_RELOADF_ACL_MSG "failed reload of %s for " ++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for " ++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " ++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " ++#define GR_SPROLEF_ACL_MSG "special role %s failure for " ++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for " ++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " ++#define GR_INVMODE_ACL_MSG "invalid mode %d by " ++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by " ++#define GR_FAILFORK_MSG "failed fork with errno %s by " ++#define GR_NICE_CHROOT_MSG "denied priority change by " ++#define GR_UNISIGLOG_MSG "%.32s occurred at %p in " ++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " ++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by " ++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by " ++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " ++#define GR_TIME_MSG "time set by " ++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by " ++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " ++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " ++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by " ++#define GR_SOCK_NOINET_MSG "denied socket(%.16s,%.16s,%d) by " ++#define GR_BIND_MSG "denied bind() by " ++#define GR_CONNECT_MSG "denied connect() by " ++#define GR_BIND_ACL_MSG "denied bind() to %pI4 port %u sock type %.16s protocol %.16s by " ++#define GR_CONNECT_ACL_MSG "denied connect() to %pI4 port %u sock type %.16s protocol %.16s by " ++#define GR_IP_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%pI4\t%u\t%u\t%u\t%u\t%pI4" ++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " ++#define GR_CAP_ACL_MSG "use of %s denied for " ++#define GR_CAP_CHROOT_MSG "use of %s in chroot denied for " ++#define GR_CAP_ACL_MSG2 "use of %s permitted for " ++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for " ++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for " ++#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by " ++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by " ++#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by " ++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " ++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by " ++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for " ++#define GR_RWXMMAP_MSG "denied RWX mmap of %.950s by " ++#define GR_RWXMPROTECT_MSG "denied RWX mprotect of %.950s by " ++#define GR_TEXTREL_AUDIT_MSG "denied text relocation in %.950s, VMA:0x%08lx 0x%08lx by " ++#define GR_PTGNUSTACK_MSG "denied marking stack executable as requested by PT_GNU_STACK marking in %.950s by " ++#define GR_VM86_MSG "denied use of vm86 by " ++#define GR_PTRACE_AUDIT_MSG "process %.950s(%.16s:%d) attached to via ptrace by " ++#define GR_PTRACE_READEXEC_MSG "denied ptrace of unreadable binary %.950s by " ++#define GR_INIT_TRANSFER_MSG "persistent special role transferred privilege to init by " ++#define GR_BADPROCPID_MSG "denied read of sensitive /proc/pid/%s entry via fd passed across exec by " ++#define GR_SYMLINKOWNER_MSG "denied following symlink %.950s since symlink owner %u does not match target owner %u, by " ++#define GR_BRUTE_DAEMON_MSG "bruteforce prevention initiated for the next 30 minutes or until service restarted, stalling each fork 30 seconds. Please investigate the crash report for " ++#define GR_BRUTE_SUID_MSG "bruteforce prevention initiated due to crash of %.950s against uid %u, banning suid/sgid execs for %u minutes. Please investigate the crash report for " ++#define GR_IPC_DENIED_MSG "denied %s of overly-permissive IPC object with creator uid %u by " ++#define GR_MSRWRITE_MSG "denied write to CPU MSR by " +diff -Naur backports-3.18.1-1.org/include/linux/grsecurity.h backports-3.18.1-1/include/linux/grsecurity.h +--- backports-3.18.1-1.org/include/linux/grsecurity.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/include/linux/grsecurity.h 2014-12-28 14:10:09.688889562 +0100 +@@ -0,0 +1,254 @@ ++#ifndef GR_SECURITY_H ++#define GR_SECURITY_H ++#include <linux/fs.h> ++#include <linux/fs_struct.h> ++#include <linux/binfmts.h> ++#include <linux/gracl.h> ++ ++/* notify of brain-dead configs */ ++#if defined(CONFIG_GRKERNSEC_PROC_USER) && defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++#error "CONFIG_GRKERNSEC_PROC_USER and CONFIG_GRKERNSEC_PROC_USERGROUP cannot both be enabled." ++#endif ++#if defined(CONFIG_GRKERNSEC_PROC) && !defined(CONFIG_GRKERNSEC_PROC_USER) && !defined(CONFIG_GRKERNSEC_PROC_USERGROUP) ++#error "CONFIG_GRKERNSEC_PROC enabled, but neither CONFIG_GRKERNSEC_PROC_USER nor CONFIG_GRKERNSEC_PROC_USERGROUP enabled" ++#endif ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) ++#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled." ++#endif ++#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP) ++#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled." ++#endif ++#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR) ++#error "CONFIG_PAX enabled, but no PaX options are enabled." ++#endif ++ ++int gr_handle_new_usb(void); ++ ++void gr_handle_brute_attach(int dumpable); ++void gr_handle_brute_check(void); ++void gr_handle_kernel_exploit(void); ++ ++char gr_roletype_to_char(void); ++ ++int gr_proc_is_restricted(void); ++ ++int gr_acl_enable_at_secure(void); ++ ++int gr_check_user_change(kuid_t real, kuid_t effective, kuid_t fs); ++int gr_check_group_change(kgid_t real, kgid_t effective, kgid_t fs); ++ ++int gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap); ++ ++void gr_del_task_from_ip_table(struct task_struct *p); ++ ++int gr_pid_is_chrooted(struct task_struct *p); ++int gr_handle_chroot_fowner(struct pid *pid, enum pid_type type); ++int gr_handle_chroot_nice(void); ++int gr_handle_chroot_sysctl(const int op); ++int gr_handle_chroot_setpriority(struct task_struct *p, ++ const int niceval); ++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt); ++int gr_chroot_fhandle(void); ++int gr_handle_chroot_chroot(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++void gr_handle_chroot_chdir(const struct path *path); ++int gr_handle_chroot_chmod(const struct dentry *dentry, ++ const struct vfsmount *mnt, const int mode); ++int gr_handle_chroot_mknod(const struct dentry *dentry, ++ const struct vfsmount *mnt, const int mode); ++int gr_handle_chroot_mount(const struct dentry *dentry, ++ const struct vfsmount *mnt, ++ const char *dev_name); ++int gr_handle_chroot_pivot(void); ++int gr_handle_chroot_unix(const pid_t pid); ++ ++int gr_handle_rawio(const struct inode *inode); ++ ++void gr_handle_ioperm(void); ++void gr_handle_iopl(void); ++void gr_handle_msr_write(void); ++ ++umode_t gr_acl_umask(void); ++ ++int gr_tpe_allow(const struct file *file); ++ ++void gr_set_chroot_entries(struct task_struct *task, const struct path *path); ++void gr_clear_chroot_entries(struct task_struct *task); ++ ++void gr_log_forkfail(const int retval); ++void gr_log_timechange(void); ++void gr_log_signal(const int sig, const void *addr, const struct task_struct *t); ++void gr_log_chdir(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++void gr_log_chroot_exec(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++void gr_log_remount(const char *devname, const int retval); ++void gr_log_unmount(const char *devname, const int retval); ++void gr_log_mount(const char *from, const char *to, const int retval); ++void gr_log_textrel(struct vm_area_struct *vma); ++void gr_log_ptgnustack(struct file *file); ++void gr_log_rwxmmap(struct file *file); ++void gr_log_rwxmprotect(struct vm_area_struct *vma); ++ ++int gr_handle_follow_link(const struct inode *parent, ++ const struct inode *inode, ++ const struct dentry *dentry, ++ const struct vfsmount *mnt); ++int gr_handle_fifo(const struct dentry *dentry, ++ const struct vfsmount *mnt, ++ const struct dentry *dir, const int flag, ++ const int acc_mode); ++int gr_handle_hardlink(const struct dentry *dentry, ++ const struct vfsmount *mnt, ++ struct inode *inode, ++ const int mode, const struct filename *to); ++ ++int gr_is_capable(const int cap); ++int gr_is_capable_nolog(const int cap); ++int gr_task_is_capable(const struct task_struct *task, const struct cred *cred, const int cap); ++int gr_task_is_capable_nolog(const struct task_struct *task, const int cap); ++ ++void gr_copy_label(struct task_struct *tsk); ++void gr_handle_crash(struct task_struct *task, const int sig); ++int gr_handle_signal(const struct task_struct *p, const int sig); ++int gr_check_crash_uid(const kuid_t uid); ++int gr_check_protected_task(const struct task_struct *task); ++int gr_check_protected_task_fowner(struct pid *pid, enum pid_type type); ++int gr_acl_handle_mmap(const struct file *file, ++ const unsigned long prot); ++int gr_acl_handle_mprotect(const struct file *file, ++ const unsigned long prot); ++int gr_check_hidden_task(const struct task_struct *tsk); ++__u32 gr_acl_handle_truncate(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++__u32 gr_acl_handle_utime(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++__u32 gr_acl_handle_access(const struct dentry *dentry, ++ const struct vfsmount *mnt, const int fmode); ++__u32 gr_acl_handle_chmod(const struct dentry *dentry, ++ const struct vfsmount *mnt, umode_t *mode); ++__u32 gr_acl_handle_chown(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++__u32 gr_acl_handle_setxattr(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++__u32 gr_acl_handle_removexattr(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++int gr_handle_ptrace(struct task_struct *task, const long request); ++int gr_handle_proc_ptrace(struct task_struct *task); ++__u32 gr_acl_handle_execve(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++int gr_check_crash_exec(const struct file *filp); ++int gr_acl_is_enabled(void); ++void gr_set_role_label(struct task_struct *task, const kuid_t uid, ++ const kgid_t gid); ++int gr_set_proc_label(const struct dentry *dentry, ++ const struct vfsmount *mnt, ++ const int unsafe_flags); ++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++__u32 gr_acl_handle_open(const struct dentry *dentry, ++ const struct vfsmount *mnt, int acc_mode); ++__u32 gr_acl_handle_creat(const struct dentry *dentry, ++ const struct dentry *p_dentry, ++ const struct vfsmount *p_mnt, ++ int open_flags, int acc_mode, const int imode); ++void gr_handle_create(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++void gr_handle_proc_create(const struct dentry *dentry, ++ const struct inode *inode); ++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ const int mode); ++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt); ++__u32 gr_acl_handle_rmdir(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++void gr_handle_delete(const ino_t ino, const dev_t dev); ++__u32 gr_acl_handle_unlink(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ const struct filename *from); ++__u32 gr_acl_handle_link(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ const struct dentry *old_dentry, ++ const struct vfsmount *old_mnt, const struct filename *to); ++int gr_handle_symlink_owner(const struct path *link, const struct inode *target); ++int gr_acl_handle_rename(struct dentry *new_dentry, ++ struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ struct dentry *old_dentry, ++ struct inode *old_parent_inode, ++ struct vfsmount *old_mnt, const struct filename *newname, unsigned int flags); ++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir, ++ struct dentry *old_dentry, ++ struct dentry *new_dentry, ++ struct vfsmount *mnt, const __u8 replace, unsigned int flags); ++__u32 gr_check_link(const struct dentry *new_dentry, ++ const struct dentry *parent_dentry, ++ const struct vfsmount *parent_mnt, ++ const struct dentry *old_dentry, ++ const struct vfsmount *old_mnt); ++int gr_acl_handle_filldir(const struct file *file, const char *name, ++ const unsigned int namelen, const ino_t ino); ++ ++__u32 gr_acl_handle_unix(const struct dentry *dentry, ++ const struct vfsmount *mnt); ++void gr_acl_handle_exit(void); ++void gr_acl_handle_psacct(struct task_struct *task, const long code); ++int gr_acl_handle_procpidmem(const struct task_struct *task); ++int gr_handle_rofs_mount(struct dentry *dentry, struct vfsmount *mnt, int mnt_flags); ++int gr_handle_rofs_blockwrite(struct dentry *dentry, struct vfsmount *mnt, int acc_mode); ++void gr_audit_ptrace(struct task_struct *task); ++dev_t gr_get_dev_from_dentry(struct dentry *dentry); ++void gr_put_exec_file(struct task_struct *task); ++ ++int gr_ptrace_readexec(struct file *file, int unsafe_flags); ++ ++#if defined(CONFIG_GRKERNSEC) && (defined(CONFIG_GRKERNSEC_RESLOG) || !defined(CONFIG_GRKERNSEC_NO_RBAC)) ++extern void gr_learn_resource(const struct task_struct *task, const int res, ++ const unsigned long wanted, const int gt); ++#else ++static inline void gr_learn_resource(const struct task_struct *task, const int res, ++ const unsigned long wanted, const int gt) ++{ ++} ++#endif ++ ++#ifdef CONFIG_GRKERNSEC_RESLOG ++extern void gr_log_resource(const struct task_struct *task, const int res, ++ const unsigned long wanted, const int gt); ++#else ++static inline void gr_log_resource(const struct task_struct *task, const int res, ++ const unsigned long wanted, const int gt) ++{ ++} ++#endif ++ ++#ifdef CONFIG_GRKERNSEC ++void task_grsec_rbac(struct seq_file *m, struct task_struct *p); ++void gr_handle_vm86(void); ++void gr_handle_mem_readwrite(u64 from, u64 to); ++ ++void gr_log_badprocpid(const char *entry); ++ ++extern int grsec_enable_dmesg; ++extern int grsec_disable_privio; ++ ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP ++extern kgid_t grsec_proc_gid; ++#endif ++ ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK ++extern int grsec_enable_chroot_findtask; ++#endif ++#ifdef CONFIG_GRKERNSEC_SETXID ++extern int grsec_enable_setxid; ++#endif ++#endif ++ ++#endif +diff -Naur backports-3.18.1-1.org/include/linux/grsock.h backports-3.18.1-1/include/linux/grsock.h +--- backports-3.18.1-1.org/include/linux/grsock.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/include/linux/grsock.h 2014-12-28 14:10:09.688889562 +0100 +@@ -0,0 +1,19 @@ ++#ifndef __GRSOCK_H ++#define __GRSOCK_H ++ ++extern void gr_attach_curr_ip(const struct sock *sk); ++extern int gr_handle_sock_all(const int family, const int type, ++ const int protocol); ++extern int gr_handle_sock_server(const struct sockaddr *sck); ++extern int gr_handle_sock_server_other(const struct sock *sck); ++extern int gr_handle_sock_client(const struct sockaddr *sck); ++extern int gr_search_connect(struct socket * sock, ++ struct sockaddr_in * addr); ++extern int gr_search_bind(struct socket * sock, ++ struct sockaddr_in * addr); ++extern int gr_search_listen(struct socket * sock); ++extern int gr_search_accept(struct socket * sock); ++extern int gr_search_socket(const int domain, const int type, ++ const int protocol); ++ ++#endif +diff -Naur backports-3.18.1-1.org/include/linux/unaligned/access_ok.h backports-3.18.1-1/include/linux/unaligned/access_ok.h +--- backports-3.18.1-1.org/include/linux/unaligned/access_ok.h 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/include/linux/unaligned/access_ok.h 2014-12-28 14:10:09.712889681 +0100 +@@ -4,34 +4,34 @@ + #include <linux/kernel.h> + #include <asm/byteorder.h> + +-static inline u16 get_unaligned_le16(const void *p) ++static inline u16 __intentional_overflow(-1) get_unaligned_le16(const void *p) + { +- return le16_to_cpup((__le16 *)p); ++ return le16_to_cpup((const __le16 *)p); + } + +-static inline u32 get_unaligned_le32(const void *p) ++static inline u32 __intentional_overflow(-1) get_unaligned_le32(const void *p) + { +- return le32_to_cpup((__le32 *)p); ++ return le32_to_cpup((const __le32 *)p); + } + +-static inline u64 get_unaligned_le64(const void *p) ++static inline u64 __intentional_overflow(-1) get_unaligned_le64(const void *p) + { +- return le64_to_cpup((__le64 *)p); ++ return le64_to_cpup((const __le64 *)p); + } + +-static inline u16 get_unaligned_be16(const void *p) ++static inline u16 __intentional_overflow(-1) get_unaligned_be16(const void *p) + { +- return be16_to_cpup((__be16 *)p); ++ return be16_to_cpup((const __be16 *)p); + } + +-static inline u32 get_unaligned_be32(const void *p) ++static inline u32 __intentional_overflow(-1) get_unaligned_be32(const void *p) + { +- return be32_to_cpup((__be32 *)p); ++ return be32_to_cpup((const __be32 *)p); + } + +-static inline u64 get_unaligned_be64(const void *p) ++static inline u64 __intentional_overflow(-1) get_unaligned_be64(const void *p) + { +- return be64_to_cpup((__be64 *)p); ++ return be64_to_cpup((const __be64 *)p); + } + + static inline void put_unaligned_le16(u16 val, void *p) +diff -Naur backports-3.18.1-1.org/include/media/v4l2-dev.h backports-3.18.1-1/include/media/v4l2-dev.h +--- backports-3.18.1-1.org/include/media/v4l2-dev.h 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/include/media/v4l2-dev.h 2014-12-28 14:10:09.716889709 +0100 +@@ -75,7 +75,7 @@ + int (*mmap) (struct file *, struct vm_area_struct *); + int (*open) (struct file *); + int (*release) (struct file *); +-}; ++} __do_const; + + /* + * Newer version of video_device, handled by videodev2.c +diff -Naur backports-3.18.1-1.org/include/media/v4l2-device.h backports-3.18.1-1/include/media/v4l2-device.h +--- backports-3.18.1-1.org/include/media/v4l2-device.h 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/include/media/v4l2-device.h 2014-12-28 14:10:09.716889709 +0100 +@@ -95,7 +95,7 @@ + this function returns 0. If the name ends with a digit (e.g. cx18), + then the name will be set to cx18-0 since cx180 looks really odd. */ + int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename, +- atomic_t *instance); ++ atomic_unchecked_t *instance); + + /* Set v4l2_dev->dev to NULL. Call when the USB parent disconnects. + Since the parent disappears this ensures that v4l2_dev doesn't have an +diff -Naur backports-3.18.1-1.org/include/net/bluetooth/l2cap.h backports-3.18.1-1/include/net/bluetooth/l2cap.h +--- backports-3.18.1-1.org/include/net/bluetooth/l2cap.h 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/include/net/bluetooth/l2cap.h 2014-12-28 14:10:09.716889709 +0100 +@@ -608,7 +608,7 @@ + unsigned char *kdata, + struct iovec *iov, + int len); +-}; ++} __do_const; + + struct l2cap_conn { + struct hci_conn *hcon; +diff -Naur backports-3.18.1-1.org/include/net/mac80211.h backports-3.18.1-1/include/net/mac80211.h +--- backports-3.18.1-1.org/include/net/mac80211.h 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/include/net/mac80211.h 2014-12-28 14:10:09.724889743 +0100 +@@ -4648,7 +4648,7 @@ + void (*remove_sta_debugfs)(void *priv, void *priv_sta); + + u32 (*get_expected_throughput)(void *priv_sta); +-}; ++} __do_const; + + static inline int rate_supported(struct ieee80211_sta *sta, + enum ieee80211_band band, +diff -Naur backports-3.18.1-1.org/include/trace/events/fs.h backports-3.18.1-1/include/trace/events/fs.h +--- backports-3.18.1-1.org/include/trace/events/fs.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/include/trace/events/fs.h 2014-12-28 14:10:09.728889769 +0100 +@@ -0,0 +1,53 @@ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM fs ++ ++#if !defined(_TRACE_FS_H) || defined(TRACE_HEADER_MULTI_READ) ++#define _TRACE_FS_H ++ ++#include <linux/fs.h> ++#include <linux/tracepoint.h> ++ ++TRACE_EVENT(do_sys_open, ++ ++ TP_PROTO(const char *filename, int flags, int mode), ++ ++ TP_ARGS(filename, flags, mode), ++ ++ TP_STRUCT__entry( ++ __string( filename, filename ) ++ __field( int, flags ) ++ __field( int, mode ) ++ ), ++ ++ TP_fast_assign( ++ __assign_str(filename, filename); ++ __entry->flags = flags; ++ __entry->mode = mode; ++ ), ++ ++ TP_printk(""%s" %x %o", ++ __get_str(filename), __entry->flags, __entry->mode) ++); ++ ++TRACE_EVENT(open_exec, ++ ++ TP_PROTO(const char *filename), ++ ++ TP_ARGS(filename), ++ ++ TP_STRUCT__entry( ++ __string( filename, filename ) ++ ), ++ ++ TP_fast_assign( ++ __assign_str(filename, filename); ++ ), ++ ++ TP_printk(""%s"", ++ __get_str(filename)) ++); ++ ++#endif /* _TRACE_FS_H */ ++ ++/* This part must be outside protection */ ++#include <trace/define_trace.h> +diff -Naur backports-3.18.1-1.org/net/bluetooth/6lowpan.c backports-3.18.1-1/net/bluetooth/6lowpan.c +--- backports-3.18.1-1.org/net/bluetooth/6lowpan.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/bluetooth/6lowpan.c 2014-12-28 14:10:09.784890034 +0100 +@@ -367,7 +367,6 @@ + + drop: + dev->stats.rx_dropped++; +- kfree_skb(skb); + return NET_RX_DROP; + } + +diff -Naur backports-3.18.1-1.org/net/bluetooth/bnep/core.c backports-3.18.1-1/net/bluetooth/bnep/core.c +--- backports-3.18.1-1.org/net/bluetooth/bnep/core.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/bluetooth/bnep/core.c 2014-12-28 14:10:09.784890034 +0100 +@@ -533,6 +533,9 @@ + + BT_DBG(""); + ++ if (!l2cap_is_socket(sock)) ++ return -EBADFD; ++ + baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst); + baswap((void *) src, &l2cap_pi(sock->sk)->chan->src); + +diff -Naur backports-3.18.1-1.org/net/bluetooth/cmtp/core.c backports-3.18.1-1/net/bluetooth/cmtp/core.c +--- backports-3.18.1-1.org/net/bluetooth/cmtp/core.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/bluetooth/cmtp/core.c 2014-12-28 14:10:09.784890034 +0100 +@@ -334,6 +334,9 @@ + + BT_DBG(""); + ++ if (!l2cap_is_socket(sock)) ++ return -EBADFD; ++ + session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL); + if (!session) + return -ENOMEM; +diff -Naur backports-3.18.1-1.org/net/bluetooth/hci_sock.c backports-3.18.1-1/net/bluetooth/hci_sock.c +--- backports-3.18.1-1.org/net/bluetooth/hci_sock.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/bluetooth/hci_sock.c 2014-12-28 14:10:09.784890034 +0100 +@@ -1067,7 +1067,7 @@ + uf.event_mask[1] = *((u32 *) f->event_mask + 1); + } + +- len = min_t(unsigned int, len, sizeof(uf)); ++ len = min((size_t)len, sizeof(uf)); + if (copy_from_user(&uf, optval, len)) { + err = -EFAULT; + break; +diff -Naur backports-3.18.1-1.org/net/bluetooth/hidp/core.c backports-3.18.1-1/net/bluetooth/hidp/core.c +--- backports-3.18.1-1.org/net/bluetooth/hidp/core.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/bluetooth/hidp/core.c 2014-12-28 14:10:09.784890034 +0100 +@@ -1322,13 +1322,14 @@ + { + struct hidp_session *session; + struct l2cap_conn *conn; +- struct l2cap_chan *chan = l2cap_pi(ctrl_sock->sk)->chan; ++ struct l2cap_chan *chan; + int ret; + + ret = hidp_verify_sockets(ctrl_sock, intr_sock); + if (ret) + return ret; + ++ chan = l2cap_pi(ctrl_sock->sk)->chan; + conn = NULL; + l2cap_chan_lock(chan); + if (chan->conn) +diff -Naur backports-3.18.1-1.org/net/bluetooth/l2cap_core.c backports-3.18.1-1/net/bluetooth/l2cap_core.c +--- backports-3.18.1-1.org/net/bluetooth/l2cap_core.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/bluetooth/l2cap_core.c 2014-12-28 14:10:09.784890034 +0100 +@@ -3512,8 +3512,10 @@ + break; + + case L2CAP_CONF_RFC: +- if (olen == sizeof(rfc)) +- memcpy(&rfc, (void *)val, olen); ++ if (olen != sizeof(rfc)) ++ break; ++ ++ memcpy(&rfc, (void *)val, olen); + + if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) && + rfc.mode != chan->mode) +diff -Naur backports-3.18.1-1.org/net/bluetooth/l2cap_sock.c backports-3.18.1-1/net/bluetooth/l2cap_sock.c +--- backports-3.18.1-1.org/net/bluetooth/l2cap_sock.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/bluetooth/l2cap_sock.c 2014-12-28 14:10:09.788890064 +0100 +@@ -628,7 +628,8 @@ + struct sock *sk = sock->sk; + struct l2cap_chan *chan = l2cap_pi(sk)->chan; + struct l2cap_options opts; +- int len, err = 0; ++ int err = 0; ++ size_t len = optlen; + u32 opt; + + BT_DBG("sk %p", sk); +@@ -655,7 +656,7 @@ + opts.max_tx = chan->max_tx; + opts.txwin_size = chan->tx_win; + +- len = min_t(unsigned int, sizeof(opts), optlen); ++ len = min(sizeof(opts), len); + if (copy_from_user((char *) &opts, optval, len)) { + err = -EFAULT; + break; +@@ -742,7 +743,8 @@ + struct bt_security sec; + struct bt_power pwr; + struct l2cap_conn *conn; +- int len, err = 0; ++ int err = 0; ++ size_t len = optlen; + u32 opt; + + BT_DBG("sk %p", sk); +@@ -766,7 +768,7 @@ + + sec.level = BT_SECURITY_LOW; + +- len = min_t(unsigned int, sizeof(sec), optlen); ++ len = min(sizeof(sec), len); + if (copy_from_user((char *) &sec, optval, len)) { + err = -EFAULT; + break; +@@ -862,7 +864,7 @@ + + pwr.force_active = BT_POWER_FORCE_ACTIVE_ON; + +- len = min_t(unsigned int, sizeof(pwr), optlen); ++ len = min(sizeof(pwr), len); + if (copy_from_user((char *) &pwr, optval, len)) { + err = -EFAULT; + break; +diff -Naur backports-3.18.1-1.org/net/bluetooth/rfcomm/sock.c backports-3.18.1-1/net/bluetooth/rfcomm/sock.c +--- backports-3.18.1-1.org/net/bluetooth/rfcomm/sock.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/bluetooth/rfcomm/sock.c 2014-12-28 14:10:09.788890064 +0100 +@@ -695,7 +695,7 @@ + struct sock *sk = sock->sk; + struct bt_security sec; + int err = 0; +- size_t len; ++ size_t len = optlen; + u32 opt; + + BT_DBG("sk %p", sk); +@@ -717,7 +717,7 @@ + + sec.level = BT_SECURITY_LOW; + +- len = min_t(unsigned int, sizeof(sec), optlen); ++ len = min(sizeof(sec), len); + if (copy_from_user((char *) &sec, optval, len)) { + err = -EFAULT; + break; +diff -Naur backports-3.18.1-1.org/net/bluetooth/rfcomm/tty.c backports-3.18.1-1/net/bluetooth/rfcomm/tty.c +--- backports-3.18.1-1.org/net/bluetooth/rfcomm/tty.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/bluetooth/rfcomm/tty.c 2014-12-28 14:10:09.788890064 +0100 +@@ -752,7 +752,7 @@ + BT_DBG("tty %p id %d", tty, tty->index); + + BT_DBG("dev %p dst %pMR channel %d opened %d", dev, &dev->dst, +- dev->channel, dev->port.count); ++ dev->channel, atomic_read(&dev->port.count)); + + err = tty_port_open(&dev->port, tty, filp); + if (err) +@@ -775,7 +775,7 @@ + struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; + + BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, +- dev->port.count); ++ atomic_read(&dev->port.count)); + + tty_port_close(&dev->port, tty, filp); + } +diff -Naur backports-3.18.1-1.org/net/ieee802154/6lowpan_rtnl.c backports-3.18.1-1/net/ieee802154/6lowpan_rtnl.c +--- backports-3.18.1-1.org/net/ieee802154/6lowpan_rtnl.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/ieee802154/6lowpan_rtnl.c 2014-12-28 14:10:09.796890100 +0100 +@@ -639,7 +639,7 @@ + dev_put(real_dev); + } + +-static struct rtnl_link_ops lowpan_link_ops __read_mostly = { ++static struct rtnl_link_ops lowpan_link_ops = { + .kind = "lowpan", + .priv_size = sizeof(struct lowpan_dev_info), + .setup = lowpan_setup, +diff -Naur backports-3.18.1-1.org/net/ieee802154/reassembly.c backports-3.18.1-1/net/ieee802154/reassembly.c +--- backports-3.18.1-1.org/net/ieee802154/reassembly.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/ieee802154/reassembly.c 2014-12-28 14:10:09.796890100 +0100 +@@ -460,14 +460,13 @@ + + static int __net_init lowpan_frags_ns_sysctl_register(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table = NULL; + struct ctl_table_header *hdr; + struct netns_ieee802154_lowpan *ieee802154_lowpan = + net_ieee802154_lowpan(net); + +- table = lowpan_frags_ns_ctl_table; + if (!net_eq(net, &init_net)) { +- table = kmemdup(table, sizeof(lowpan_frags_ns_ctl_table), ++ table = kmemdup(lowpan_frags_ns_ctl_table, sizeof(lowpan_frags_ns_ctl_table), + GFP_KERNEL); + if (table == NULL) + goto err_alloc; +@@ -494,8 +493,7 @@ + return 0; + + err_reg: +- if (!net_eq(net, &init_net)) +- kfree(table); ++ kfree(table); + err_alloc: + return -ENOMEM; + } +diff -Naur backports-3.18.1-1.org/net/mac80211/cfg.c backports-3.18.1-1/net/mac80211/cfg.c +--- backports-3.18.1-1.org/net/mac80211/cfg.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/mac80211/cfg.c 2014-12-28 14:10:09.812890175 +0100 +@@ -541,7 +541,7 @@ + ret = ieee80211_vif_use_channel(sdata, chandef, + IEEE80211_CHANCTX_EXCLUSIVE); + } +- } else if (local->open_count == local->monitors) { ++ } else if (local_read(&local->open_count) == local->monitors) { + local->_oper_chandef = *chandef; + ieee80211_hw_config(local, 0); + } +@@ -3326,7 +3326,7 @@ + else + local->probe_req_reg--; + +- if (!local->open_count) ++ if (!local_read(&local->open_count)) + break; + + ieee80211_queue_work(&local->hw, &local->reconfig_filter); +@@ -3460,8 +3460,8 @@ + if (chanctx_conf) { + *chandef = sdata->vif.bss_conf.chandef; + ret = 0; +- } else if (local->open_count > 0 && +- local->open_count == local->monitors && ++ } else if (local_read(&local->open_count) > 0 && ++ local_read(&local->open_count) == local->monitors && + sdata->vif.type == NL80211_IFTYPE_MONITOR) { + if (local->use_chanctx) + *chandef = local->monitor_chandef; +diff -Naur backports-3.18.1-1.org/net/mac80211/ieee80211_i.h backports-3.18.1-1/net/mac80211/ieee80211_i.h +--- backports-3.18.1-1.org/net/mac80211/ieee80211_i.h 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/mac80211/ieee80211_i.h 2014-12-28 14:10:09.812890175 +0100 +@@ -29,6 +29,7 @@ + #include <net/ieee80211_radiotap.h> + #include <net/cfg80211.h> + #include <net/mac80211.h> ++#include <asm/local.h> + #include "key.h" + #include "sta_info.h" + #include "debug.h" +@@ -1057,7 +1058,7 @@ + /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ + spinlock_t queue_stop_reason_lock; + +- int open_count; ++ local_t open_count; + int monitors, cooked_mntrs; + /* number of interfaces with corresponding FIF_ flags */ + int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll, +diff -Naur backports-3.18.1-1.org/net/mac80211/iface.c backports-3.18.1-1/net/mac80211/iface.c +--- backports-3.18.1-1.org/net/mac80211/iface.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/mac80211/iface.c 2014-12-28 14:10:09.812890175 +0100 +@@ -532,7 +532,7 @@ + break; + } + +- if (local->open_count == 0) { ++ if (local_read(&local->open_count) == 0) { + res = drv_start(local); + if (res) + goto err_del_bss; +@@ -579,7 +579,7 @@ + res = drv_add_interface(local, sdata); + if (res) + goto err_stop; +- } else if (local->monitors == 0 && local->open_count == 0) { ++ } else if (local->monitors == 0 && local_read(&local->open_count) == 0) { + res = ieee80211_add_virtual_monitor(local); + if (res) + goto err_stop; +@@ -688,7 +688,7 @@ + atomic_inc(&local->iff_promiscs); + + if (coming_up) +- local->open_count++; ++ local_inc(&local->open_count); + + if (hw_reconf_flags) + ieee80211_hw_config(local, hw_reconf_flags); +@@ -726,7 +726,7 @@ + err_del_interface: + drv_remove_interface(local, sdata); + err_stop: +- if (!local->open_count) ++ if (!local_read(&local->open_count)) + drv_stop(local); + err_del_bss: + sdata->bss = NULL; +@@ -892,7 +892,7 @@ + } + + if (going_down) +- local->open_count--; ++ local_dec(&local->open_count); + + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: +@@ -954,7 +954,7 @@ + } + spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); + +- if (local->open_count == 0) ++ if (local_read(&local->open_count) == 0) + ieee80211_clear_tx_pending(local); + + /* +@@ -997,7 +997,7 @@ + if (cancel_scan) + flush_delayed_work(&local->scan_work); + +- if (local->open_count == 0) { ++ if (local_read(&local->open_count) == 0) { + ieee80211_stop_device(local); + + /* no reconfiguring after stop! */ +@@ -1008,7 +1008,7 @@ + ieee80211_configure_filter(local); + ieee80211_hw_config(local, hw_reconf_flags); + +- if (local->monitors == local->open_count) ++ if (local->monitors == local_read(&local->open_count)) + ieee80211_add_virtual_monitor(local); + } + +diff -Naur backports-3.18.1-1.org/net/mac80211/main.c backports-3.18.1-1/net/mac80211/main.c +--- backports-3.18.1-1.org/net/mac80211/main.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/mac80211/main.c 2014-12-28 14:10:09.812890175 +0100 +@@ -175,7 +175,7 @@ + changed &= ~(IEEE80211_CONF_CHANGE_CHANNEL | + IEEE80211_CONF_CHANGE_POWER); + +- if (changed && local->open_count) { ++ if (changed && local_read(&local->open_count)) { + ret = drv_config(local, changed); + /* + * Goal: +diff -Naur backports-3.18.1-1.org/net/mac80211/pm.c backports-3.18.1-1/net/mac80211/pm.c +--- backports-3.18.1-1.org/net/mac80211/pm.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/mac80211/pm.c 2014-12-28 14:10:09.812890175 +0100 +@@ -12,7 +12,7 @@ + struct ieee80211_sub_if_data *sdata; + struct sta_info *sta; + +- if (!local->open_count) ++ if (!local_read(&local->open_count)) + goto suspend; + + ieee80211_scan_cancel(local); +@@ -59,7 +59,7 @@ + cancel_work_sync(&local->dynamic_ps_enable_work); + del_timer_sync(&local->dynamic_ps_timer); + +- local->wowlan = wowlan && local->open_count; ++ local->wowlan = wowlan && local_read(&local->open_count); + if (local->wowlan) { + int err = drv_suspend(local, wowlan); + if (err < 0) { +@@ -125,7 +125,7 @@ + WARN_ON(!list_empty(&local->chanctx_list)); + + /* stop hardware - this must stop RX */ +- if (local->open_count) ++ if (local_read(&local->open_count)) + ieee80211_stop_device(local); + + suspend: +diff -Naur backports-3.18.1-1.org/net/mac80211/rate.c backports-3.18.1-1/net/mac80211/rate.c +--- backports-3.18.1-1.org/net/mac80211/rate.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/mac80211/rate.c 2014-12-28 14:10:09.812890175 +0100 +@@ -720,7 +720,7 @@ + + ASSERT_RTNL(); + +- if (local->open_count) ++ if (local_read(&local->open_count)) + return -EBUSY; + + if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) { +diff -Naur backports-3.18.1-1.org/net/mac80211/util.c backports-3.18.1-1/net/mac80211/util.c +--- backports-3.18.1-1.org/net/mac80211/util.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/mac80211/util.c 2014-12-28 14:10:09.816890209 +0100 +@@ -1669,7 +1669,7 @@ + } + #endif + /* everything else happens only if HW was up & running */ +- if (!local->open_count) ++ if (!local_read(&local->open_count)) + goto wake_up; + + /* +@@ -1895,7 +1895,7 @@ + local->in_reconfig = false; + barrier(); + +- if (local->monitors == local->open_count && local->monitors > 0) ++ if (local->monitors == local_read(&local->open_count) && local->monitors > 0) + ieee80211_add_virtual_monitor(local); + + /* +diff -Naur backports-3.18.1-1.org/net/wireless/wext-core.c backports-3.18.1-1/net/wireless/wext-core.c +--- backports-3.18.1-1.org/net/wireless/wext-core.c 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/net/wireless/wext-core.c 2014-12-28 14:10:09.832890290 +0100 +@@ -748,8 +748,7 @@ + */ + + /* Support for very large requests */ +- if ((descr->flags & IW_DESCR_FLAG_NOMAX) && +- (user_length > descr->max_tokens)) { ++ if (user_length > descr->max_tokens) { + /* Allow userspace to GET more than max so + * we can support any size GET requests. + * There is still a limit : -ENOMEM. +@@ -788,22 +787,6 @@ + } + } + +- if (IW_IS_GET(cmd) && !(descr->flags & IW_DESCR_FLAG_NOMAX)) { +- /* +- * If this is a GET, but not NOMAX, it means that the extra +- * data is not bounded by userspace, but by max_tokens. Thus +- * set the length to max_tokens. This matches the extra data +- * allocation. +- * The driver should fill it with the number of tokens it +- * provided, and it may check iwp->length rather than having +- * knowledge of max_tokens. If the driver doesn't change the +- * iwp->length, this ioctl just copies back max_token tokens +- * filled with zeroes. Hopefully the driver isn't claiming +- * them to be valid data. +- */ +- iwp->length = descr->max_tokens; +- } +- + err = handler(dev, info, (union iwreq_data *) iwp, extra); + + iwp->length += essid_compat; diff --git a/src/patches/backports-3.18.1-1-ipfire-build.patch b/src/patches/backports-3.18.1-1-ipfire-build.patch new file mode 100644 index 0000000..0b2998e --- /dev/null +++ b/src/patches/backports-3.18.1-1-ipfire-build.patch @@ -0,0 +1,34 @@ +diff -Naur backports-3.18.1-1.org/Makefile backports-3.18.1-1/Makefile +--- backports-3.18.1-1.org/Makefile 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/Makefile 2014-12-29 15:51:19.358111370 +0100 +@@ -8,9 +8,9 @@ + SHELL := /bin/bash + BACKPORT_PWD := $(shell pwd) + +-KMODDIR ?= updates ++KMODDIR ?= kernel + ifneq ($(origin KLIB), undefined) +-KMODPATH_ARG := "INSTALL_MOD_PATH=$(KLIB)" ++KMODPATH_ARG := + else + KLIB := /lib/modules/$(shell uname -r)/ + KMODPATH_ARG := +diff -Naur backports-3.18.1-1.org/Makefile.real backports-3.18.1-1/Makefile.real +--- backports-3.18.1-1.org/Makefile.real 2014-12-21 22:37:13.000000000 +0100 ++++ backports-3.18.1-1/Makefile.real 2014-12-29 15:51:40.934780933 +0100 +@@ -92,11 +92,11 @@ + @$(MAKE) -C $(KLIB_BUILD) M=$(BACKPORT_PWD) \ + INSTALL_MOD_DIR=$(KMODDIR) $(KMODPATH_ARG) \ + modules_install +- @./scripts/blacklist.sh $(KLIB)/ $(KLIB)/$(KMODDIR) ++# @./scripts/blacklist.sh $(KLIB)/ $(KLIB)/$(KMODDIR) + @./scripts/compress_modules.sh $(KLIB)/$(KMODDIR) +- @./scripts/check_depmod.sh +- @/sbin/depmod -a +- @./scripts/update-initramfs.sh $(KLIB) ++# @./scripts/check_depmod.sh ++# @/sbin/depmod -a ++# @./scripts/update-initramfs.sh $(KLIB) + @echo + @echo Your backported driver modules should be installed now. + @echo Reboot. diff --git a/src/patches/backports-3.18.1-1_add_libertas_uap.patch b/src/patches/backports-3.18.1-1_add_libertas_uap.patch new file mode 100644 index 0000000..9a5b01b --- /dev/null +++ b/src/patches/backports-3.18.1-1_add_libertas_uap.patch @@ -0,0 +1,5058 @@ +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/Kconfig backports-3.18.1-1/drivers/net/wireless/Kconfig +--- backports-3.18.1-1.org/drivers/net/wireless/Kconfig 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/Kconfig 2014-12-29 20:37:43.945764119 +0100 +@@ -55,6 +55,14 @@ + ---help--- + A driver for Marvell Libertas 8388 USB devices using thinfirm. + ++config LIBERTAS_UAP ++ tristate "Marvell 8xxx Libertas UAP" ++ depends on MAC80211 ++ depends on MMC ++ select FW_LOADER ++ ---help--- ++ Driver for Marvell Libertas 8xxx micro AP. ++ + config AIRO + depends on n + tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/Makefile backports-3.18.1-1/drivers/net/wireless/libertas_uap/Makefile +--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/Makefile 2014-12-29 20:41:50.975778546 +0100 +@@ -0,0 +1,6 @@ ++obj-$(CPTCFG_LIBERTAS_UAP) += uap8xxx.o ++ ++uap8xxx-y += uap_main.o uap_sdio_mmc.o ++uap8xxx-$(CPTCFG_PROC_FS) += uap_proc.o uap_debug.o ++ ++EXTRA_CFLAGS += -DFPNUM='"52"' -DPXA3XX_DMA_ALIGN -DDEBUG_LEVEL1 +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_debug.c backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_debug.c +--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_debug.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_debug.c 2014-12-29 20:37:43.949097590 +0100 +@@ -0,0 +1,260 @@ ++/** @file uap_debug.c ++ * @brief This file contains functions for debug proc file. ++ * ++ * Copyright (C) 2008-2009, Marvell International Ltd. ++ * ++ * This software file (the "File") is distributed by Marvell International ++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 ++ * (the "License"). You may use, redistribute and/or modify this File in ++ * accordance with the terms and conditions of the License, a copy of which ++ * is available along with the File in the gpl.txt file or by writing to ++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++ * ++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ++ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about ++ * this warranty disclaimer. ++ * ++ */ ++#ifdef CONFIG_PROC_FS ++#include "uap_headers.h" ++ ++/******************************************************** ++ Local Variables ++********************************************************/ ++ ++#define item_size(n) (sizeof ((uap_adapter *)0)->n) ++#define item_addr(n) ((u32) &((uap_adapter *)0)->n) ++ ++#define item_dbg_size(n) (sizeof (((uap_adapter *)0)->dbg.n)) ++#define item_dbg_addr(n) ((u32) &(((uap_adapter *)0)->dbg.n)) ++ ++#define item_dev_size(n) (sizeof ((uap_dev_t *)0)->n) ++#define item_dev_addr(n) ((u32) &((uap_dev_t *)0)->n) ++ ++/** MicroAp device offset */ ++#define OFFSET_UAP_DEV 0x01 ++/** Bluetooth adapter offset */ ++#define OFFSET_UAP_ADAPTER 0x02 ++ ++struct debug_data ++{ ++ /** Name */ ++ char name[32]; ++ /** Size */ ++ u32 size; ++ /** Address */ ++ u32 addr; ++ /** Offset */ ++ u32 offset; ++ /** Flag */ ++ u32 flag; ++}; ++ ++/* To debug any member of uap_adapter, simply add one line here. ++ */ ++static struct debug_data items[] = { ++ {"cmd_sent", item_dev_size(cmd_sent), 0, item_dev_addr(cmd_sent), ++ OFFSET_UAP_DEV}, ++ {"data_sent", item_dev_size(data_sent), 0, item_dev_addr(data_sent), ++ OFFSET_UAP_DEV}, ++ {"IntCounter", item_size(IntCounter), 0, item_addr(IntCounter), ++ OFFSET_UAP_ADAPTER}, ++ {"cmd_pending", item_size(cmd_pending), 0, item_addr(cmd_pending), ++ OFFSET_UAP_ADAPTER}, ++ {"num_cmd_h2c_fail", item_dbg_size(num_cmd_host_to_card_failure), 0, ++ item_dbg_addr(num_cmd_host_to_card_failure), OFFSET_UAP_ADAPTER}, ++ {"num_tx_h2c_fail", item_dbg_size(num_tx_host_to_card_failure), 0, ++ item_dbg_addr(num_tx_host_to_card_failure), OFFSET_UAP_ADAPTER}, ++ {"psmode", item_size(psmode), 0, item_addr(psmode), OFFSET_UAP_ADAPTER}, ++ {"ps_state", item_size(ps_state), 0, item_addr(ps_state), ++ OFFSET_UAP_ADAPTER}, ++#ifdef DEBUG_LEVEL1 ++ {"drvdbg", sizeof(drvdbg), (u32) & drvdbg, 0, 0} ++#endif ++}; ++ ++static int num_of_items = sizeof(items) / sizeof(items[0]); ++ ++/******************************************************** ++ Global Variables ++********************************************************/ ++ ++/******************************************************** ++ Local Functions ++********************************************************/ ++/** ++ * @brief proc read function ++ * ++ * @param page pointer to buffer ++ * @param s read data starting position ++ * @param off offset ++ * @param cnt counter ++ * @param eof end of file flag ++ * @param data data to output ++ * @return number of output data ++ */ ++static int uap_debug_proc_show(struct seq_file *s, void *data) { ++ int val = 0; ++ int i; ++ ++ struct debug_data *d = (struct debug_data *)s->private; ++ ++ if (MODULE_GET == 0) ++ return UAP_STATUS_FAILURE; ++ ++ for (i = 0; i < num_of_items; i++) { ++ if (d[i].size == 1) ++ val = *((u8 *) d[i].addr); ++ else if (d[i].size == 2) ++ val = *((u16 *) d[i].addr); ++ else if (d[i].size == 4) ++ val = *((u32 *) d[i].addr); ++ ++ seq_printf(s, "%s=%d\n", d[i].name, val); ++ } ++ MODULE_PUT; ++ return 0; ++} ++ ++static int uap_debug_proc_open(struct inode* inode, struct file* file) { ++ return single_open(file, uap_debug_proc_show, PDE_DATA(inode)); ++} ++ ++/** ++ * @brief proc write function ++ * ++ * @param f file pointer ++ * @param buf pointer to data buffer ++ * @param cnt data number to write ++ * @param data data to write ++ * @return number of data ++ */ ++static ssize_t uap_debug_proc_write(struct file *f, const char __user *buf, size_t cnt, loff_t *data) { ++ int r, i; ++ char *pdata; ++ char *p; ++ char *p0; ++ char *p1; ++ char *p2; ++ struct debug_data *d = (struct debug_data *)PDE_DATA(file_inode(f)); ++ ++ if (MODULE_GET == 0) ++ return UAP_STATUS_FAILURE; ++ ++ pdata = (char *) kmalloc(cnt, GFP_KERNEL); ++ if (pdata == NULL) { ++ MODULE_PUT; ++ return 0; ++ } ++ ++ if (copy_from_user(pdata, buf, cnt)) { ++ PRINTM(INFO, "Copy from user failed\n"); ++ kfree(pdata); ++ MODULE_PUT; ++ return 0; ++ } ++ ++ p0 = pdata; ++ for (i = 0; i < num_of_items; i++) { ++ do { ++ p = strstr(p0, d[i].name); ++ if (p == NULL) ++ break; ++ p1 = strchr(p, '\n'); ++ if (p1 == NULL) ++ break; ++ p0 = p1++; ++ p2 = strchr(p, '='); ++ if (!p2) ++ break; ++ p2++; ++ r = string_to_number(p2); ++ if (d[i].size == 1) ++ *((u8 *) d[i].addr) = (u8) r; ++ else if (d[i].size == 2) ++ *((u16 *) d[i].addr) = (u16) r; ++ else if (d[i].size == 4) ++ *((u32 *) d[i].addr) = (u32) r; ++ break; ++ } while (TRUE); ++ } ++ kfree(pdata); ++#ifdef DEBUG_LEVEL1 ++ printk(KERN_ALERT "drvdbg = 0x%x\n", drvdbg); ++ printk(KERN_ALERT "INFO (%08lx) %s\n", DBG_INFO, ++ (drvdbg & DBG_INFO) ? "X" : ""); ++ printk(KERN_ALERT "WARN (%08lx) %s\n", DBG_WARN, ++ (drvdbg & DBG_WARN) ? "X" : ""); ++ printk(KERN_ALERT "ENTRY (%08lx) %s\n", DBG_ENTRY, ++ (drvdbg & DBG_ENTRY) ? "X" : ""); ++ printk(KERN_ALERT "CMD_D (%08lx) %s\n", DBG_CMD_D, ++ (drvdbg & DBG_CMD_D) ? "X" : ""); ++ printk(KERN_ALERT "DAT_D (%08lx) %s\n", DBG_DAT_D, ++ (drvdbg & DBG_DAT_D) ? "X" : ""); ++ printk(KERN_ALERT "CMND (%08lx) %s\n", DBG_CMND, ++ (drvdbg & DBG_CMND) ? "X" : ""); ++ printk(KERN_ALERT "DATA (%08lx) %s\n", DBG_DATA, ++ (drvdbg & DBG_DATA) ? "X" : ""); ++ printk(KERN_ALERT "ERROR (%08lx) %s\n", DBG_ERROR, ++ (drvdbg & DBG_ERROR) ? "X" : ""); ++ printk(KERN_ALERT "FATAL (%08lx) %s\n", DBG_FATAL, ++ (drvdbg & DBG_FATAL) ? "X" : ""); ++ printk(KERN_ALERT "MSG (%08lx) %s\n", DBG_MSG, ++ (drvdbg & DBG_MSG) ? "X" : ""); ++#endif ++ MODULE_PUT; ++ return cnt; ++} ++ ++static const struct file_operations uap_debug_proc_fops = { ++ .owner = THIS_MODULE, ++ .open = uap_debug_proc_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .write = uap_debug_proc_write, ++}; ++ ++/******************************************************** ++ Global Functions ++********************************************************/ ++/** ++ * @brief create debug proc file ++ * ++ * @param priv pointer uap_private ++ * @param dev pointer net_device ++ * @return N/A ++ */ ++void ++uap_debug_entry(uap_private * priv, struct net_device *dev) ++{ ++ int i; ++ ++ if (priv->proc_entry == NULL) ++ return; ++ ++ for (i = 0; i < num_of_items; i++) { ++ if (items[i].flag & OFFSET_UAP_ADAPTER) ++ items[i].addr = items[i].offset + (u32) priv->adapter; ++ if (items[i].flag & OFFSET_UAP_DEV) ++ items[i].addr = items[i].offset + (u32) & priv->uap_dev; ++ } ++ proc_create_data("debug", 0644, priv->proc_entry, &uap_debug_proc_fops, ++ &items[0]); ++} ++ ++/** ++ * @brief remove proc file ++ * ++ * @param priv pointer uap_private ++ * @return N/A ++ */ ++void ++uap_debug_remove(uap_private * priv) ++{ ++ remove_proc_entry("debug", priv->proc_entry); ++} ++ ++#endif +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_drv.h backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_drv.h +--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_drv.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_drv.h 2014-12-29 20:37:43.949097590 +0100 +@@ -0,0 +1,667 @@ ++/** @file uap_drv.h ++ * @brief This file contains Linux OS related definitions and ++ * declarations, uAP driver ++ * ++ * Copyright (C) 2008-2009, Marvell International Ltd. ++ * ++ * This software file (the "File") is distributed by Marvell International ++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 ++ * (the "License"). You may use, redistribute and/or modify this File in ++ * accordance with the terms and conditions of the License, a copy of which ++ * is available along with the File in the gpl.txt file or by writing to ++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++ * ++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ++ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about ++ * this warranty disclaimer. ++ * ++ */ ++ ++#ifndef _UAP_DRV_H ++#define _UAP_DRV_H ++ ++/** Driver release version */ ++#define DRIVER_VERSION "26146" ++ ++/** True */ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++/** False */ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++/** Bit definitions */ ++#ifndef BIT ++#define BIT(x) (1UL << (x)) ++#endif ++ ++/** Dma addresses are 32-bits wide. */ ++#ifndef __ATTRIB_ALIGN__ ++#define __ATTRIB_ALIGN__ __attribute__((aligned(4))) ++#endif ++ ++/** attribute pack */ ++#ifndef __ATTRIB_PACK__ ++#define __ATTRIB_PACK__ __attribute__ ((packed)) ++#endif ++ ++/** Debug Macro definition*/ ++#ifdef DEBUG_LEVEL1 ++ ++extern u32 drvdbg; ++ ++/** Debug message control bit definition for drvdbg */ ++/** Debug message */ ++#define DBG_MSG BIT(0) ++/** Debug fatal message */ ++#define DBG_FATAL BIT(1) ++/** Debug error message */ ++#define DBG_ERROR BIT(2) ++/** Debug data message */ ++#define DBG_DATA BIT(3) ++/** Debug command message */ ++#define DBG_CMND BIT(4) ++ ++/** Debug data */ ++#define DBG_DAT_D BIT(16) ++/** Debug command */ ++#define DBG_CMD_D BIT(17) ++ ++/** Debug entry */ ++#define DBG_ENTRY BIT(28) ++/** Debug warning */ ++#define DBG_WARN BIT(29) ++/** Debug info */ ++#define DBG_INFO BIT(30) ++ ++/** Print info */ ++#define PRINTM_INFO(msg...) {if (drvdbg & DBG_INFO) printk(KERN_DEBUG msg);} ++/** Print warn message */ ++#define PRINTM_WARN(msg...) {if (drvdbg & DBG_WARN) printk(KERN_DEBUG msg);} ++/** Print entry */ ++#define PRINTM_ENTRY(msg...) {if (drvdbg & DBG_ENTRY) printk(KERN_DEBUG msg);} ++/** Print cmd_d */ ++#define PRINTM_CMD_D(msg...) {if (drvdbg & DBG_CMD_D) printk(KERN_DEBUG msg);} ++/** Print data_d */ ++#define PRINTM_DAT_D(msg...) {if (drvdbg & DBG_DAT_D) printk(KERN_DEBUG msg);} ++/** Print command */ ++#define PRINTM_CMND(msg...) {if (drvdbg & DBG_CMND) printk(KERN_DEBUG msg);} ++/** Print data */ ++#define PRINTM_DATA(msg...) {if (drvdbg & DBG_DATA) printk(KERN_DEBUG msg);} ++/** Print error message */ ++#define PRINTM_ERROR(msg...) {if (drvdbg & DBG_ERROR) printk(KERN_DEBUG msg);} ++/** Print fatal message */ ++#define PRINTM_FATAL(msg...) {if (drvdbg & DBG_FATAL) printk(KERN_DEBUG msg);} ++/** Print message */ ++#define PRINTM_MSG(msg...) {if (drvdbg & DBG_MSG) printk(KERN_ALERT msg);} ++/** Print level */ ++#define PRINTM(level,msg...) PRINTM_##level(msg) ++ ++#else ++ ++#define PRINTM(level,msg...) do {} while (0) ++ ++#endif /* DEBUG_LEVEL1 */ ++ ++/** Wait until a condition becomes true */ ++#define ASSERT(cond) \ ++do { \ ++ if (!(cond)) \ ++ PRINTM(INFO, "ASSERT: %s, %s:%i\n", \ ++ __FUNCTION__, __FILE__, __LINE__); \ ++} while(0) ++ ++/** Log enrty point for debugging */ ++#define ENTER() PRINTM(ENTRY, "Enter: %s, %s:%i\n", __FUNCTION__, \ ++ __FILE__, __LINE__) ++/** Log exit point for debugging */ ++#define LEAVE() PRINTM(ENTRY, "Leave: %s, %s:%i\n", __FUNCTION__, \ ++ __FILE__, __LINE__) ++ ++#ifdef DEBUG_LEVEL1 ++/** Dump buffer length */ ++#define DBG_DUMP_BUF_LEN 64 ++/** Maximum dump per line */ ++#define MAX_DUMP_PER_LINE 16 ++/** Data dump length */ ++#define DATA_DUMP_LEN 32 ++ ++static inline void ++hexdump(char *prompt, u8 * buf, int len) ++{ ++ int i; ++ char dbgdumpbuf[DBG_DUMP_BUF_LEN]; ++ char *ptr = dbgdumpbuf; ++ ++ printk(KERN_DEBUG "%s:\n", prompt); ++ for (i = 1; i <= len; i++) { ++ ptr += sprintf(ptr, "%02x ", *buf); ++ buf++; ++ if (i % MAX_DUMP_PER_LINE == 0) { ++ *ptr = 0; ++ printk(KERN_DEBUG "%s\n", dbgdumpbuf); ++ ptr = dbgdumpbuf; ++ } ++ } ++ if (len % MAX_DUMP_PER_LINE) { ++ *ptr = 0; ++ printk(KERN_DEBUG "%s\n", dbgdumpbuf); ++ } ++} ++ ++/** Debug command */ ++#define DBG_HEXDUMP_CMD_D(x,y,z) {if (drvdbg & DBG_CMD_D) hexdump(x,y,z);} ++/** Debug data */ ++#define DBG_HEXDUMP_DAT_D(x,y,z) {if (drvdbg & DBG_DAT_D) hexdump(x,y,z);} ++/** Debug hexdump */ ++#define DBG_HEXDUMP(level,x,y,z) DBG_HEXDUMP_##level(x,y,z) ++/** hexdump */ ++#define HEXDUMP(x,y,z) {if (drvdbg & DBG_INFO) hexdump(x,y,z);} ++#else ++/** Do nothing since debugging is not turned on */ ++#define DBG_HEXDUMP(level,x,y,z) do {} while (0) ++/** Do nothing since debugging is not turned on */ ++#define HEXDUMP(x,y,z) do {} while (0) ++#endif ++ ++/** ++ * Typedefs ++ */ ++/** Unsigned char */ ++typedef u8 BOOLEAN; ++ ++/* ++ * OS macro definitions ++ */ ++/** OS macro to get time */ ++#define os_time_get() jiffies ++ ++/** OS macro to update transfer start time */ ++#define UpdateTransStart(dev) { \ ++ dev->trans_start = jiffies; \ ++} ++ ++/** Try to get a reference to the module */ ++#define MODULE_GET try_module_get(THIS_MODULE) ++/** Decrease module reference count */ ++#define MODULE_PUT module_put(THIS_MODULE) ++ ++/** OS macro to initialize semaphore */ ++#define OS_INIT_SEMAPHORE(x) sema_init(x,1) ++/** OS macro to acquire blocking semaphore */ ++#define OS_ACQ_SEMAPHORE_BLOCK(x) down_interruptible(x) ++/** OS macro to acquire non-blocking semaphore */ ++#define OS_ACQ_SEMAPHORE_NOBLOCK(x) down_trylock(x) ++/** OS macro to release semaphore */ ++#define OS_REL_SEMAPHORE(x) up(x) ++ ++static inline void ++os_sched_timeout(u32 millisec) ++{ ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule_timeout((millisec * HZ) / 1000); ++} ++ ++/** Maximum size of ethernet packet */ ++#define MRVDRV_MAXIMUM_ETH_PACKET_SIZE 1514 ++ ++/** Maximum size of multicast list */ ++#define MRVDRV_MAX_MULTICAST_LIST_SIZE 32 ++ ++/** Find minimum */ ++#ifndef MIN ++#define MIN(a,b) ((a) < (b) ? (a) : (b)) ++#endif ++ ++/** Find maximum */ ++#ifndef MAX ++#define MAX(a,b) ((a) > (b) ? (a) : (b)) ++#endif ++ ++/** Find number of elements */ ++#ifndef NELEMENTS ++#define NELEMENTS(x) (sizeof(x)/sizeof(x[0])) ++#endif ++ ++/** Buffer Constants */ ++ ++/** Size of command buffer */ ++#define MRVDRV_SIZE_OF_CMD_BUFFER (2 * 1024) ++ ++/** Length of device length */ ++#define DEV_NAME_LEN 32 ++ ++/** Length of ethernet address */ ++#ifndef ETH_ALEN ++#define ETH_ALEN 6 ++#endif ++ ++/** Default watchdog timeout */ ++#define MRVDRV_DEFAULT_WATCHDOG_TIMEOUT (2 * HZ) ++ ++/** Success */ ++#define UAP_STATUS_SUCCESS (0) ++/** Failure */ ++#define UAP_STATUS_FAILURE (-1) ++/** Not accepted */ ++#define UAP_STATUS_NOT_ACCEPTED (-2) ++ ++/** Max loop count (* 100ms) for waiting device ready at init time */ ++#define MAX_WAIT_DEVICE_READY_COUNT 50 ++ ++/** Tx high watermark. Stop Tx queue after this is crossed */ ++#define TX_HIGH_WATERMARK 4 ++/** Tx low watermark. Restart Tx queue after this is crossed */ ++#define TX_LOW_WATERMARK 2 ++ ++/** Netlink protocol number */ ++#define NETLINK_MARVELL (MAX_LINKS - 1) ++/** Netlink maximum payload size */ ++#define NL_MAX_PAYLOAD 1024 ++/** Netlink multicast group number */ ++#define NL_MULTICAST_GROUP 1 ++ ++/** 20 seconds */ ++#define MRVDRV_TIMER_20S 20000 ++ ++/** Host Command option for wait till Send */ ++#define HostCmd_OPTION_WAITFORSEND 0x0001 ++/** Host Command option for wait for RSP */ ++#define HostCmd_OPTION_WAITFORRSP 0x0002 ++/** Host Command option for wait for RSP or Timeout */ ++#define HostCmd_OPTION_WAITFORRSP_TIMEOUT 0x0003 ++/** Host Command option for wait for RSP of sleep confirm */ ++#define HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM 0x0004 ++ ++/** Sleep until a condition gets true or a timeout elapses */ ++#define os_wait_interruptible_timeout(waitq, cond, timeout) \ ++ wait_event_interruptible_timeout(waitq, cond, ((timeout) * HZ / 1000)) ++ ++/** Private command ID to Host command */ ++#define UAPHOSTCMD (SIOCDEVPRIVATE + 1) ++ ++/** Private command ID to Power Mode */ ++#define UAP_POWER_MODE (SIOCDEVPRIVATE + 3) ++/** sleep_param */ ++typedef struct _ps_sleep_param ++{ ++ /** control bitmap */ ++ u32 ctrl_bitmap; ++ /** minimum sleep period (micro second) */ ++ u32 min_sleep; ++ /** maximum sleep period (micro second) */ ++ u32 max_sleep; ++} ps_sleep_param; ++ ++/** inactivity sleep_param */ ++typedef struct _inact_sleep_param ++{ ++ /** inactivity timeout (micro second) */ ++ u32 inactivity_to; ++ /** miniumu awake period (micro second) */ ++ u32 min_awake; ++ /** maximum awake period (micro second) */ ++ u32 max_awake; ++} inact_sleep_param; ++ ++/** flag for ps mode */ ++#define PS_FLAG_PS_MODE 1 ++/** flag for sleep param */ ++#define PS_FLAG_SLEEP_PARAM 2 ++/** flag for inactivity sleep param */ ++#define PS_FLAG_INACT_SLEEP_PARAM 4 ++ ++/** Disable power mode */ ++#define PS_MODE_DISABLE 0 ++/** Enable periodic dtim ps */ ++#define PS_MODE_PERIODIC_DTIM 1 ++/** Enable inactivity ps */ ++#define PS_MODE_INACTIVITY 2 ++ ++/** sleep parameter */ ++#define SLEEP_PARAMETER 1 ++/** inactivity sleep parameter */ ++#define INACTIVITY_SLEEP_PARAMETER 2 ++/** ps_mgmt */ ++typedef struct _ps_mgmt ++{ ++ /** flags for valid field */ ++ u16 flags; ++ /** power mode */ ++ u16 ps_mode; ++ /** sleep param */ ++ ps_sleep_param sleep_param; ++ /** inactivity sleep param */ ++ inact_sleep_param inact_param; ++} ps_mgmt; ++ ++/** Semaphore structure */ ++typedef struct semaphore SEMAPHORE; ++ ++/** Global Varibale Declaration */ ++/** Private data structure of the device */ ++typedef struct _uap_private uap_private; ++/** Adapter data structure of the device */ ++typedef struct _uap_adapter uap_adapter; ++/** private structure */ ++extern uap_private *uappriv; ++ ++/** ENUM definition*/ ++ ++/** Hardware status codes */ ++typedef enum _HARDWARE_STATUS ++{ ++ HWReady, ++ HWInitializing, ++ HWReset, ++ HWClosing, ++ HWNotReady ++} HARDWARE_STATUS; ++ ++/** info for debug purpose */ ++typedef struct _uap_dbg ++{ ++ /** Number of host to card command failures */ ++ u32 num_cmd_host_to_card_failure; ++ /** Number of host to card Tx failures */ ++ u32 num_tx_host_to_card_failure; ++} uap_dbg; ++ ++/** Set thread state */ ++#define OS_SET_THREAD_STATE(x) set_current_state(x) ++ ++typedef struct ++{ ++ /** Task */ ++ struct task_struct *task; ++ /** Queue */ ++ wait_queue_head_t waitQ; ++ /** PID */ ++ pid_t pid; ++ /** Private structure */ ++ void *priv; ++} uap_thread; ++ ++static inline void ++uap_activate_thread(uap_thread * thr) ++{ ++ /** Record the thread pid */ ++ thr->pid = current->pid; ++ ++ /** Initialize the wait queue */ ++ init_waitqueue_head(&thr->waitQ); ++} ++ ++static inline void ++uap_deactivate_thread(uap_thread * thr) ++{ ++ thr->pid = 0; ++ return; ++} ++ ++static inline void ++uap_create_thread(int (*uapfunc) (void *), uap_thread * thr, char *name) ++{ ++ thr->task = kthread_run(uapfunc, thr, "%s", name); ++} ++ ++static inline int ++uap_terminate_thread(uap_thread * thr) ++{ ++ /* Check if the thread is active or not */ ++ if (!thr->pid) ++ return -1; ++ kthread_stop(thr->task); ++ return 0; ++} ++ ++/** Data structure for the Marvell uAP device */ ++typedef struct _uap_dev ++{ ++ /** device name */ ++ char name[DEV_NAME_LEN]; ++ /** card pointer */ ++ void *card; ++ /** IO port */ ++ u32 ioport; ++ /** Rx unit */ ++ u8 rx_unit; ++ /** Data sent: ++ TRUE - Data is sent to fw, no Tx Done received ++ FALSE - Tx done received for previous Tx */ ++ BOOLEAN data_sent; ++ /** CMD sent: ++ TRUE - CMD is sent to fw, no CMD Done received ++ FALSE - CMD done received for previous CMD */ ++ BOOLEAN cmd_sent; ++ /** netdev pointer */ ++ struct net_device *netdev; ++} uap_dev_t, *puap_dev_t; ++ ++/** Private structure for the MV device */ ++struct _uap_private ++{ ++ /** Device open */ ++ int open; ++ ++ /** Device adapter structure */ ++ uap_adapter *adapter; ++ /** Device structure */ ++ uap_dev_t uap_dev; ++ ++ /** Net device statistics structure */ ++ struct net_device_stats stats; ++ ++ /** Number of Tx timeouts */ ++ u32 num_tx_timeout; ++ ++ /** Media connection status */ ++ BOOLEAN MediaConnected; ++ ++#ifdef CONFIG_PROC_FS ++ struct proc_dir_entry *proc_uap; ++ struct proc_dir_entry *proc_entry; ++#endif /* CONFIG_PROC_FS */ ++ ++ /** Firmware helper */ ++ const struct firmware *fw_helper; ++ /** Firmware */ ++ const struct firmware *firmware; ++ /** Hotplug device */ ++ struct device *hotplug_device; ++ /** thread to service interrupts */ ++ uap_thread MainThread; ++ /** Driver lock */ ++ spinlock_t driver_lock; ++ /** Driver lock flags */ ++ ulong driver_flags; ++ ++}; ++ ++/** PS_CMD_ConfirmSleep */ ++typedef struct _PS_CMD_ConfirmSleep ++{ ++ /** SDIO Length */ ++ u16 SDLen; ++ /** SDIO Type */ ++ u16 SDType; ++ /** Command */ ++ u16 Command; ++ /** Size */ ++ u16 Size; ++ /** Sequence number */ ++ u16 SeqNum; ++ /** Result */ ++ u16 Result; ++} __ATTRIB_PACK__ PS_CMD_ConfirmSleep, *PPS_CMD_ConfirmSleep; ++ ++/** Wlan Adapter data structure*/ ++struct _uap_adapter ++{ ++ /** Power save confirm sleep command */ ++ PS_CMD_ConfirmSleep PSConfirmSleep; ++ /** Device status */ ++ HARDWARE_STATUS HardwareStatus; ++ /** Interrupt counter */ ++ u32 IntCounter; ++ /** Tx packet queue */ ++ struct sk_buff_head tx_queue; ++ /** Cmd packet queue */ ++ struct sk_buff_head cmd_queue; ++ /** Command sequence number */ ++ u16 SeqNum; ++ /** Command buffer */ ++ u8 *CmdBuf; ++ /** cmd pending flag */ ++ u8 cmd_pending; ++ /** cmd wait option */ ++ u8 cmd_wait_option; ++ /** Command buffer length */ ++ u32 CmdSize; ++ /** Command wait queue */ ++ wait_queue_head_t cmdwait_q __ATTRIB_ALIGN__; ++ /** Command wait queue state flag */ ++ u8 CmdWaitQWoken; ++ /** PnP support */ ++ BOOLEAN SurpriseRemoved; ++ /** Debug */ ++ uap_dbg dbg; ++ /** Netlink kernel socket */ ++ struct sock *nl_sk; ++ /** Semaphore for CMD */ ++ SEMAPHORE CmdSem; ++ /** Power Save mode */ ++ u8 psmode; ++ /** Power Save state */ ++ u8 ps_state; ++ /** Number of wakeup tries */ ++ u32 WakeupTries; ++}; ++ ++static inline int ++os_upload_rx_packet(uap_private * priv, struct sk_buff *skb) ++{ ++ skb->dev = priv->uap_dev.netdev; ++ skb->protocol = eth_type_trans(skb, priv->uap_dev.netdev); ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ if (in_interrupt()) ++ netif_rx(skb); ++ else ++ netif_rx_ni(skb); ++ return 0; ++} ++ ++/* ++ * netif carrier_on/off and start(wake)/stop_queue handling ++ */ ++static inline void ++os_carrier_on(uap_private * priv) ++{ ++ if (!netif_carrier_ok(priv->uap_dev.netdev) && ++ (priv->MediaConnected == TRUE)) { ++ netif_carrier_on(priv->uap_dev.netdev); ++ } ++} ++ ++static inline void ++os_carrier_off(uap_private * priv) ++{ ++ if (netif_carrier_ok(priv->uap_dev.netdev)) { ++ netif_carrier_off(priv->uap_dev.netdev); ++ } ++} ++ ++static inline void ++os_start_queue(uap_private * priv) ++{ ++ if (netif_queue_stopped(priv->uap_dev.netdev) && ++ (priv->MediaConnected == TRUE)) { ++ netif_wake_queue(priv->uap_dev.netdev); ++ } ++} ++ ++static inline void ++os_stop_queue(uap_private * priv) ++{ ++ if (!netif_queue_stopped(priv->uap_dev.netdev)) { ++ netif_stop_queue(priv->uap_dev.netdev); ++ } ++} ++ ++/** Interface specific header */ ++#define INTF_HEADER_LEN 4 ++ ++/** headroom alignment for tx packet */ ++#define HEADER_ALIGNMENT 8 ++ ++/** The number of times to try when polling for status bits */ ++#define MAX_POLL_TRIES 100 ++ ++/** Length of SNAP header */ ++#define MRVDRV_SNAP_HEADER_LEN 8 ++ ++/** Extra length of Tx packet buffer */ ++#define EXTRA_LEN 36 ++ ++/** Buffer size for ethernet Tx packets */ ++#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \ ++ (ETH_FRAME_LEN + sizeof(TxPD) + EXTRA_LEN) ++ ++/** Buffer size for ethernet Rx packets */ ++#define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \ ++ (ETH_FRAME_LEN + sizeof(RxPD) \ ++ + MRVDRV_SNAP_HEADER_LEN + EXTRA_LEN) ++ ++/** Packet type: data, command & event */ ++typedef enum _mv_type ++{ ++ MV_TYPE_DAT = 0, ++ MV_TYPE_CMD = 1, ++ MV_TYPE_EVENT = 3 ++} mv_type; ++ ++/** Disable interrupt */ ++#define OS_INT_DISABLE spin_lock_irqsave(&priv->driver_lock, priv->driver_flags) ++/** Enable interrupt */ ++#define OS_INT_RESTORE spin_unlock_irqrestore(&priv->driver_lock, priv->driver_flags) ++ ++int uap_process_rx_packet(uap_private * priv, struct sk_buff *skb); ++void uap_interrupt(uap_private * priv); ++uap_private *uap_add_card(void *card); ++int uap_remove_card(void *card); ++int uap_process_event(uap_private * priv, u8 * payload, uint len); ++int uap_soft_reset(uap_private * priv); ++int uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len); ++ ++#ifdef CONFIG_PROC_FS ++/** The proc fs interface */ ++void uap_proc_entry(uap_private * priv, struct net_device *dev); ++void uap_proc_remove(uap_private * priv); ++int string_to_number(char *s); ++void uap_debug_entry(uap_private * priv, struct net_device *dev); ++void uap_debug_remove(uap_private * priv); ++#endif /* CONFIG_PROC_FS */ ++ ++int sbi_register(void); ++ ++void sbi_unregister(void); ++int sbi_register_dev(uap_private * priv); ++int sbi_unregister_dev(uap_private * priv); ++int sbi_prog_fw_w_helper(uap_private *); ++ ++int sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb); ++int sbi_enable_host_int(uap_private * priv); ++int sbi_disable_host_int(uap_private * priv); ++ ++int sbi_get_int_status(uap_private * priv, u8 * ireg); ++/** Check firmware status */ ++int sbi_check_fw_status(uap_private *, int); ++int sbi_prog_helper(uap_private *); ++ ++int sbi_wakeup_firmware(uap_private * priv); ++ ++#endif /* _UAP_DRV_H */ +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_fw.h backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_fw.h +--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_fw.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_fw.h 2014-12-29 20:37:43.949097590 +0100 +@@ -0,0 +1,359 @@ ++/** @file uap_fw.h ++ * ++ * @brief This file contains firmware specific defines. ++ * ++ * Copyright (C) 2008-2009, Marvell International Ltd. ++ * ++ * This software file (the "File") is distributed by Marvell International ++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 ++ * (the "License"). You may use, redistribute and/or modify this File in ++ * accordance with the terms and conditions of the License, a copy of which ++ * is available along with the File in the gpl.txt file or by writing to ++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++ * ++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ++ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about ++ * this warranty disclaimer. ++ * ++ */ ++/******************************************************** ++Change log: ++ 02/26/08: Initial creation ++********************************************************/ ++ ++#ifndef _UAP_FW_H ++#define _UAP_FW_H ++ ++/** uap upload size */ ++#define UAP_UPLD_SIZE 2312 ++/** Packet type Micro AP */ ++#define PKT_TYPE_MICROAP 1 ++/** Packet type client */ ++#define PKT_TYPE_CLIENT 0 ++ ++/** TxPD descriptor */ ++typedef struct _TxPD ++{ ++ /** Bss Type */ ++ u8 BssType; ++ /** Bss num */ ++ u8 BssNum; ++ /** Tx packet length */ ++ u16 TxPktLength; ++ /** Tx packet offset */ ++ u16 TxPktOffset; ++ /** Tx packet type */ ++ u16 TxPktType; ++ /** Tx Control */ ++ u32 TxControl; ++ /** reserved */ ++ u32 reserved[2]; ++} __ATTRIB_PACK__ TxPD, *PTxPD; ++ ++/** RxPD Descriptor */ ++typedef struct _RxPD ++{ ++ /** Bss Type */ ++ u8 BssType; ++ /** Bss Num */ ++ u8 BssNum; ++ /** Tx packet length */ ++ u16 RxPktLength; ++ /** Tx packet offset */ ++ u16 RxPktOffset; ++} __ATTRIB_PACK__ RxPD, *PRxPD; ++ ++#ifdef BIG_ENDIAN ++/** Convert from 16 bit little endian format to CPU format */ ++#define uap_le16_to_cpu(x) le16_to_cpu(x) ++/** Convert from 32 bit little endian format to CPU format */ ++#define uap_le32_to_cpu(x) le32_to_cpu(x) ++/** Convert from 64 bit little endian format to CPU format */ ++#define uap_le64_to_cpu(x) le64_to_cpu(x) ++/** Convert to 16 bit little endian format from CPU format */ ++#define uap_cpu_to_le16(x) cpu_to_le16(x) ++/** Convert to 32 bit little endian format from CPU format */ ++#define uap_cpu_to_le32(x) cpu_to_le32(x) ++/** Convert to 64 bit little endian format from CPU format */ ++#define uap_cpu_to_le64(x) cpu_to_le64(x) ++ ++/** Convert TxPD to little endian format from CPU format */ ++#define endian_convert_TxPD(x); \ ++ { \ ++ (x)->TxPktLength = uap_cpu_to_le16((x)->TxPktLength); \ ++ (x)->TxPktOffset = uap_cpu_to_le32((x)->TxPktOffset); \ ++ (x)->TxControl = uap_cpu_to_le32((x)->TxControl); \ ++ (x)->TxPktType = uap_cpu_to_le32((x)->TxPktType); \ ++ } ++ ++/** Convert RxPD from little endian format to CPU format */ ++#define endian_convert_RxPD(x); \ ++ { \ ++ (x)->RxPktLength = uap_le16_to_cpu((x)->RxPktLength); \ ++ (x)->RxPktOffset = uap_le32_to_cpu((x)->RxPktOffset); \ ++ } ++#else /* BIG_ENDIAN */ ++/** Do nothing */ ++#define uap_le16_to_cpu(x) x ++/** Do nothing */ ++#define uap_le32_to_cpu(x) x ++/** Do nothing */ ++#define uap_le64_to_cpu(x) x ++/** Do nothing */ ++#define uap_cpu_to_le16(x) x ++/** Do nothing */ ++#define uap_cpu_to_le32(x) x ++/** Do nothing */ ++#define uap_cpu_to_le64(x) x ++ ++/** Do nothing */ ++#define endian_convert_TxPD(x) ++/** Do nothing */ ++#define endian_convert_RxPD(x) ++#endif /* BIG_ENDIAN */ ++ ++/** Host Command ID : Function initialization */ ++#define HostCmd_CMD_FUNC_INIT 0x00a9 ++/** Host Command ID : Function shutdown */ ++#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa ++ ++/** Host Command id: SYS_INFO */ ++#define HOST_CMD_APCMD_SYS_INFO 0x00ae ++/** Host Command id: SYS_RESET */ ++#define HOST_CMD_APCMD_SYS_RESET 0x00af ++/** Host Command id: SYS_CONFIGURE */ ++#define HOST_CMD_APCMD_SYS_CONFIGURE 0x00b0 ++/** Host Command id: BSS_START */ ++#define HOST_CMD_APCMD_BSS_START 0x00b1 ++/** Host Command id: SYS_STOP */ ++#define HOST_CMD_APCMD_BSS_STOP 0x00b2 ++/** Host Command id: STA_LIST */ ++#define HOST_CMD_APCMD_STA_LIST 0x00b3 ++/** Host Command id: STA_FILTER_TABLE */ ++#define HOST_CMD_APCMD_STA_FILTER_TABLE 0x00b4 ++/** Host Command id: STA_DEAUTH */ ++#define HOST_CMD_APCMD_STA_DEAUTH 0x00b5 ++/** Host Command id: SOFT_RESET */ ++#define HOST_CMD_APCMD_SOFT_RESET 0x00d5 ++/** Host Command id: POWER_MGMT_EXT */ ++#define HOST_CMD_POWER_MGMT_EXT 0x00ef ++/** Host Command id: SLEEP_CONFIRM*/ ++#define HOST_CMD_SLEEP_CONFIRM 0x00d8 ++ ++/** TLV type : SSID */ ++#define TLV_TYPE_SSID 0x0000 ++/** TLV type : Rates */ ++#define TLV_TYPE_RATES 0x0001 ++/** TLV type : PHY DS */ ++#define TLV_TYPE_PHY_DS 0x0003 ++ ++/** TLV Id : Base id */ ++#define PROPRIETARY_TLV_BASE_ID 0x0100 ++/** TLV Id : AP_MAC_ADDRESS */ ++#define MRVL_AP_MAC_ADDRESS_TLV_ID (PROPRIETARY_TLV_BASE_ID + 43) ++/** TLV Id : Beacon period */ ++#define MRVL_BEACON_PERIOD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 44) ++/** TLV Id : Dtim period */ ++#define MRVL_DTIM_PERIOD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 45) ++/** TLV Id : Basic rates */ ++#define MRVL_BASIC_RATES_TLV_ID (PROPRIETARY_TLV_BASE_ID + 46) ++/** TLV Id : Tx Power */ ++#define MRVL_TX_POWER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 47) ++/** TLV Id : Broadcast SSID control */ ++#define MRVL_BCAST_SSID_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 48) ++/** TLV Id : Preamble control */ ++#define MRVL_PREAMBLE_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 49) ++/** TLV Id : Antenna control */ ++#define MRVL_ANTENNA_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 50) ++/** TLV Id : RTS threshold */ ++#define MRVL_RTS_THRESHOLD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 51) ++/** TLV Id : Radio control */ ++#define MRVL_RADIO_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 52) ++/** TLV Id : TX data rate */ ++#define MRVL_TX_DATA_RATE_TLV_ID (PROPRIETARY_TLV_BASE_ID + 53) ++/** TLV Id : Packet forward control */ ++#define MRVL_PKT_FWD_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 54) ++/** TLV Id : STA info */ ++#define MRVL_STA_INFO_TLV_ID (PROPRIETARY_TLV_BASE_ID + 55) ++/** TLV Id : STA MAC address filter */ ++#define MRVL_STA_MAC_ADDR_FILTER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 56) ++/** TLV Id : STA ageout timer */ ++#define MRVL_STA_AGEOUT_TIMER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 57) ++/** TLV Id : Security config */ ++#define MRVL_SECURITY_CFG_TLV_ID (PROPRIETARY_TLV_BASE_ID + 58) ++/** TLV Id : WEP KEY */ ++#define MRVL_WEP_KEY_TLV_ID (PROPRIETARY_TLV_BASE_ID + 59) ++/** TLV Id : WPA Passphrase */ ++#define MRVL_WPA_PASSPHRASE_TLV_ID (PROPRIETARY_TLV_BASE_ID + 60) ++ ++/** Action get */ ++#define ACTION_GET 0 ++/** Action set */ ++#define ACTION_SET 1 ++/** Length of ethernet address */ ++#ifndef ETH_ALEN ++#define ETH_ALEN 6 ++#endif ++ ++/** HostCmd_DS_GEN */ ++typedef struct ++{ ++ /** Command */ ++ u16 Command; ++ /** Size */ ++ u16 Size; ++ /** Sequence number */ ++ u16 SeqNum; ++ /** Result */ ++ u16 Result; ++} __ATTRIB_PACK__ HostCmd_DS_GEN; ++ ++/** Size of HostCmd_DS_GEN */ ++#define S_DS_GEN sizeof(HostCmd_DS_GEN) ++ ++/** _HostCmd_HEADER*/ ++typedef struct ++{ ++ /** Command Header : Command */ ++ u16 Command; ++ /** Command Header : Size */ ++ u16 Size; ++} __ATTRIB_PACK__ HostCmd_HEADER; ++ ++/** HostCmd_SYS_CONFIG */ ++typedef struct _HostCmd_SYS_CONFIG ++{ ++ /** CMD Action GET/SET*/ ++ u16 Action; ++ /** Tlv buffer */ ++ u8 TlvBuffer[0]; ++} __ATTRIB_PACK__ HostCmd_SYS_CONFIG; ++ ++/** HostCmd_DS_POWER_MGMT_EXT */ ++typedef struct _HostCmd_DS_POWER_MGMT_EXT ++{ ++ /** CMD Action Get/Set*/ ++ u16 action; ++ /** power mode */ ++ u16 power_mode; ++} __ATTRIB_PACK__ HostCmd_DS_POWER_MGMT_EXT; ++ ++/** _HostCmd_DS_COMMAND*/ ++typedef struct _HostCmd_DS_COMMAND ++{ ++ ++ /** Command Header : Command */ ++ u16 Command; ++ /** Command Header : Size */ ++ u16 Size; ++ /** Command Header : Sequence number */ ++ u16 SeqNum; ++ /** Command Header : Result */ ++ u16 Result; ++ /** Command Body */ ++ union ++ { ++ HostCmd_SYS_CONFIG sys_config; ++ HostCmd_DS_POWER_MGMT_EXT pm_cfg; ++ ++ } params; ++} __ATTRIB_PACK__ HostCmd_DS_COMMAND; ++ ++/** MrvlIEtypesHeader_*/ ++typedef struct _MrvlIEtypesHeader ++{ ++ /** Header type */ ++ u16 Type; ++ /** Header length */ ++ u16 Len; ++} __ATTRIB_PACK__ MrvlIEtypesHeader_t; ++ ++/** MrvlIEtypes_Data_t */ ++typedef struct _MrvlIEtypes_Data_t ++{ ++ /** Header */ ++ MrvlIEtypesHeader_t Header; ++ /** Data */ ++ u8 Data[1]; ++} __ATTRIB_PACK__ MrvlIEtypes_Data_t; ++ ++/** MrvlIEtypes_ChanListParamSet_t */ ++typedef struct _MrvlIEtypes_MacAddr_t ++{ ++ /** Header */ ++ MrvlIEtypesHeader_t Header; ++ /** AP MAC address */ ++ u8 ApMacAddr[ETH_ALEN]; ++} __ATTRIB_PACK__ MrvlIEtypes_MacAddr_t; ++ ++/** Event ID: BSS started */ ++#define MICRO_AP_EV_ID_BSS_START 46 ++ ++/** Event ID: BSS idle event */ ++#define MICRO_AP_EV_BSS_IDLE 67 ++ ++/** Event ID: BSS active event */ ++#define MICRO_AP_EV_BSS_ACTIVE 68 ++ ++/** Event ID: PS_AWAKE */ ++#define EVENT_PS_AWAKE 0x0a ++ ++/** Event ID: PS_SLEEP */ ++#define EVENT_PS_SLEEP 0x0b ++ ++/** PS_STATE */ ++typedef enum _PS_STATE ++{ ++ PS_STATE_AWAKE, ++ PS_STATE_PRE_SLEEP, ++ PS_STATE_SLEEP ++} PS_STATE; ++ ++/** TLV type: AP Sleep param */ ++#define TLV_TYPE_AP_SLEEP_PARAM (PROPRIETARY_TLV_BASE_ID + 106) ++/** TLV type: AP Inactivity Sleep param */ ++#define TLV_TYPE_AP_INACT_SLEEP_PARAM (PROPRIETARY_TLV_BASE_ID + 107) ++ ++/** MrvlIEtypes_sleep_param_t */ ++typedef struct _MrvlIEtypes_sleep_param_t ++{ ++ /** Header */ ++ MrvlIEtypesHeader_t header; ++ /** control bitmap */ ++ u32 ctrl_bitmap; ++ /** min_sleep */ ++ u32 min_sleep; ++ /** max_sleep */ ++ u32 max_sleep; ++} __ATTRIB_PACK__ MrvlIEtypes_sleep_param_t; ++ ++/** MrvlIEtypes_inact_sleep_param_t */ ++typedef struct _MrvlIEtypes_inact_sleep_param_t ++{ ++ /** Header */ ++ MrvlIEtypesHeader_t header; ++ /** inactivity timeout */ ++ u32 inactivity_to; ++ /** min_awake */ ++ u32 min_awake; ++ /** max_awake */ ++ u32 max_awake; ++} __ATTRIB_PACK__ MrvlIEtypes_inact_sleep_param_t; ++ ++/** AP_Event */ ++typedef struct _AP_Event ++{ ++ /** Event ID */ ++ u32 EventId; ++ /* ++ * Reserved for STA_ASSOCIATED event and contains ++ * status information for the MIC_COUNTERMEASURES event. ++ */ ++ /** Reserved/status */ ++ u16 status; ++ /** AP MAC address */ ++ u8 MacAddr[ETH_ALEN]; ++} __ATTRIB_PACK__ AP_Event; ++#endif /* _UAP_FW_H */ +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_headers.h backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_headers.h +--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_headers.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_headers.h 2014-12-29 20:37:43.949097590 +0100 +@@ -0,0 +1,64 @@ ++/** @file uap_headers.h ++ * ++ * @brief This file contains all the necessary include file. ++ * ++ * Copyright (C) 2008-2009, Marvell International Ltd. ++ * ++ * This software file (the "File") is distributed by Marvell International ++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 ++ * (the "License"). You may use, redistribute and/or modify this File in ++ * accordance with the terms and conditions of the License, a copy of which ++ * is available along with the File in the gpl.txt file or by writing to ++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++ * ++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ++ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about ++ * this warranty disclaimer. ++ * ++ */ ++#ifndef _UAP_HEADERS_H ++#define _UAP_HEADERS_H ++ ++/* Linux header files */ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/version.h> ++#include <linux/param.h> ++#include <linux/types.h> ++#include <linux/interrupt.h> ++#include <linux/proc_fs.h> ++#include <linux/kthread.h> ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) ++#include <linux/semaphore.h> ++#else ++#include <asm/semaphore.h> ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ++#include <linux/config.h> ++#endif ++ ++/* Net header files */ ++#include <linux/netdevice.h> ++#include <linux/net.h> ++#include <linux/skbuff.h> ++#include <linux/if_ether.h> ++#include <linux/etherdevice.h> ++#include <net/sock.h> ++#include <linux/netlink.h> ++#include <linux/firmware.h> ++#include <linux/delay.h> ++ ++#include "uap_drv.h" ++#include "uap_fw.h" ++ ++#include <linux/mmc/sdio.h> ++#include <linux/mmc/sdio_ids.h> ++#include <linux/mmc/sdio_func.h> ++#include <linux/mmc/card.h> ++#include "uap_sdio_mmc.h" ++ ++#endif /* _UAP_HEADERS_H */ +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_main.c backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_main.c +--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_main.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_main.c 2014-12-29 20:37:43.952431125 +0100 +@@ -0,0 +1,1817 @@ ++/** @file uap_main.c ++ * @brief This file contains the major functions in uAP ++ * driver. It includes init, exit etc.. ++ * This file also contains the initialization for SW, ++ * FW and HW ++ * ++ * Copyright (C) 2008-2009, Marvell International Ltd. ++ * ++ * This software file (the "File") is distributed by Marvell International ++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 ++ * (the "License"). You may use, redistribute and/or modify this File in ++ * accordance with the terms and conditions of the License, a copy of which ++ * is available along with the File in the gpl.txt file or by writing to ++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++ * ++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ++ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about ++ * this warranty disclaimer. ++ * ++ */ ++/** ++ * @mainpage uAP Linux Driver ++ * ++ * @section overview_sec Overview ++ * ++ * This is Linux reference driver for Marvell uAP. ++ * ++ * @section copyright_sec Copyright ++ * ++ * Copyright (C) 2008, Marvell International Ltd. ++ * ++ */ ++ ++#include "uap_headers.h" ++ ++/** ++ * the global variable of a pointer to uap_private ++ * structure variable ++ */ ++uap_private *uappriv = NULL; ++#ifdef DEBUG_LEVEL1 ++#define DEFAULT_DEBUG_MASK (DBG_MSG | DBG_FATAL | DBG_ERROR) ++u32 drvdbg = DEFAULT_DEBUG_MASK; ++#endif ++/** Helper name */ ++char *helper_name = NULL; ++/** Firmware name */ ++char *fw_name = NULL; ++ ++/** Semaphore for add/remove card */ ++SEMAPHORE AddRemoveCardSem; ++ ++/******************************************************** ++ Local Functions ++********************************************************/ ++/** ++ * @brief This function send sleep confirm command to firmware ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE ++ */ ++static int ++uap_dnld_sleep_confirm_cmd(uap_private * priv) ++{ ++ uap_adapter *Adapter = priv->adapter; ++ int ret = UAP_STATUS_SUCCESS; ++ ENTER(); ++ PRINTM(CMND, "Sleep confirm\n"); ++ Adapter->cmd_pending = TRUE; ++ Adapter->cmd_wait_option = HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM; ++ ret = ++ sbi_host_to_card(priv, (u8 *) & Adapter->PSConfirmSleep, ++ sizeof(PS_CMD_ConfirmSleep)); ++ if (ret != UAP_STATUS_SUCCESS) { ++ Adapter->ps_state = PS_STATE_AWAKE; ++ Adapter->cmd_pending = FALSE; ++ Adapter->cmd_wait_option = FALSE; ++ } ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function process sleep confirm resp from firmware ++ * ++ * @param priv A pointer to uap_private structure ++ * @param resp A pointer to resp buf ++ * @param resp_len resp buf len ++ * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE ++ */ ++int ++uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ HostCmd_DS_COMMAND *cmd; ++ uap_adapter *Adapter = priv->adapter; ++ ENTER(); ++ PRINTM(CMND, "Sleep confirm resp\n"); ++ if (!resp_len) { ++ PRINTM(ERROR, "Cmd Size is 0\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ cmd = (HostCmd_DS_COMMAND *) resp; ++ cmd->Result = uap_le16_to_cpu(cmd->Result); ++ if (cmd->Result != UAP_STATUS_SUCCESS) { ++ PRINTM(ERROR, "HOST_CMD_APCMD_PS_SLEEP_CONFIRM fail=%x\n", cmd->Result); ++ ret = -EFAULT; ++ } ++ done: ++ if (ret == UAP_STATUS_SUCCESS) ++ Adapter->ps_state = PS_STATE_SLEEP; ++ else ++ Adapter->ps_state = PS_STATE_AWAKE; ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function checks condition and prepares to ++ * send sleep confirm command to firmware if OK. ++ * ++ * @param priv A pointer to uap_private structure ++ * @return n/a ++ */ ++static void ++uap_ps_cond_check(uap_private * priv) ++{ ++ uap_adapter *Adapter = priv->adapter; ++ ++ ENTER(); ++ if (!priv->uap_dev.cmd_sent && ++ !Adapter->cmd_pending && !Adapter->IntCounter) { ++ uap_dnld_sleep_confirm_cmd(priv); ++ } else { ++ PRINTM(INFO, "Delay Sleep Confirm (%s%s%s)\n", ++ (priv->uap_dev.cmd_sent) ? "D" : "", ++ (Adapter->cmd_pending) ? "C" : "", ++ (Adapter->IntCounter) ? "I" : ""); ++ } ++ LEAVE(); ++} ++ ++/** ++ * @brief This function add cmd to cmdQ and waiting for response ++ * ++ * @param priv A pointer to uap_private structure ++ * @param skb A pointer to the skb for process ++ * @param wait_option Wait option ++ * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE ++ */ ++static int ++uap_process_cmd(uap_private * priv, struct sk_buff *skb, u8 wait_option) ++{ ++ uap_adapter *Adapter = priv->adapter; ++ int ret = UAP_STATUS_SUCCESS; ++ HostCmd_DS_COMMAND *cmd; ++ u8 *headptr; ++ ENTER(); ++ if (Adapter->HardwareStatus != HWReady) { ++ PRINTM(ERROR, "Hw not ready, uap_process_cmd\n"); ++ kfree(skb); ++ LEAVE(); ++ return -EFAULT; ++ } ++ skb->cb[0] = wait_option; ++ headptr = skb->data; ++ *(u16 *) & headptr[0] = uap_cpu_to_le16(skb->len); ++ *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_CMD); ++ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); ++ Adapter->SeqNum++; ++ cmd->SeqNum = uap_cpu_to_le16(Adapter->SeqNum); ++ PRINTM(CMND, "process_cmd: %x\n", cmd->Command); ++ DBG_HEXDUMP(CMD_D, "process_cmd", (u8 *) cmd, cmd->Size); ++ if (!wait_option) { ++ skb_queue_tail(&priv->adapter->cmd_queue, skb); ++ wake_up_interruptible(&priv->MainThread.waitQ); ++ LEAVE(); ++ return ret; ++ } ++ if (OS_ACQ_SEMAPHORE_BLOCK(&Adapter->CmdSem)) { ++ PRINTM(ERROR, "Acquire semaphore error, uap_prepare_cmd\n"); ++ kfree(skb); ++ LEAVE(); ++ return -EBUSY; ++ } ++ skb_queue_tail(&priv->adapter->cmd_queue, skb); ++ Adapter->CmdWaitQWoken = FALSE; ++ wake_up_interruptible(&priv->MainThread.waitQ); ++ /* Sleep until response is generated by FW */ ++ if (wait_option == HostCmd_OPTION_WAITFORRSP_TIMEOUT) { ++ if (!os_wait_interruptible_timeout ++ (Adapter->cmdwait_q, Adapter->CmdWaitQWoken, MRVDRV_TIMER_20S)) { ++ PRINTM(ERROR, "Cmd timeout\n"); ++ Adapter->cmd_pending = FALSE; ++ ret = -EFAULT; ++ } ++ } else ++ wait_event_interruptible(Adapter->cmdwait_q, Adapter->CmdWaitQWoken); ++ OS_REL_SEMAPHORE(&Adapter->CmdSem); ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief Inspect the response buffer for pointers to expected TLVs ++ * ++ * ++ * @param pTlv Pointer to the start of the TLV buffer to parse ++ * @param tlvBufSize Size of the TLV buffer ++ * @param reqTlvType request tlv's tlvtype ++ * @param ppTlv Output parameter: Pointer to the request TLV if found ++ * ++ * @return void ++ */ ++static void ++uap_get_tlv_ptrs(MrvlIEtypes_Data_t * pTlv, int tlvBufSize, ++ u16 reqTlvType, MrvlIEtypes_Data_t ** ppTlv) ++{ ++ MrvlIEtypes_Data_t *pCurrentTlv; ++ int tlvBufLeft; ++ u16 tlvType; ++ u16 tlvLen; ++ ++ ENTER(); ++ pCurrentTlv = pTlv; ++ tlvBufLeft = tlvBufSize; ++ *ppTlv = NULL; ++ PRINTM(INFO, "uap_get_tlv: tlvBufSize = %d, reqTlvType=%x\n", tlvBufSize, ++ reqTlvType); ++ while (tlvBufLeft >= sizeof(MrvlIEtypesHeader_t)) { ++ tlvType = uap_le16_to_cpu(pCurrentTlv->Header.Type); ++ tlvLen = uap_le16_to_cpu(pCurrentTlv->Header.Len); ++ if (reqTlvType == tlvType) ++ *ppTlv = (MrvlIEtypes_Data_t *) pCurrentTlv; ++ if (*ppTlv) { ++ HEXDUMP("TLV Buf", (u8 *) * ppTlv, tlvLen); ++ break; ++ } ++ tlvBufLeft -= (sizeof(pTlv->Header) + tlvLen); ++ pCurrentTlv = (MrvlIEtypes_Data_t *) (pCurrentTlv->Data + tlvLen); ++ } /* while */ ++ LEAVE(); ++} ++ ++/** ++ * @brief This function get mac ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS on success, otherwise failure code ++ */ ++static int ++uap_get_mac_address(uap_private * priv) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ u32 CmdSize; ++ HostCmd_DS_COMMAND *cmd; ++ uap_adapter *Adapter = priv->adapter; ++ struct sk_buff *skb; ++ MrvlIEtypes_MacAddr_t *pMacAddrTlv; ++ MrvlIEtypes_Data_t *pTlv; ++ u16 tlvBufSize; ++ ENTER(); ++ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); ++ if (!skb) { ++ PRINTM(ERROR, "No free skb\n"); ++ ret = -ENOMEM; ++ goto done; ++ } ++ CmdSize = ++ S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t); ++ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); ++ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE); ++ cmd->Size = uap_cpu_to_le16(CmdSize); ++ cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_GET); ++ pMacAddrTlv = ++ (MrvlIEtypes_MacAddr_t *) (skb->data + INTF_HEADER_LEN + S_DS_GEN + ++ sizeof(HostCmd_SYS_CONFIG)); ++ pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID); ++ pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN); ++ skb_put(skb, CmdSize + INTF_HEADER_LEN); ++ if (UAP_STATUS_SUCCESS != ++ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { ++ PRINTM(ERROR, "Fail to process cmd SYS_CONFIGURE Query\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ if (!Adapter->CmdSize) { ++ PRINTM(ERROR, "Cmd Size is 0\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf; ++ cmd->Result = uap_le16_to_cpu(cmd->Result); ++ if (cmd->Result != UAP_STATUS_SUCCESS) { ++ PRINTM(ERROR, "uap_get_mac_address fail=%x\n", cmd->Result); ++ ret = -EFAULT; ++ goto done; ++ } ++ pTlv = ++ (MrvlIEtypes_Data_t *) (Adapter->CmdBuf + S_DS_GEN + ++ sizeof(HostCmd_SYS_CONFIG)); ++ tlvBufSize = Adapter->CmdSize - S_DS_GEN - sizeof(HostCmd_SYS_CONFIG); ++ uap_get_tlv_ptrs(pTlv, tlvBufSize, MRVL_AP_MAC_ADDRESS_TLV_ID, ++ (MrvlIEtypes_Data_t **) & pMacAddrTlv); ++ if (pMacAddrTlv) { ++ memcpy(priv->uap_dev.netdev->dev_addr, pMacAddrTlv->ApMacAddr, ++ ETH_ALEN); ++ HEXDUMP("Original MAC addr", priv->uap_dev.netdev->dev_addr, ETH_ALEN); ++ } ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function checks the conditions and sends packet to device ++ * ++ * @param priv A pointer to uap_private structure ++ * @param skb A pointer to the skb for process ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++uap_process_tx(uap_private * priv, struct sk_buff *skb) ++{ ++ uap_adapter *Adapter = priv->adapter; ++ int ret = UAP_STATUS_SUCCESS; ++ TxPD *pLocalTxPD; ++ u8 *headptr; ++ struct sk_buff *newskb; ++ int newheadlen; ++ ENTER(); ++ ASSERT(skb); ++ if (!skb) { ++ LEAVE(); ++ return UAP_STATUS_FAILURE; ++ } ++ if (skb_headroom(skb) < (sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT)) { ++ newheadlen = sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT; ++ PRINTM(WARN, "Tx: Insufficient skb headroom %d\n", skb_headroom(skb)); ++ /* Insufficient skb headroom - allocate a new skb */ ++ newskb = skb_realloc_headroom(skb, newheadlen); ++ if (unlikely(newskb == NULL)) { ++ PRINTM(ERROR, "Tx: Cannot allocate skb\n"); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ kfree_skb(skb); ++ skb = newskb; ++ PRINTM(INFO, "new skb headroom %d\n", skb_headroom(skb)); ++ } ++ /* headptr should be aligned */ ++ headptr = skb->data - sizeof(TxPD) - INTF_HEADER_LEN; ++ headptr = (u8 *) ((u32) headptr & ~((u32) (HEADER_ALIGNMENT - 1))); ++ ++ pLocalTxPD = (TxPD *) (headptr + INTF_HEADER_LEN); ++ memset(pLocalTxPD, 0, sizeof(TxPD)); ++ pLocalTxPD->BssType = PKT_TYPE_MICROAP; ++ pLocalTxPD->TxPktLength = skb->len; ++ /* offset of actual data */ ++ pLocalTxPD->TxPktOffset = (long) skb->data - (long) pLocalTxPD; ++ endian_convert_TxPD(pLocalTxPD); ++ *(u16 *) & headptr[0] = ++ uap_cpu_to_le16(skb->len + ((long) skb->data - (long) headptr)); ++ *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_DAT); ++ ret = ++ sbi_host_to_card(priv, headptr, ++ skb->len + ((long) skb->data - (long) headptr)); ++ if (ret) { ++ PRINTM(ERROR, "uap_process_tx Error: sbi_host_to_card failed: 0x%X\n", ++ ret); ++ Adapter->dbg.num_tx_host_to_card_failure++; ++ goto done; ++ } ++ PRINTM(DATA, "Data => FW\n"); ++ DBG_HEXDUMP(DAT_D, "Tx", headptr, ++ MIN(skb->len + sizeof(TxPD), DATA_DUMP_LEN)); ++ done: ++ /* Freed skb */ ++ kfree_skb(skb); ++ LEAVE(); ++ return ret; ++} ++ ++static struct netlink_kernel_cfg cfg = { ++ .groups = NL_MULTICAST_GROUP, ++}; ++ ++/** ++ * @brief This function initializes the adapter structure ++ * and set default value to the member of adapter. ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++uap_init_sw(uap_private * priv) ++{ ++ uap_adapter *Adapter = priv->adapter; ++ ++ ENTER(); ++ ++ if (!(Adapter->CmdBuf = kmalloc(MRVDRV_SIZE_OF_CMD_BUFFER, GFP_KERNEL))) { ++ PRINTM(INFO, "Failed to allocate command buffer!\n"); ++ LEAVE(); ++ return UAP_STATUS_FAILURE; ++ } ++ ++ Adapter->cmd_pending = FALSE; ++ Adapter->CmdWaitQWoken = FALSE; ++ Adapter->ps_state = PS_STATE_AWAKE; ++ Adapter->WakeupTries = 0; ++ ++ memset(&Adapter->PSConfirmSleep, 0, sizeof(PS_CMD_ConfirmSleep)); ++ /** SDIO header */ ++ Adapter->PSConfirmSleep.SDLen = ++ uap_cpu_to_le16(sizeof(PS_CMD_ConfirmSleep)); ++ Adapter->PSConfirmSleep.SDType = uap_cpu_to_le16(MV_TYPE_CMD); ++ Adapter->PSConfirmSleep.SeqNum = 0; ++ Adapter->PSConfirmSleep.Command = uap_cpu_to_le16(HOST_CMD_SLEEP_CONFIRM); ++ Adapter->PSConfirmSleep.Size = uap_cpu_to_le16(sizeof(HostCmd_DS_GEN)); ++ Adapter->PSConfirmSleep.Result = 0; ++ ++ init_waitqueue_head(&Adapter->cmdwait_q); ++ OS_INIT_SEMAPHORE(&Adapter->CmdSem); ++ ++ skb_queue_head_init(&Adapter->tx_queue); ++ skb_queue_head_init(&Adapter->cmd_queue); ++ ++ /* Status variable */ ++ Adapter->HardwareStatus = HWInitializing; ++ ++ /* PnP support */ ++ Adapter->SurpriseRemoved = FALSE; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ++ Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL, ++ NL_MULTICAST_GROUP, NULL, ++ THIS_MODULE); ++#else ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ++ Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL, ++ NL_MULTICAST_GROUP, NULL, NULL, ++ THIS_MODULE); ++#else ++ Adapter->nl_sk = netlink_kernel_create(&init_net, NETLINK_MARVELL, &cfg); ++#endif ++#endif ++ if (!Adapter->nl_sk) { ++ PRINTM(ERROR, ++ "Could not initialize netlink event passing mechanism!\n"); ++ } ++ LEAVE(); ++ return UAP_STATUS_SUCCESS; ++} ++ ++/** ++ * @brief This function sends FUNC_INIT command to firmware ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS on success, otherwise failure code ++ */ ++static int ++uap_func_init(uap_private * priv) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ u32 CmdSize; ++ HostCmd_DS_GEN *cmd; ++ uap_adapter *Adapter = priv->adapter; ++ struct sk_buff *skb; ++ ENTER(); ++ if (Adapter->HardwareStatus != HWReady) { ++ PRINTM(ERROR, "uap_func_init:Hardware is not ready!\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); ++ if (!skb) { ++ PRINTM(ERROR, "No free skb\n"); ++ ret = -ENOMEM; ++ goto done; ++ } ++ CmdSize = sizeof(HostCmd_DS_GEN); ++ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); ++ cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_INIT); ++ cmd->Size = uap_cpu_to_le16(CmdSize); ++ skb_put(skb, CmdSize + INTF_HEADER_LEN); ++ PRINTM(CMND, "HostCmd_CMD_FUNC_INIT\n"); ++ if (UAP_STATUS_SUCCESS != ++ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { ++ PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_INIT\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function sends FUNC_SHUTDOWN command to firmware ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS on success, otherwise failure code ++ */ ++static int __exit ++uap_func_shutdown(uap_private * priv) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ u32 CmdSize; ++ HostCmd_DS_GEN *cmd; ++ uap_adapter *Adapter = priv->adapter; ++ struct sk_buff *skb; ++ ENTER(); ++ if (Adapter->HardwareStatus != HWReady) { ++ PRINTM(ERROR, "uap_func_shutdown:Hardware is not ready!\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); ++ if (!skb) { ++ PRINTM(ERROR, "No free skb\n"); ++ ret = -ENOMEM; ++ goto done; ++ } ++ CmdSize = sizeof(HostCmd_DS_GEN); ++ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); ++ cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_SHUTDOWN); ++ cmd->Size = uap_cpu_to_le16(CmdSize); ++ skb_put(skb, CmdSize + INTF_HEADER_LEN); ++ PRINTM(CMND, "HostCmd_CMD_FUNC_SHUTDOWN\n"); ++ if (UAP_STATUS_SUCCESS != ++ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { ++ PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_SHUTDOWN\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function initializes firmware ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++uap_init_fw(uap_private * priv) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ ENTER(); ++ sbi_disable_host_int(priv); ++ /* Check if firmware is already running */ ++ if (sbi_check_fw_status(priv, 1) == UAP_STATUS_SUCCESS) { ++ PRINTM(MSG, "UAP FW already running! Skip FW download\n"); ++ } else { ++ if ((ret = request_firmware(&priv->fw_helper, helper_name, ++ priv->hotplug_device)) < 0) { ++ PRINTM(FATAL, ++ "request_firmware() failed (helper), error code = %#x\n", ++ ret); ++ goto done; ++ } ++ ++ /* Download the helper */ ++ ret = sbi_prog_helper(priv); ++ ++ if (ret) { ++ PRINTM(FATAL, ++ "Bootloader in invalid state! Helper download failed!\n"); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ if ((ret = request_firmware(&priv->firmware, fw_name, ++ priv->hotplug_device)) < 0) { ++ PRINTM(FATAL, "request_firmware() failed, error code = %#x\n", ret); ++ goto done; ++ } ++ ++ /* Download the main firmware via the helper firmware */ ++ if (sbi_prog_fw_w_helper(priv)) { ++ PRINTM(FATAL, "UAP FW download failed!\n"); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ /* Check if the firmware is downloaded successfully or not */ ++ if (sbi_check_fw_status(priv, MAX_FIRMWARE_POLL_TRIES) == ++ UAP_STATUS_FAILURE) { ++ PRINTM(FATAL, "FW failed to be active in time!\n"); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ PRINTM(MSG, "UAP FW is active\n"); ++ } ++ sbi_enable_host_int(priv); ++ priv->adapter->HardwareStatus = HWReady; ++ if (uap_func_init(priv) != UAP_STATUS_SUCCESS) { ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ done: ++ if (priv->fw_helper) ++ release_firmware(priv->fw_helper); ++ if (priv->firmware) ++ release_firmware(priv->firmware); ++ LEAVE(); ++ return ret; ++ ++} ++ ++/** ++ * @brief This function frees the structure of adapter ++ * ++ * @param priv A pointer to uap_private structure ++ * @return n/a ++ */ ++static void ++uap_free_adapter(uap_private * priv) ++{ ++ uap_adapter *Adapter = priv->adapter; ++ ++ ENTER(); ++ ++ if (Adapter) { ++ if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) { ++ sock_release((Adapter->nl_sk)->sk_socket); ++ Adapter->nl_sk = NULL; ++ } ++ if (Adapter->CmdBuf) ++ kfree(Adapter->CmdBuf); ++ skb_queue_purge(&priv->adapter->tx_queue); ++ skb_queue_purge(&priv->adapter->cmd_queue); ++ /* Free the adapter object itself */ ++ kfree(Adapter); ++ priv->adapter = NULL; ++ } ++ ++ LEAVE(); ++} ++ ++/** ++ * @brief This function handles the major job in uap driver. ++ * it handles the event generated by firmware, rx data received ++ * from firmware and tx data sent from kernel. ++ * ++ * @param data A pointer to uap_thread structure ++ * @return BT_STATUS_SUCCESS ++ */ ++static int ++uap_service_main_thread(void *data) ++{ ++ uap_thread *thread = data; ++ uap_private *priv = thread->priv; ++ uap_adapter *Adapter = priv->adapter; ++ wait_queue_t wait; ++ u8 ireg = 0; ++ struct sk_buff *skb; ++ ENTER(); ++ uap_activate_thread(thread); ++ init_waitqueue_entry(&wait, current); ++ current->flags |= PF_NOFREEZE; ++ ++ for (;;) { ++ add_wait_queue(&thread->waitQ, &wait); ++ OS_SET_THREAD_STATE(TASK_INTERRUPTIBLE); ++ if ((Adapter->WakeupTries) || ++ (!Adapter->IntCounter && Adapter->ps_state == PS_STATE_PRE_SLEEP) || ++ (!priv->adapter->IntCounter ++ && (priv->uap_dev.data_sent || ++ skb_queue_empty(&priv->adapter->tx_queue)) ++ && (priv->uap_dev.cmd_sent || Adapter->cmd_pending || ++ skb_queue_empty(&priv->adapter->cmd_queue)) ++ )) { ++ PRINTM(INFO, "Main: Thread sleeping...\n"); ++ schedule(); ++ } ++ OS_SET_THREAD_STATE(TASK_RUNNING); ++ remove_wait_queue(&thread->waitQ, &wait); ++ if (kthread_should_stop() || Adapter->SurpriseRemoved) { ++ PRINTM(INFO, "main-thread: break from main thread: " ++ "SurpriseRemoved=0x%x\n", Adapter->SurpriseRemoved); ++ /* Cancel pending command */ ++ if (Adapter->cmd_pending == TRUE) { ++ /* Wake up cmd Q */ ++ Adapter->CmdWaitQWoken = TRUE; ++ wake_up_interruptible(&Adapter->cmdwait_q); ++ } ++ break; ++ } ++ ++ PRINTM(INFO, "Main: Thread waking up...\n"); ++ if (priv->adapter->IntCounter) { ++ OS_INT_DISABLE; ++ Adapter->IntCounter = 0; ++ OS_INT_RESTORE; ++ sbi_get_int_status(priv, &ireg); ++ } else if ((priv->adapter->ps_state == PS_STATE_SLEEP) && ++ (!skb_queue_empty(&priv->adapter->cmd_queue) || ++ !skb_queue_empty(&priv->adapter->tx_queue))) { ++ priv->adapter->WakeupTries++; ++ PRINTM(CMND, "%lu : Wakeup device...\n", os_time_get()); ++ sbi_wakeup_firmware(priv); ++ continue; ++ } ++ if (Adapter->ps_state == PS_STATE_PRE_SLEEP) ++ uap_ps_cond_check(priv); ++ ++ /* The PS state is changed during processing of Sleep Request event ++ above */ ++ if ((Adapter->ps_state == PS_STATE_SLEEP) || ++ (Adapter->ps_state == PS_STATE_PRE_SLEEP)) ++ continue; ++ /* Execute the next command */ ++ if (!priv->uap_dev.cmd_sent && !Adapter->cmd_pending && ++ (Adapter->HardwareStatus == HWReady)) { ++ if (!skb_queue_empty(&priv->adapter->cmd_queue)) { ++ skb = skb_dequeue(&priv->adapter->cmd_queue); ++ if (skb) { ++ Adapter->CmdSize = 0; ++ Adapter->cmd_pending = TRUE; ++ Adapter->cmd_wait_option = skb->cb[0]; ++ if (sbi_host_to_card(priv, skb->data, skb->len)) { ++ PRINTM(ERROR, "Cmd:sbi_host_to_card failed!\n"); ++ Adapter->cmd_pending = FALSE; ++ Adapter->dbg.num_cmd_host_to_card_failure++; ++ /* Wake up cmd Q */ ++ Adapter->CmdWaitQWoken = TRUE; ++ wake_up_interruptible(&Adapter->cmdwait_q); ++ } else { ++ if (Adapter->cmd_wait_option == ++ HostCmd_OPTION_WAITFORSEND) { ++ /* Wake up cmd Q */ ++ Adapter->CmdWaitQWoken = TRUE; ++ wake_up_interruptible(&Adapter->cmdwait_q); ++ Adapter->cmd_wait_option = FALSE; ++ } ++ } ++ kfree_skb(skb); ++ } ++ } ++ } ++ if (!priv->uap_dev.data_sent && (Adapter->HardwareStatus == HWReady)) { ++ if (!skb_queue_empty(&priv->adapter->tx_queue)) { ++ skb = skb_dequeue(&priv->adapter->tx_queue); ++ if (skb) { ++ if (uap_process_tx(priv, skb)) { ++ priv->stats.tx_dropped++; ++ priv->stats.tx_errors++; ++ os_start_queue(priv); ++ } else { ++ priv->stats.tx_packets++; ++ priv->stats.tx_bytes += skb->len; ++ } ++ ++ } ++ } ++ } ++ } ++ uap_deactivate_thread(thread); ++ LEAVE(); ++ return UAP_STATUS_SUCCESS; ++} ++ ++/** ++ * @brief uap hostcmd ioctl handler ++ * ++ * @param dev A pointer to net_device structure ++ * @param req A pointer to ifreq structure ++ * @return UAP_STATUS_SUCCESS --success, otherwise fail ++ */ ++/********* format of ifr_data *************/ ++/* buf_len + Hostcmd_body */ ++/* buf_len: 4 bytes */ ++/* the length of the buf which */ ++/* can be used to return data */ ++/* to application */ ++/* Hostcmd_body */ ++/*******************************************/ ++static int ++uap_hostcmd_ioctl(struct net_device *dev, struct ifreq *req) ++{ ++ u32 buf_len; ++ HostCmd_HEADER head; ++ uap_private *priv = (uap_private *) netdev_priv(dev); ++ uap_adapter *Adapter = priv->adapter; ++ int ret = UAP_STATUS_SUCCESS; ++ struct sk_buff *skb; ++ ++ ENTER(); ++ ++ /* Sanity check */ ++ if (req->ifr_data == NULL) { ++ PRINTM(ERROR, "uap_hostcmd_ioctl() corrupt data\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ if (copy_from_user(&buf_len, req->ifr_data, sizeof(buf_len))) { ++ PRINTM(ERROR, "Copy from user failed\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ memset(&head, 0, sizeof(HostCmd_HEADER)); ++ /* Get the command size from user space */ ++ if (copy_from_user ++ (&head, req->ifr_data + sizeof(buf_len), sizeof(HostCmd_HEADER))) { ++ PRINTM(ERROR, "Copy from user failed\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ head.Size = uap_le16_to_cpu(head.Size); ++ if (head.Size > MRVDRV_SIZE_OF_CMD_BUFFER) { ++ PRINTM(ERROR, "CmdSize too big=%d\n", head.Size); ++ LEAVE(); ++ return -EFAULT; ++ } ++ PRINTM(CMND, "ioctl: hostcmd=%x, size=%d,buf_len=%d\n", head.Command, ++ head.Size, buf_len); ++ skb = dev_alloc_skb(head.Size + INTF_HEADER_LEN); ++ if (!skb) { ++ PRINTM(ERROR, "No free skb\n"); ++ LEAVE(); ++ return -ENOMEM; ++ } ++ ++ /* Get the command from user space */ ++ if (copy_from_user ++ (skb->data + INTF_HEADER_LEN, req->ifr_data + sizeof(buf_len), ++ head.Size)) { ++ PRINTM(ERROR, "Copy from user failed\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ skb_put(skb, head.Size + INTF_HEADER_LEN); ++ if (UAP_STATUS_SUCCESS != ++ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) { ++ PRINTM(ERROR, "Fail to process cmd\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ if (!Adapter->CmdSize) { ++ PRINTM(ERROR, "Cmd Size is 0\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ if (Adapter->CmdSize > buf_len) { ++ PRINTM(ERROR, "buf_len is too small\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ /* Copy to user */ ++ if (copy_to_user ++ (req->ifr_data + sizeof(buf_len), Adapter->CmdBuf, Adapter->CmdSize)) { ++ PRINTM(ERROR, "Copy to user failed!\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief uap power mode ioctl handler ++ * ++ * @param dev A pointer to net_device structure ++ * @param req A pointer to ifreq structure ++ * @return UAP_STATUS_SUCCESS --success, otherwise fail ++ */ ++static int ++uap_power_mode_ioctl(struct net_device *dev, struct ifreq *req) ++{ ++ ps_mgmt pm_cfg; ++ int ret = UAP_STATUS_SUCCESS; ++ uap_private *priv = (uap_private *) netdev_priv(dev); ++ uap_adapter *Adapter = priv->adapter; ++ struct sk_buff *skb = NULL; ++ HostCmd_DS_COMMAND *cmd; ++ u32 CmdSize; ++ u8 *tlv = NULL; ++ MrvlIEtypes_sleep_param_t *sleep_tlv = NULL; ++ MrvlIEtypes_inact_sleep_param_t *inact_tlv = NULL; ++ u16 tlv_buf_left = 0; ++ MrvlIEtypesHeader_t *tlvbuf = NULL; ++ u16 tlv_type = 0; ++ u16 tlv_len = 0; ++ ++ ENTER(); ++ ++ /* Sanity check */ ++ if (req->ifr_data == NULL) { ++ PRINTM(ERROR, "uap_power_mode_ioctl() corrupt data\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ ++ memset(&pm_cfg, 0, sizeof(ps_mgmt)); ++ if (copy_from_user(&pm_cfg, req->ifr_data, sizeof(ps_mgmt))) { ++ PRINTM(ERROR, "Copy from user failed\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ PRINTM(CMND, ++ "ioctl power: flag=0x%x ps_mode=%d ctrl_bitmap=%d min_sleep=%d max_sleep=%d " ++ "inact_to=%d min_awake=%d max_awake=%d\n", pm_cfg.flags, ++ (int) pm_cfg.ps_mode, (int) pm_cfg.sleep_param.ctrl_bitmap, ++ (int) pm_cfg.sleep_param.min_sleep, ++ (int) pm_cfg.sleep_param.max_sleep, ++ (int) pm_cfg.inact_param.inactivity_to, ++ (int) pm_cfg.inact_param.min_awake, ++ (int) pm_cfg.inact_param.max_awake); ++ ++ if (pm_cfg. ++ flags & ~(PS_FLAG_PS_MODE | PS_FLAG_SLEEP_PARAM | ++ PS_FLAG_INACT_SLEEP_PARAM)) { ++ PRINTM(ERROR, "Invalid parameter: flags = 0x%x\n", pm_cfg.flags); ++ ret = -EINVAL; ++ goto done; ++ } ++ if (pm_cfg.ps_mode > PS_MODE_INACTIVITY) { ++ PRINTM(ERROR, "Invalid parameter: ps_mode = %d\n", (int) pm_cfg.flags); ++ ret = -EINVAL; ++ goto done; ++ } ++ ++ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); ++ if (!skb) { ++ PRINTM(INFO, "No free skb\n"); ++ ret = -ENOMEM; ++ goto done; ++ } ++ ++ CmdSize = S_DS_GEN + sizeof(HostCmd_DS_POWER_MGMT_EXT); ++ ++ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); ++ cmd->Command = uap_cpu_to_le16(HOST_CMD_POWER_MGMT_EXT); ++ if (!pm_cfg.flags) { ++ cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_GET); ++ } else { ++ cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_SET); ++ cmd->params.pm_cfg.power_mode = uap_cpu_to_le16(pm_cfg.ps_mode); ++ tlv = (u8 *) & cmd->params.pm_cfg + sizeof(HostCmd_DS_POWER_MGMT_EXT); ++ ++ if ((pm_cfg.ps_mode) && (pm_cfg.flags & PS_FLAG_SLEEP_PARAM)) { ++ sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlv; ++ sleep_tlv->header.Type = uap_cpu_to_le16(TLV_TYPE_AP_SLEEP_PARAM); ++ sleep_tlv->header.Len = ++ uap_cpu_to_le16(sizeof(MrvlIEtypes_sleep_param_t) - ++ sizeof(MrvlIEtypesHeader_t)); ++ sleep_tlv->ctrl_bitmap = ++ uap_cpu_to_le32(pm_cfg.sleep_param.ctrl_bitmap); ++ sleep_tlv->min_sleep = ++ uap_cpu_to_le32(pm_cfg.sleep_param.min_sleep); ++ sleep_tlv->max_sleep = ++ uap_cpu_to_le32(pm_cfg.sleep_param.max_sleep); ++ CmdSize += sizeof(MrvlIEtypes_sleep_param_t); ++ tlv += sizeof(MrvlIEtypes_sleep_param_t); ++ } ++ if ((pm_cfg.ps_mode == PS_MODE_INACTIVITY) && ++ (pm_cfg.flags & PS_FLAG_INACT_SLEEP_PARAM)) { ++ inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlv; ++ inact_tlv->header.Type = ++ uap_cpu_to_le16(TLV_TYPE_AP_INACT_SLEEP_PARAM); ++ inact_tlv->header.Len = ++ uap_cpu_to_le16(sizeof(MrvlIEtypes_inact_sleep_param_t) - ++ sizeof(MrvlIEtypesHeader_t)); ++ inact_tlv->inactivity_to = ++ uap_cpu_to_le32(pm_cfg.inact_param.inactivity_to); ++ inact_tlv->min_awake = ++ uap_cpu_to_le32(pm_cfg.inact_param.min_awake); ++ inact_tlv->max_awake = ++ uap_cpu_to_le32(pm_cfg.inact_param.max_awake); ++ CmdSize += sizeof(MrvlIEtypes_inact_sleep_param_t); ++ tlv += sizeof(MrvlIEtypes_inact_sleep_param_t); ++ } ++ } ++ cmd->Size = uap_cpu_to_le16(CmdSize); ++ skb_put(skb, CmdSize + INTF_HEADER_LEN); ++ if (UAP_STATUS_SUCCESS != ++ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) { ++ PRINTM(ERROR, "Fail to process cmd POWER_MODE\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ if (!Adapter->CmdSize) { ++ PRINTM(ERROR, "Cmd Size is 0\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf; ++ cmd->Result = uap_le16_to_cpu(cmd->Result); ++ if (cmd->Result != UAP_STATUS_SUCCESS) { ++ PRINTM(ERROR, "HOST_CMD_APCMD_POWER_MODE fail=%x\n", cmd->Result); ++ ret = -EFAULT; ++ goto done; ++ } ++ if (pm_cfg.flags) { ++ Adapter->psmode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode); ++ } else { ++ pm_cfg.flags = PS_FLAG_PS_MODE; ++ pm_cfg.ps_mode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode); ++ tlv_buf_left = ++ cmd->Size - (sizeof(HostCmd_DS_POWER_MGMT_EXT) + S_DS_GEN); ++ tlvbuf = ++ (MrvlIEtypesHeader_t *) ((u8 *) & cmd->params.pm_cfg + ++ sizeof(HostCmd_DS_POWER_MGMT_EXT)); ++ while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) { ++ tlv_type = uap_le16_to_cpu(tlvbuf->Type); ++ tlv_len = uap_le16_to_cpu(tlvbuf->Len); ++ switch (tlv_type) { ++ case TLV_TYPE_AP_SLEEP_PARAM: ++ sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlvbuf; ++ pm_cfg.flags |= PS_FLAG_SLEEP_PARAM; ++ pm_cfg.sleep_param.ctrl_bitmap = ++ uap_le32_to_cpu(sleep_tlv->ctrl_bitmap); ++ pm_cfg.sleep_param.min_sleep = ++ uap_le32_to_cpu(sleep_tlv->min_sleep); ++ pm_cfg.sleep_param.max_sleep = ++ uap_le32_to_cpu(sleep_tlv->max_sleep); ++ break; ++ case TLV_TYPE_AP_INACT_SLEEP_PARAM: ++ inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlvbuf; ++ pm_cfg.flags |= PS_FLAG_INACT_SLEEP_PARAM; ++ pm_cfg.inact_param.inactivity_to = ++ uap_le32_to_cpu(inact_tlv->inactivity_to); ++ pm_cfg.inact_param.min_awake = ++ uap_le32_to_cpu(inact_tlv->min_awake); ++ pm_cfg.inact_param.max_awake = ++ uap_le32_to_cpu(inact_tlv->max_awake); ++ break; ++ } ++ tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t); ++ tlvbuf = ++ (MrvlIEtypesHeader_t *) ((u8 *) tlvbuf + tlv_len + ++ sizeof(MrvlIEtypesHeader_t)); ++ } ++ /* Copy to user */ ++ if (copy_to_user(req->ifr_data, &pm_cfg, sizeof(ps_mgmt))) { ++ PRINTM(ERROR, "Copy to user failed!\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ } ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function send bss_stop command to firmware ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS on success, otherwise failure code ++ */ ++static int ++uap_bss_stop(uap_private * priv) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ u32 CmdSize; ++ HostCmd_DS_GEN *cmd; ++ uap_adapter *Adapter = priv->adapter; ++ struct sk_buff *skb; ++ ENTER(); ++ if (Adapter->HardwareStatus != HWReady) { ++ PRINTM(ERROR, "uap_bss_stop:Hardware is not ready!\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); ++ if (!skb) { ++ PRINTM(ERROR, "No free skb\n"); ++ ret = -ENOMEM; ++ goto done; ++ } ++ CmdSize = sizeof(HostCmd_DS_GEN); ++ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); ++ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_BSS_STOP); ++ cmd->Size = uap_cpu_to_le16(CmdSize); ++ skb_put(skb, CmdSize + INTF_HEADER_LEN); ++ PRINTM(CMND, "APCMD_BSS_STOP\n"); ++ if (UAP_STATUS_SUCCESS != ++ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { ++ PRINTM(ERROR, "Fail to process cmd BSS_STOP\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/******************************************************** ++ Global Functions ++********************************************************/ ++/** ++ * @brief This function send soft_reset command to firmware ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS on success, otherwise failure code ++ */ ++int ++uap_soft_reset(uap_private * priv) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ u32 CmdSize; ++ HostCmd_DS_GEN *cmd; ++ uap_adapter *Adapter = priv->adapter; ++ struct sk_buff *skb; ++ ENTER(); ++ ret = uap_bss_stop(priv); ++ if (ret != UAP_STATUS_SUCCESS) ++ goto done; ++ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); ++ if (!skb) { ++ PRINTM(ERROR, "No free skb\n"); ++ ret = -ENOMEM; ++ goto done; ++ } ++ CmdSize = sizeof(HostCmd_DS_GEN); ++ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); ++ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SOFT_RESET); ++ cmd->Size = uap_cpu_to_le16(CmdSize); ++ skb_put(skb, CmdSize + INTF_HEADER_LEN); ++ PRINTM(CMND, "APCMD_SOFT_RESET\n"); ++ if (UAP_STATUS_SUCCESS != ++ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORSEND)) { ++ PRINTM(ERROR, "Fail to process cmd SOFT_RESET\n"); ++ ret = -EFAULT; ++ goto done; ++ } ++ Adapter->SurpriseRemoved = TRUE; ++ /* delay to allow hardware complete reset */ ++ os_sched_timeout(5); ++ if (priv->MediaConnected == TRUE) { ++ os_stop_queue(priv); ++ os_carrier_off(priv); ++ priv->MediaConnected = FALSE; ++ } ++ Adapter->CmdSize = 0; ++ Adapter->CmdWaitQWoken = TRUE; ++ wake_up_interruptible(&Adapter->cmdwait_q); ++ skb_queue_purge(&priv->adapter->tx_queue); ++ skb_queue_purge(&priv->adapter->cmd_queue); ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function processes received packet and forwards it ++ * to kernel/upper layer ++ * ++ * @param priv A pointer to uap_private ++ * @param skb A pointer to skb which includes the received packet ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++uap_process_rx_packet(uap_private * priv, struct sk_buff *skb) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ RxPD *pRxPD; ++ ENTER(); ++ priv->adapter->ps_state = PS_STATE_AWAKE; ++ pRxPD = (RxPD *) skb->data; ++ endian_convert_RxPD(pRxPD); ++ DBG_HEXDUMP(DAT_D, "Rx", skb->data, MIN(skb->len, DATA_DUMP_LEN)); ++ skb_pull(skb, pRxPD->RxPktOffset); ++ priv->stats.rx_packets++; ++ priv->stats.rx_bytes += skb->len; ++ os_upload_rx_packet(priv, skb); ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function opens the network device ++ * ++ * @param dev A pointer to net_device structure ++ * @return UAP_STATUS_SUCCESS ++ */ ++static int ++uap_open(struct net_device *dev) ++{ ++ uap_private *priv = (uap_private *) (uap_private *) netdev_priv(dev); ++ uap_adapter *Adapter = priv->adapter; ++ int i = 0; ++ ++ ENTER(); ++ ++ /* On some systems the device open handler will be called before HW ready. */ ++ /* Use the following flag check and wait function to work around the issue. */ ++ while ((Adapter->HardwareStatus != HWReady) && ++ (i < MAX_WAIT_DEVICE_READY_COUNT)) { ++ i++; ++ os_sched_timeout(100); ++ } ++ if (i >= MAX_WAIT_DEVICE_READY_COUNT) { ++ PRINTM(FATAL, "HW not ready, uap_open() return failure\n"); ++ LEAVE(); ++ return UAP_STATUS_FAILURE; ++ } ++ ++ if (MODULE_GET == 0) ++ return UAP_STATUS_FAILURE; ++ ++ priv->open = TRUE; ++ if (priv->MediaConnected == TRUE) { ++ os_carrier_on(priv); ++ os_start_queue(priv); ++ } else { ++ os_stop_queue(priv); ++ os_carrier_off(priv); ++ } ++ LEAVE(); ++ return UAP_STATUS_SUCCESS; ++} ++ ++/** ++ * @brief This function closes the network device ++ * ++ * @param dev A pointer to net_device structure ++ * @return UAP_STATUS_SUCCESS ++ */ ++static int ++uap_close(struct net_device *dev) ++{ ++ uap_private *priv = (uap_private *) netdev_priv(dev); ++ ++ ENTER(); ++ skb_queue_purge(&priv->adapter->tx_queue); ++ os_stop_queue(priv); ++ os_carrier_off(priv); ++ ++ MODULE_PUT; ++ priv->open = FALSE; ++ LEAVE(); ++ return UAP_STATUS_SUCCESS; ++} ++ ++/** ++ * @brief This function returns the network statistics ++ * ++ * @param dev A pointer to uap_private structure ++ * @return A pointer to net_device_stats structure ++ */ ++static struct net_device_stats * ++uap_get_stats(struct net_device *dev) ++{ ++ uap_private *priv = (uap_private *) netdev_priv(dev); ++ ++ return &priv->stats; ++} ++ ++/** ++ * @brief This function sets the MAC address to firmware. ++ * ++ * @param dev A pointer to uap_private structure ++ * @param addr MAC address to set ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++uap_set_mac_address(struct net_device *dev, void *addr) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ uap_private *priv = (uap_private *) netdev_priv(dev); ++ struct sockaddr *pHwAddr = (struct sockaddr *) addr; ++ u32 CmdSize; ++ HostCmd_DS_COMMAND *cmd; ++ MrvlIEtypes_MacAddr_t *pMacAddrTlv; ++ uap_adapter *Adapter = priv->adapter; ++ struct sk_buff *skb; ++ ++ ENTER(); ++ ++ /* Dump MAC address */ ++ DBG_HEXDUMP(CMD_D, "Original MAC addr", dev->dev_addr, ETH_ALEN); ++ DBG_HEXDUMP(CMD_D, "New MAC addr", pHwAddr->sa_data, ETH_ALEN); ++ if (priv->open && (priv->MediaConnected == TRUE)) { ++ os_carrier_on(priv); ++ os_start_queue(priv); ++ } ++ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); ++ if (!skb) { ++ PRINTM(ERROR, "No free skb\n"); ++ LEAVE(); ++ return -ENOMEM; ++ } ++ CmdSize = ++ S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t); ++ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); ++ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE); ++ cmd->Size = uap_cpu_to_le16(CmdSize); ++ cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_SET); ++ pMacAddrTlv = ++ (MrvlIEtypes_MacAddr_t *) ((u8 *) cmd + S_DS_GEN + ++ sizeof(HostCmd_SYS_CONFIG)); ++ pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID); ++ pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN); ++ memcpy(pMacAddrTlv->ApMacAddr, pHwAddr->sa_data, ETH_ALEN); ++ skb_put(skb, CmdSize + INTF_HEADER_LEN); ++ PRINTM(CMND, "set_mac_address\n"); ++ if (UAP_STATUS_SUCCESS != ++ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { ++ PRINTM(ERROR, "Fail to set mac address\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ if (!Adapter->CmdSize) { ++ PRINTM(ERROR, "Cmd Size is 0\n"); ++ LEAVE(); ++ return -EFAULT; ++ } ++ cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf; ++ cmd->Result = uap_cpu_to_le16(cmd->Result); ++ if (cmd->Result != UAP_STATUS_SUCCESS) { ++ PRINTM(ERROR, "set mac addrress fail,cmd result=%x\n", cmd->Result); ++ ret = -EFAULT; ++ } else ++ memcpy(dev->dev_addr, pHwAddr->sa_data, ETH_ALEN); ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function handles the timeout of packet ++ * transmission ++ * ++ * @param dev A pointer to net_device structure ++ * @return n/a ++ */ ++static void ++uap_tx_timeout(struct net_device *dev) ++{ ++ uap_private *priv = (uap_private *) netdev_priv(dev); ++ ++ ENTER(); ++ ++ PRINTM(DATA, "Tx timeout\n"); ++ UpdateTransStart(dev); ++ priv->num_tx_timeout++; ++ priv->adapter->IntCounter++; ++ wake_up_interruptible(&priv->MainThread.waitQ); ++ ++ LEAVE(); ++} ++ ++/** ++ * @brief This function handles packet transmission ++ * ++ * @param skb A pointer to sk_buff structure ++ * @param dev A pointer to net_device structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++uap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ uap_private *priv = (uap_private *) netdev_priv(dev); ++ int ret = UAP_STATUS_SUCCESS; ++ ++ ENTER(); ++ PRINTM(DATA, "Data <= kernel\n"); ++ DBG_HEXDUMP(DAT_D, "Tx", skb->data, MIN(skb->len, DATA_DUMP_LEN)); ++ /* skb sanity check */ ++ if (!skb->len || (skb->len > MRVDRV_MAXIMUM_ETH_PACKET_SIZE)) { ++ PRINTM(ERROR, "Tx Error: Bad skb length %d : %d\n", skb->len, ++ MRVDRV_MAXIMUM_ETH_PACKET_SIZE); ++ priv->stats.tx_dropped++; ++ kfree(skb); ++ goto done; ++ } ++ skb_queue_tail(&priv->adapter->tx_queue, skb); ++ wake_up_interruptible(&priv->MainThread.waitQ); ++ if (skb_queue_len(&priv->adapter->tx_queue) > TX_HIGH_WATERMARK) { ++ UpdateTransStart(dev); ++ os_stop_queue(priv); ++ } ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief ioctl function - entry point ++ * ++ * @param dev A pointer to net_device structure ++ * @param req A pointer to ifreq structure ++ * @param cmd command ++ * @return UAP_STATUS_SUCCESS--success, otherwise fail ++ */ ++static int ++uap_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ ++ ENTER(); ++ ++ PRINTM(CMND, "uap_do_ioctl: ioctl cmd = 0x%x\n", cmd); ++ ++ switch (cmd) { ++ case UAPHOSTCMD: ++ ret = uap_hostcmd_ioctl(dev, req); ++ break; ++ case UAP_POWER_MODE: ++ ret = uap_power_mode_ioctl(dev, req); ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function handles events generated by firmware ++ * ++ * @param priv A pointer to uap_private structure ++ * @param payload A pointer to payload buffer ++ * @param len Length of the payload ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++uap_process_event(uap_private * priv, u8 * payload, uint len) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ uap_adapter *Adapter = priv->adapter; ++ struct sk_buff *skb = NULL; ++ struct nlmsghdr *nlh = NULL; ++ struct sock *sk = Adapter->nl_sk; ++ AP_Event *pEvent; ++ ++ ENTER(); ++ Adapter->ps_state = PS_STATE_AWAKE; ++ if (len > NL_MAX_PAYLOAD) { ++ PRINTM(ERROR, "event size is too big!!! len=%d\n", len); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ pEvent = (AP_Event *) payload; ++ PRINTM(CMND, "Event: %d\n", pEvent->EventId); ++ switch (pEvent->EventId) { ++ case MICRO_AP_EV_ID_BSS_START: ++ memcpy(priv->uap_dev.netdev->dev_addr, pEvent->MacAddr, ETH_ALEN); ++ DBG_HEXDUMP(CMD_D, "BSS MAC addr", priv->uap_dev.netdev->dev_addr, ++ ETH_ALEN); ++ break; ++ case MICRO_AP_EV_BSS_ACTIVE: ++ // carrier on ++ priv->MediaConnected = TRUE; ++ os_carrier_on(priv); ++ os_start_queue(priv); ++ break; ++ case MICRO_AP_EV_BSS_IDLE: ++ os_stop_queue(priv); ++ os_carrier_off(priv); ++ priv->MediaConnected = FALSE; ++ break; ++ case EVENT_PS_AWAKE: ++ PRINTM(CMND, "UAP: PS_AWAKE\n"); ++ Adapter->ps_state = PS_STATE_AWAKE; ++ Adapter->WakeupTries = 0; ++ break; ++ case EVENT_PS_SLEEP: ++ PRINTM(CMND, "UAP: PS_SLEEP\n"); ++ Adapter->ps_state = PS_STATE_PRE_SLEEP; ++ break; ++ default: ++ break; ++ } ++ if ((pEvent->EventId == EVENT_PS_AWAKE) || ++ (pEvent->EventId == EVENT_PS_SLEEP)) ++ goto done; ++ if (sk) { ++ /* Allocate skb */ ++ if (!(skb = alloc_skb(NLMSG_SPACE(NL_MAX_PAYLOAD), GFP_ATOMIC))) { ++ PRINTM(ERROR, "Could not allocate skb for netlink.\n"); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ nlh = (struct nlmsghdr *) skb->data; ++ nlh->nlmsg_len = NLMSG_SPACE(len); ++ ++ /* From kernel */ ++ nlh->nlmsg_pid = 0; ++ nlh->nlmsg_flags = 0; ++ ++ /* Data */ ++ skb_put(skb, nlh->nlmsg_len); ++ memcpy(NLMSG_DATA(nlh), payload, len); ++ ++ /* From Kernel */ ++ NETLINK_CB(skb).portid = 0; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ++ /* Multicast message */ ++ NETLINK_CB(skb).dst_pid = 0; ++#endif ++ ++ /* Multicast group number */ ++ NETLINK_CB(skb).dst_group = NL_MULTICAST_GROUP; ++ ++ /* Send message */ ++ netlink_broadcast(sk, skb, 0, NL_MULTICAST_GROUP, GFP_KERNEL); ++ ++ ret = UAP_STATUS_SUCCESS; ++ } else { ++ PRINTM(ERROR, "Could not send event through NETLINK. Link down.\n"); ++ ret = UAP_STATUS_FAILURE; ++ } ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function handles the interrupt. it will change PS ++ * state if applicable. it will wake up main_thread to handle ++ * the interrupt event as well. ++ * ++ * @param priv A pointer to uap_private structure ++ * @return n/a ++ */ ++void ++uap_interrupt(uap_private * priv) ++{ ++ ENTER(); ++ priv->adapter->IntCounter++; ++ priv->adapter->WakeupTries = 0; ++ PRINTM(INFO, "*\n"); ++ wake_up_interruptible(&priv->MainThread.waitQ); ++ ++ LEAVE(); ++ ++} ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) ++/** Network device handlers */ ++static const struct net_device_ops uap_netdev_ops = { ++ .ndo_open = uap_open, ++ .ndo_start_xmit = uap_hard_start_xmit, ++ .ndo_stop = uap_close, ++ .ndo_do_ioctl = uap_do_ioctl, ++ .ndo_set_mac_address = uap_set_mac_address, ++ .ndo_tx_timeout = uap_tx_timeout, ++ .ndo_get_stats = uap_get_stats, ++}; ++#endif ++ ++/** ++ * @brief This function adds the card. it will probe the ++ * card, allocate the uap_priv and initialize the device. ++ * ++ * @param card A pointer to card ++ * @return A pointer to uap_private structure ++ */ ++uap_private * ++uap_add_card(void *card) ++{ ++ struct net_device *dev = NULL; ++ uap_private *priv = NULL; ++ ++ ENTER(); ++ ++ if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) ++ goto exit_sem_err; ++ ++ /* Allocate an Ethernet device */ ++ if (!(dev = alloc_etherdev(sizeof(uap_private)))) { ++ PRINTM(FATAL, "Init ethernet device failed!\n"); ++ goto error; ++ } ++ priv = (uap_private *) netdev_priv(dev); ++ ++ /* Allocate name */ ++ if (dev_alloc_name(dev, "uap%d") < 0) { ++ PRINTM(ERROR, "Could not allocate device name!\n"); ++ goto error; ++ } ++ ++ /* Allocate buffer for uap_adapter */ ++ if (!(priv->adapter = kmalloc(sizeof(uap_adapter), GFP_KERNEL))) { ++ PRINTM(FATAL, "Allocate buffer for uap_adapter failed!\n"); ++ goto error; ++ } ++ memset(priv->adapter, 0, sizeof(uap_adapter)); ++ ++ priv->uap_dev.netdev = dev; ++ priv->uap_dev.card = card; ++ priv->MediaConnected = FALSE; ++ uappriv = priv; ++ ((struct sdio_mmc_card *) card)->priv = priv; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ++ SET_MODULE_OWNER(dev); ++#endif ++ ++ /* Setup the OS Interface to our functions */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) ++ dev->open = uap_open; ++ dev->stop = uap_close; ++ dev->hard_start_xmit = uap_hard_start_xmit; ++ dev->tx_timeout = uap_tx_timeout; ++ dev->get_stats = uap_get_stats; ++ dev->do_ioctl = uap_do_ioctl; ++ dev->set_mac_address = uap_set_mac_address; ++ dev->set_multicast_list = uap_set_multicast_list; ++#else ++ dev->netdev_ops = &uap_netdev_ops; ++#endif ++ dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT; ++ dev->hard_header_len += sizeof(TxPD) + INTF_HEADER_LEN; ++ dev->hard_header_len += HEADER_ALIGNMENT; ++#define NETIF_F_DYNALLOC 16 ++ dev->features |= NETIF_F_DYNALLOC; ++ dev->flags |= IFF_BROADCAST | IFF_MULTICAST; ++ ++ /* Init SW */ ++ if (uap_init_sw(priv)) { ++ PRINTM(FATAL, "Software Init Failed\n"); ++ goto error; ++ } ++ ++ PRINTM(INFO, "Starting kthread...\n"); ++ priv->MainThread.priv = priv; ++ spin_lock_init(&priv->driver_lock); ++ uap_create_thread(uap_service_main_thread, &priv->MainThread, ++ "uap_main_service"); ++ while (priv->MainThread.pid == 0) { ++ os_sched_timeout(2); ++ } ++ ++ /* Register the device */ ++ if (sbi_register_dev(priv) < 0) { ++ PRINTM(FATAL, "Failed to register uap device!\n"); ++ goto err_registerdev; ++ } ++#ifdef FW_DNLD_NEEDED ++ SET_NETDEV_DEV(dev, priv->hotplug_device); ++#endif ++ ++ /* Init FW and HW */ ++ if (uap_init_fw(priv)) { ++ PRINTM(FATAL, "Firmware Init Failed\n"); ++ goto err_init_fw; ++ } ++ ++ priv->uap_dev.cmd_sent = FALSE; ++ priv->uap_dev.data_sent = FALSE; ++ ++ /* Get mac address from firmware */ ++ if (uap_get_mac_address(priv)) { ++ PRINTM(FATAL, "Fail to get mac address\n"); ++ goto err_init_fw; ++ } ++ /* Register network device */ ++ if (register_netdev(dev)) { ++ printk(KERN_ERR "Cannot register network device!\n"); ++ goto err_init_fw; ++ } ++#ifdef CONFIG_PROC_FS ++ uap_proc_entry(priv, dev); ++ uap_debug_entry(priv, dev); ++#endif /* CPNFIG_PROC_FS */ ++ OS_REL_SEMAPHORE(&AddRemoveCardSem); ++ ++ LEAVE(); ++ return priv; ++ err_init_fw: ++ sbi_unregister_dev(priv); ++ err_registerdev: ++ ((struct sdio_mmc_card *) card)->priv = NULL; ++ /* Stop the thread servicing the interrupts */ ++ priv->adapter->SurpriseRemoved = TRUE; ++ wake_up_interruptible(&priv->MainThread.waitQ); ++ while (priv->MainThread.pid) { ++ os_sched_timeout(1); ++ } ++ error: ++ if (dev) { ++ if (dev->reg_state == NETREG_REGISTERED) ++ unregister_netdev(dev); ++ if (priv->adapter) ++ uap_free_adapter(priv); ++ free_netdev(dev); ++ uappriv = NULL; ++ } ++ OS_REL_SEMAPHORE(&AddRemoveCardSem); ++ exit_sem_err: ++ LEAVE(); ++ return NULL; ++} ++ ++/** ++ * @brief This function removes the card. ++ * ++ * @param card A pointer to card ++ * @return UAP_STATUS_SUCCESS ++ */ ++int ++uap_remove_card(void *card) ++{ ++ uap_private *priv = uappriv; ++ uap_adapter *Adapter; ++ struct net_device *dev; ++ ++ ENTER(); ++ ++ if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) ++ goto exit_sem_err; ++ ++ if (!priv || !(Adapter = priv->adapter)) { ++ goto exit_remove; ++ } ++ Adapter->SurpriseRemoved = TRUE; ++ if (Adapter->cmd_pending == TRUE) { ++ /* Wake up cmd Q */ ++ Adapter->CmdWaitQWoken = TRUE; ++ wake_up_interruptible(&Adapter->cmdwait_q); ++ } ++ dev = priv->uap_dev.netdev; ++ if (priv->MediaConnected == TRUE) { ++ os_stop_queue(priv); ++ os_carrier_off(priv); ++ priv->MediaConnected = FALSE; ++ } ++ Adapter->CmdSize = 0; ++ Adapter->CmdWaitQWoken = TRUE; ++ wake_up_interruptible(&Adapter->cmdwait_q); ++ skb_queue_purge(&priv->adapter->tx_queue); ++ skb_queue_purge(&priv->adapter->cmd_queue); ++ ++ /* Disable interrupts on the card */ ++ sbi_disable_host_int(priv); ++ PRINTM(INFO, "netdev_finish_unregister: %s%s.\n", dev->name, ++ (dev->features & NETIF_F_DYNALLOC) ? "" : ", old style"); ++ unregister_netdev(dev); ++ PRINTM(INFO, "Unregister finish\n"); ++ wake_up_interruptible(&priv->MainThread.waitQ); ++ while (priv->MainThread.pid) { ++ os_sched_timeout(1); ++ } ++ ++ if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) { ++ sock_release((Adapter->nl_sk)->sk_socket); ++ Adapter->nl_sk = NULL; ++ } ++#ifdef CONFIG_PROC_FS ++ uap_debug_remove(priv); ++ uap_proc_remove(priv); ++#endif ++ sbi_unregister_dev(priv); ++ PRINTM(INFO, "Free Adapter\n"); ++ uap_free_adapter(priv); ++ priv->uap_dev.netdev = NULL; ++ free_netdev(dev); ++ uappriv = NULL; ++ ++ exit_remove: ++ OS_REL_SEMAPHORE(&AddRemoveCardSem); ++ exit_sem_err: ++ LEAVE(); ++ return UAP_STATUS_SUCCESS; ++} ++ ++/** ++ * @brief This function initializes module. ++ * ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int __init ++uap_init_module(void) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ ENTER(); ++ ++ OS_INIT_SEMAPHORE(&AddRemoveCardSem); ++ ret = sbi_register(); ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function cleans module ++ * ++ * @return n/a ++ */ ++static void __exit ++uap_cleanup_module(void) ++{ ++ ENTER(); ++ ++ if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) ++ goto exit_sem_err; ++ ++ if ((uappriv) && (uappriv->adapter)) { ++ uap_func_shutdown(uappriv); ++ } ++ OS_REL_SEMAPHORE(&AddRemoveCardSem); ++ exit_sem_err: ++ sbi_unregister(); ++ LEAVE(); ++} ++ ++module_init(uap_init_module); ++module_exit(uap_cleanup_module); ++module_param(helper_name, charp, 0); ++MODULE_PARM_DESC(helper_name, "Helper name"); ++module_param(fw_name, charp, 0); ++MODULE_PARM_DESC(fw_name, "Firmware name"); ++ ++MODULE_DESCRIPTION("M-UAP Driver"); ++MODULE_AUTHOR("Marvell International Ltd."); ++MODULE_VERSION(DRIVER_VERSION); ++MODULE_LICENSE("GPL"); +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_proc.c backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_proc.c +--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_proc.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_proc.c 2014-12-29 20:37:43.952431125 +0100 +@@ -0,0 +1,258 @@ ++/** @file uap_proc.c ++ * @brief This file contains functions for proc file. ++ * ++ * Copyright (C) 2008-2009, Marvell International Ltd. ++ * ++ * This software file (the "File") is distributed by Marvell International ++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 ++ * (the "License"). You may use, redistribute and/or modify this File in ++ * accordance with the terms and conditions of the License, a copy of which ++ * is available along with the File in the gpl.txt file or by writing to ++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++ * ++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ++ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about ++ * this warranty disclaimer. ++ * ++ */ ++#ifdef CONFIG_PROC_FS ++#include <linux/proc_fs.h> ++#include <linux/seq_file.h> ++#include "uap_headers.h" ++ ++/** /proc directory root */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) ++#define PROC_DIR NULL ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++#define PROC_DIR &proc_root ++#else ++#define PROC_DIR proc_net ++#endif ++ ++/******************************************************** ++ Local Variables ++********************************************************/ ++ ++/******************************************************** ++ Global Variables ++********************************************************/ ++ ++/******************************************************** ++ Local Functions ++********************************************************/ ++ ++static int uap_info_proc_show(struct seq_file *s, void *data) { ++ int i; ++ struct net_device *netdev = (struct net_device*)s->private; ++ struct netdev_hw_addr *ha; ++ uap_private *priv = (uap_private *) netdev_priv(netdev); ++ ++ seq_printf(s, "driver_name = " ""uap"\n"); ++ seq_printf(s, "driver_version = %s-(FP%s)", DRIVER_VERSION, FPNUM); ++ seq_printf(s, "\nInterfaceName="%s"\n", netdev->name); ++ ++ seq_printf(s, "State="%s"\n", ++ ((priv->MediaConnected == ++ FALSE) ? "Disconnected" : "Connected")); ++ seq_printf(s, "MACAddress="%02x:%02x:%02x:%02x:%02x:%02x"\n", ++ netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], ++ netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); ++ i = 0; ++ netdev_for_each_mc_addr(ha, netdev) { ++ ++i; ++ } ++ seq_printf(s, "MCCount="%d"\n", i); ++ ++ /* ++ * Put out the multicast list ++ */ ++ i = 0; ++ netdev_for_each_mc_addr(ha, netdev) { ++ seq_printf(s, ++ "MCAddr[%d]="%02x:%02x:%02x:%02x:%02x:%02x"\n", ++ i++, ++ ha->addr[0], ha->addr[1], ++ ha->addr[2], ha->addr[3], ++ ha->addr[4], ha->addr[5]); ++ } ++ ++ seq_printf(s, "num_tx_bytes = %lu\n", priv->stats.tx_bytes); ++ seq_printf(s, "num_rx_bytes = %lu\n", priv->stats.rx_bytes); ++ seq_printf(s, "num_tx_pkts = %lu\n", priv->stats.tx_packets); ++ seq_printf(s, "num_rx_pkts = %lu\n", priv->stats.rx_packets); ++ seq_printf(s, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped); ++ seq_printf(s, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped); ++ seq_printf(s, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors); ++ seq_printf(s, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); ++ seq_printf(s, "num_tx_timeout = %u\n", priv->num_tx_timeout); ++ seq_printf(s, "carrier %s\n", ++ ((netif_carrier_ok(priv->uap_dev.netdev)) ? "on" : "off")); ++ seq_printf(s, "tx queue %s\n", ++ ((netif_queue_stopped(priv->uap_dev.netdev)) ? "stopped" : ++ "started")); ++ ++ return 0; ++} ++ ++static int uap_info_proc_open(struct inode *inode, struct file *file) { ++ return single_open(file, uap_info_proc_show, PDE_DATA(inode)); ++} ++ ++static int uap_hwstatus_proc_show(struct seq_file *s, void *data) { ++ struct net_device *netdev = (struct net_device*)s->private; ++ uap_private *priv = (uap_private *) netdev_priv(netdev); ++ ++ MODULE_GET; ++ seq_printf(s, "%d\n", priv->adapter->HardwareStatus); ++ MODULE_PUT; ++ ++ return 0; ++} ++ ++static int uap_hwstatus_proc_open(struct inode *inode, struct file *file) { ++ return single_open(file, uap_hwstatus_proc_show, PDE_DATA(inode)); ++} ++ ++static ssize_t uap_hwstatus_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *data) { ++ struct net_device *netdev = (struct net_device *)PDE_DATA(file_inode(file)); ++ uap_private *priv = (uap_private *) netdev_priv(netdev); ++ ++ int hwstatus; ++ char value[10]; ++ ++ if (count > sizeof(value)) ++ return count; ++ ++ if (copy_from_user(&value, buffer, count)) ++ return -EFAULT; ++ ++ hwstatus = string_to_number(value); ++ switch (hwstatus) { ++ case HWReset: ++ PRINTM(MSG, "reset hw\n"); ++ uap_soft_reset(priv); ++ priv->adapter->HardwareStatus = HWReset; ++ break; ++ default: ++ break; ++ } ++ ++ MODULE_PUT; ++ return count; ++} ++ ++static const struct file_operations uap_info_proc_fops = { ++ .owner = THIS_MODULE, ++ .open = uap_info_proc_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static const struct file_operations uap_hwstatus_proc_fops = { ++ .owner = THIS_MODULE, ++ .open = uap_hwstatus_proc_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .write = uap_hwstatus_proc_write, ++}; ++ ++/******************************************************** ++ Global Functions ++********************************************************/ ++/** ++ * @brief create uap proc file ++ * ++ * @param priv pointer uap_private ++ * @param dev pointer net_device ++ * @return N/A ++ */ ++void ++uap_proc_entry(uap_private * priv, struct net_device *dev) ++{ ++ PRINTM(INFO, "Creating Proc Interface\n"); ++ /* Check if uap directory already exists */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) ++ struct proc_dir_entry *r = PROC_DIR; ++ ++ for (r = r->subdir; r; r = r->next) { ++ if (r->namelen && !strcmp("uap", r->name)) { ++ /* Directory exists */ ++ PRINTM(WARN, "proc directory already exists!\n"); ++ priv->proc_uap = r; ++ break; ++ } ++ } ++#endif ++ if (!priv->proc_uap) { ++ priv->proc_uap = proc_mkdir("uap", PROC_DIR); ++ if (!priv->proc_uap) ++ return; ++ } ++ priv->proc_entry = proc_mkdir(dev->name, priv->proc_uap); ++ ++ if (priv->proc_entry) { ++ proc_create_data("info", 0644, priv->proc_entry, &uap_info_proc_fops, dev); ++ proc_create_data("hwinfo", 0644, priv->proc_entry, &uap_hwstatus_proc_fops, dev); ++ } ++} ++ ++/** ++ * @brief remove proc file ++ * ++ * @param priv pointer uap_private ++ * @return N/A ++ */ ++void ++uap_proc_remove(uap_private * priv) ++{ ++ if (priv->proc_uap) { ++ if (priv->proc_entry) { ++ remove_proc_entry("info", priv->proc_entry); ++ remove_proc_entry("hwstatus", priv->proc_entry); ++ } ++ remove_proc_entry(priv->uap_dev.netdev->name, priv->proc_uap); ++ } ++} ++ ++/** ++ * @brief convert string to number ++ * ++ * @param s pointer to numbered string ++ * @return converted number from string s ++ */ ++int ++string_to_number(char *s) ++{ ++ int r = 0; ++ int base = 0; ++ int pn = 1; ++ ++ if (strncmp(s, "-", 1) == 0) { ++ pn = -1; ++ s++; ++ } ++ if ((strncmp(s, "0x", 2) == 0) || (strncmp(s, "0X", 2) == 0)) { ++ base = 16; ++ s += 2; ++ } else ++ base = 10; ++ ++ for (s = s; *s != 0; s++) { ++ if ((*s >= '0') && (*s <= '9')) ++ r = (r * base) + (*s - '0'); ++ else if ((*s >= 'A') && (*s <= 'F')) ++ r = (r * base) + (*s - 'A' + 10); ++ else if ((*s >= 'a') && (*s <= 'f')) ++ r = (r * base) + (*s - 'a' + 10); ++ else ++ break; ++ } ++ ++ return (r * pn); ++} ++ ++#endif +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c +--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c 2014-12-29 20:37:43.955764567 +0100 +@@ -0,0 +1,1428 @@ ++/** @file uap_sdio_mmc.c ++ * @brief This file contains SDIO IF (interface) module ++ * related functions. ++ * ++ * Copyright (C) 2007-2009, Marvell International Ltd. ++ * ++ * This software file (the "File") is distributed by Marvell International ++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 ++ * (the "License"). You may use, redistribute and/or modify this File in ++ * accordance with the terms and conditions of the License, a copy of which ++ * is available along with the File in the gpl.txt file or by writing to ++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++ * ++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ++ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about ++ * this warranty disclaimer. ++ * ++ */ ++/**************************************************** ++Change log: ++****************************************************/ ++ ++#include "uap_sdio_mmc.h" ++ ++#include <linux/firmware.h> ++ ++/** define SDIO block size */ ++/* We support up to 480-byte block size due to FW buffer limitation. */ ++#define SD_BLOCK_SIZE 256 ++ ++/** define allocated buffer size */ ++#define ALLOC_BUF_SIZE (((MAX(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, \ ++ MRVDRV_SIZE_OF_CMD_BUFFER) + INTF_HEADER_LEN \ ++ + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE) * SD_BLOCK_SIZE) ++ ++/** Max retry number of CMD53 write */ ++#define MAX_WRITE_IOMEM_RETRY 2 ++ ++/******************************************************** ++ Local Variables ++********************************************************/ ++ ++/** SDIO Rx unit */ ++static u8 sdio_rx_unit = 0; ++ ++/**Interrupt status */ ++static u8 sd_ireg = 0; ++/******************************************************** ++ Global Variables ++********************************************************/ ++extern u8 *helper_name; ++extern u8 *fw_name; ++/** Default helper name */ ++#define DEFAULT_HELPER_NAME "mrvl/helper_sd.bin" ++/** Default firmware name */ ++#define DEFAULT_FW_NAME "mrvl/sd8688_ap.bin" ++ ++/******************************************************** ++ Local Functions ++********************************************************/ ++/** ++ * @brief This function reads the IO register. ++ * ++ * @param priv A pointer to uap_private structure ++ * @param reg register to be read ++ * @param dat A pointer to variable that keeps returned value ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++sbi_read_ioreg(uap_private * priv, u32 reg, u8 * dat) ++{ ++ struct sdio_mmc_card *card; ++ int ret = UAP_STATUS_FAILURE; ++ ++ ENTER(); ++ ++ card = priv->uap_dev.card; ++ if (!card || !card->func) { ++ PRINTM(ERROR, "sbi_read_ioreg(): card or function is NULL!\n"); ++ goto done; ++ } ++ ++ *dat = sdio_readb(card->func, reg, &ret); ++ if (ret) { ++ PRINTM(ERROR, "sbi_read_ioreg(): sdio_readb failed! ret=%d\n", ret); ++ goto done; ++ } ++ ++ PRINTM(INFO, "sbi_read_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv, ++ card->func->num, reg, *dat); ++ ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function writes the IO register. ++ * ++ * @param priv A pointer to uap_private structure ++ * @param reg register to be written ++ * @param dat the value to be written ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++sbi_write_ioreg(uap_private * priv, u32 reg, u8 dat) ++{ ++ struct sdio_mmc_card *card; ++ int ret = UAP_STATUS_FAILURE; ++ ++ ENTER(); ++ ++ card = priv->uap_dev.card; ++ if (!card || !card->func) { ++ PRINTM(ERROR, "sbi_write_ioreg(): card or function is NULL!\n"); ++ goto done; ++ } ++ ++ PRINTM(INFO, "sbi_write_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv, ++ card->func->num, reg, dat); ++ ++ sdio_writeb(card->func, dat, reg, &ret); ++ if (ret) { ++ PRINTM(ERROR, "sbi_write_ioreg(): sdio_readb failed! ret=%d\n", ret); ++ goto done; ++ } ++ ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function get rx_unit value ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++sd_get_rx_unit(uap_private * priv) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ u8 reg; ++ ++ ENTER(); ++ ++ ret = sbi_read_ioreg(priv, CARD_RX_UNIT_REG, ®); ++ if (ret == UAP_STATUS_SUCCESS) ++ sdio_rx_unit = reg; ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function reads rx length ++ * ++ * @param priv A pointer to uap_private structure ++ * @param dat A pointer to keep returned data ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++sd_read_rx_len(uap_private * priv, u16 * dat) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ u8 reg; ++ ++ ENTER(); ++ ++ ret = sbi_read_ioreg(priv, CARD_RX_LEN_REG, ®); ++ if (ret == UAP_STATUS_SUCCESS) ++ *dat = (u16) reg << sdio_rx_unit; ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function reads fw status registers ++ * ++ * @param priv A pointer to uap_private structure ++ * @param dat A pointer to keep returned data ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++sd_read_firmware_status(uap_private * priv, u16 * dat) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ u8 fws0; ++ u8 fws1; ++ ++ ENTER(); ++ ++ ret = sbi_read_ioreg(priv, CARD_FW_STATUS0_REG, &fws0); ++ if (ret < 0) { ++ LEAVE(); ++ return UAP_STATUS_FAILURE; ++ } ++ ++ ret = sbi_read_ioreg(priv, CARD_FW_STATUS1_REG, &fws1); ++ if (ret < 0) { ++ LEAVE(); ++ return UAP_STATUS_FAILURE; ++ } ++ ++ *dat = (((u16) fws1) << 8) | fws0; ++ ++ LEAVE(); ++ return UAP_STATUS_SUCCESS; ++} ++ ++/** ++ * @brief This function polls the card status register. ++ * ++ * @param priv A pointer to uap_private structure ++ * @param bits the bit mask ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++mv_sdio_poll_card_status(uap_private * priv, u8 bits) ++{ ++ int tries; ++ u8 cs; ++ ++ ENTER(); ++ ++ for (tries = 0; tries < MAX_POLL_TRIES; tries++) { ++ if (sbi_read_ioreg(priv, CARD_STATUS_REG, &cs) < 0) ++ break; ++ else if ((cs & bits) == bits) { ++ LEAVE(); ++ return UAP_STATUS_SUCCESS; ++ } ++ udelay(10); ++ } ++ ++ PRINTM(WARN, "mv_sdio_poll_card_status failed, tries = %d\n", tries); ++ ++ LEAVE(); ++ return UAP_STATUS_FAILURE; ++} ++ ++/** ++ * @brief This function set the sdio bus width. ++ * ++ * @param priv A pointer to uap_private structure ++ * @param mode 1--1 bit mode, 4--4 bit mode ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++#if 0 ++static int ++sdio_set_bus_width(uap_private * priv, u8 mode) ++{ ++ ENTER(); ++ LEAVE(); ++ return UAP_STATUS_SUCCESS; ++} ++#endif ++ ++/** ++ * @brief This function reads data from the card. ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++sd_card_to_host(uap_private * priv) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ u16 buf_len = 0; ++ int buf_block_len; ++ int blksz; ++ struct sk_buff *skb = NULL; ++ u16 type; ++ u8 *payload = NULL; ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ ++ ENTER(); ++ ++ if (!card || !card->func) { ++ PRINTM(ERROR, "card or function is NULL!\n"); ++ ret = UAP_STATUS_FAILURE; ++ goto exit; ++ } ++ ++ /* Read the length of data to be transferred */ ++ ret = sd_read_rx_len(priv, &buf_len); ++ if (ret < 0) { ++ PRINTM(ERROR, "card_to_host, read scratch reg failed\n"); ++ ret = UAP_STATUS_FAILURE; ++ goto exit; ++ } ++ ++ /* Allocate buffer */ ++ blksz = SD_BLOCK_SIZE; ++ buf_block_len = (buf_len + blksz - 1) / blksz; ++ if (buf_len <= INTF_HEADER_LEN || (buf_block_len * blksz) > ALLOC_BUF_SIZE) { ++ PRINTM(ERROR, "card_to_host, invalid packet length: %d\n", buf_len); ++ ret = UAP_STATUS_FAILURE; ++ goto exit; ++ } ++#ifdef PXA3XX_DMA_ALIGN ++ skb = dev_alloc_skb(buf_block_len * blksz + PXA3XX_DMA_ALIGNMENT); ++#else ++ skb = dev_alloc_skb(buf_block_len * blksz); ++#endif ++ if (skb == NULL) { ++ PRINTM(WARN, "No free skb\n"); ++ goto exit; ++ } ++#ifdef PXA3XX_DMA_ALIGN ++ if ((u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)) { ++ skb_put(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)); ++ skb_pull(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)); ++ } ++#endif /* PXA3XX_DMA_ALIGN */ ++ ++ payload = skb->tail; ++ ret = sdio_readsb(card->func, payload, priv->uap_dev.ioport, ++ buf_block_len * blksz); ++ if (ret < 0) { ++ PRINTM(ERROR, "card_to_host, read iomem failed: %d\n", ret); ++ ret = UAP_STATUS_FAILURE; ++ goto exit; ++ } ++ HEXDUMP("SDIO Blk Rd", payload, blksz * buf_block_len); ++ /* ++ * This is SDIO specific header ++ * u16 length, ++ * u16 type (MV_TYPE_DAT = 0, MV_TYPE_CMD = 1, MV_TYPE_EVENT = 3) ++ */ ++ buf_len = uap_le16_to_cpu(*(u16 *) & payload[0]); ++ type = uap_le16_to_cpu(*(u16 *) & payload[2]); ++ switch (type) { ++ case MV_TYPE_EVENT: ++ skb_put(skb, buf_len); ++ skb_pull(skb, INTF_HEADER_LEN); ++ uap_process_event(priv, skb->data, skb->len); ++ kfree_skb(skb); ++ skb = NULL; ++ break; ++ case MV_TYPE_CMD: ++ skb_put(skb, buf_len); ++ skb_pull(skb, INTF_HEADER_LEN); ++ priv->adapter->cmd_pending = FALSE; ++ if (priv->adapter->cmd_wait_option == ++ HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM) { ++ priv->adapter->cmd_wait_option = FALSE; ++ uap_process_sleep_confirm_resp(priv, skb->data, skb->len); ++ } else if (priv->adapter->cmd_wait_option) { ++ memcpy(priv->adapter->CmdBuf, skb->data, skb->len); ++ priv->adapter->CmdSize = skb->len; ++ priv->adapter->cmd_wait_option = FALSE; ++ priv->adapter->CmdWaitQWoken = TRUE; ++ wake_up_interruptible(&priv->adapter->cmdwait_q); ++ } ++ kfree_skb(skb); ++ skb = NULL; ++ break; ++ case MV_TYPE_DAT: ++ skb_put(skb, buf_len); ++ skb_pull(skb, INTF_HEADER_LEN); ++ uap_process_rx_packet(priv, skb); ++ break; ++ default: ++ priv->stats.rx_errors++; ++ priv->stats.rx_dropped++; ++ /* Driver specified event and command resp should be handle here */ ++ PRINTM(INFO, "Unknown PKT type:%d\n", type); ++ kfree_skb(skb); ++ skb = NULL; ++ break; ++ } ++ exit: ++ if (ret) { ++ if (skb) ++ kfree_skb(skb); ++ } ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function enables the host interrupts mask ++ * ++ * @param priv A pointer to uap_private structure ++ * @param mask the interrupt mask ++ * @return UAP_STATUS_SUCCESS ++ */ ++static int ++enable_host_int_mask(uap_private * priv, u8 mask) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ ++ ENTER(); ++ ++ /* Simply write the mask to the register */ ++ ret = sbi_write_ioreg(priv, HOST_INT_MASK_REG, mask); ++ ++ if (ret) { ++ PRINTM(WARN, "Unable to enable the host interrupt!\n"); ++ ret = UAP_STATUS_FAILURE; ++ } ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** @brief This function disables the host interrupts mask. ++ * ++ * @param priv A pointer to uap_private structure ++ * @param mask the interrupt mask ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++disable_host_int_mask(uap_private * priv, u8 mask) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ u8 host_int_mask; ++ ++ ENTER(); ++ ++ /* Read back the host_int_mask register */ ++ ret = sbi_read_ioreg(priv, HOST_INT_MASK_REG, &host_int_mask); ++ if (ret) { ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ ++ /* Update with the mask and write back to the register */ ++ host_int_mask &= ~mask; ++ ret = sbi_write_ioreg(priv, HOST_INT_MASK_REG, host_int_mask); ++ if (ret < 0) { ++ PRINTM(WARN, "Unable to diable the host interrupt!\n"); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/******************************************************** ++ Global Functions ++********************************************************/ ++ ++/** ++ * @brief This function handles the interrupt. ++ * ++ * @param func A pointer to sdio_func structure. ++ * @return n/a ++ */ ++static void ++sbi_interrupt(struct sdio_func *func) ++{ ++ struct sdio_mmc_card *card; ++ uap_private *priv; ++ u8 ireg = 0; ++ int ret = UAP_STATUS_SUCCESS; ++ ++ ENTER(); ++ ++ card = sdio_get_drvdata(func); ++ if (!card || !card->priv) { ++ PRINTM(MSG, "%s: sbi_interrupt(%p) card or priv is NULL, card=%p\n", ++ __FUNCTION__, func, card); ++ LEAVE(); ++ return; ++ } ++ priv = card->priv; ++#ifdef FW_WAKEUP_TIME ++ if ((priv->adapter->wt_pwrup_sending != 0L) && ++ (priv->adapter->wt_int == 0L)) ++ priv->adapter->wt_int = get_utimeofday(); ++#endif ++ ++ ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); ++ if (ret) { ++ PRINTM(WARN, "sdio_read_ioreg: read int status register failed\n"); ++ goto done; ++ } ++ if (ireg != 0) { ++ /* ++ * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS ++ * Clear the interrupt status register and re-enable the interrupt ++ */ ++ PRINTM(INFO, "sdio_ireg = 0x%x\n", ireg); ++ sdio_writeb(card->func, ++ ~(ireg) & (DN_LD_HOST_INT_STATUS | UP_LD_HOST_INT_STATUS), ++ HOST_INTSTATUS_REG, &ret); ++ if (ret) { ++ PRINTM(WARN, ++ "sdio_write_ioreg: clear int status register failed\n"); ++ goto done; ++ } ++ } ++ OS_INT_DISABLE; ++ sd_ireg |= ireg; ++ OS_INT_RESTORE; ++ ++ uap_interrupt(priv); ++ done: ++ LEAVE(); ++} ++ ++/** ++ * @brief This function probe the card ++ * ++ * @param func A pointer to sdio_func structure ++ * @param id A pointer to structure sd_device_id ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++static int ++uap_probe(struct sdio_func *func, const struct sdio_device_id *id) ++{ ++ int ret = UAP_STATUS_FAILURE; ++ struct sdio_mmc_card *card = NULL; ++ ++ ENTER(); ++ ++ PRINTM(MSG, "%s: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", ++ __FUNCTION__, func->vendor, func->device, func->class, func->num); ++ ++ card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); ++ if (!card) { ++ ret = -ENOMEM; ++ goto done; ++ } ++ ++ card->func = func; ++ ++ if (!uap_add_card(card)) { ++ PRINTM(ERROR, "%s: uap_add_callback failed\n", __FUNCTION__); ++ kfree(card); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ ++ ret = UAP_STATUS_SUCCESS; ++ ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function removes the card ++ * ++ * @param func A pointer to sdio_func structure ++ * @return N/A ++ */ ++static void ++uap_remove(struct sdio_func *func) ++{ ++ struct sdio_mmc_card *card; ++ ++ ENTER(); ++ ++ if (func) { ++ card = sdio_get_drvdata(func); ++ if (card) { ++ uap_remove_card(card); ++ kfree(card); ++ } ++ } ++ ++ LEAVE(); ++} ++ ++#ifdef CONFIG_PM ++/** ++ * @brief This function handles client driver suspend ++ * ++ * @param func A pointer to sdio_func structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++uap_suspend(struct sdio_func *func) ++{ ++ ENTER(); ++ LEAVE(); ++ return 0; ++} ++ ++/** ++ * @brief This function handles client driver resume ++ * ++ * @param func A pointer to sdio_func structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++uap_resume(struct sdio_func *func) ++{ ++ ENTER(); ++ LEAVE(); ++ return 0; ++} ++#endif ++ ++/** Device ID for SD8688 */ ++#define SD_DEVICE_ID_8688_UAP 0x9104 ++/** UAP IDs */ ++static const struct sdio_device_id uap_ids[] = { ++ {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SD_DEVICE_ID_8688_UAP)}, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(sdio, uap_ids); ++ ++static struct sdio_driver uap_sdio = { ++ .name = "uap_sdio", ++ .id_table = uap_ids, ++ .probe = uap_probe, ++ .remove = uap_remove, ++#ifdef CONFIG_PM ++/* .suspend = uap_suspend, */ ++/* .resume = uap_resume, */ ++#endif ++ ++}; ++ ++/** ++ * @brief This function registers the IF module in bus driver. ++ * ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int __init ++sbi_register() ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ ++ ENTER(); ++ ++ /* SDIO Driver Registration */ ++ if (sdio_register_driver(&uap_sdio) != 0) { ++ PRINTM(FATAL, "SDIO Driver Registration Failed \n"); ++ ret = UAP_STATUS_FAILURE; ++ } ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function de-registers the IF module in bus driver. ++ * ++ * @return n/a ++ */ ++void __exit ++sbi_unregister(void) ++{ ++ ENTER(); ++ ++ /* SDIO Driver Unregistration */ ++ sdio_unregister_driver(&uap_sdio); ++ ++ LEAVE(); ++} ++ ++/** ++ * @brief This function checks the interrupt status and handle it accordingly. ++ * ++ * @param priv A pointer to uap_private structure ++ * @param ireg A pointer to variable that keeps returned value ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++sbi_get_int_status(uap_private * priv, u8 * ireg) ++{ ++ int ret = UAP_STATUS_SUCCESS; ++ u8 sdio_ireg = 0; ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ ++ ENTER(); ++ ++ *ireg = 0; ++ OS_INT_DISABLE; ++ sdio_ireg = sd_ireg; ++ sd_ireg = 0; ++ OS_INT_RESTORE; ++ ++ sdio_claim_host(card->func); ++ ++ if (sdio_ireg & DN_LD_HOST_INT_STATUS) { /* tx_done INT */ ++ if (!priv->uap_dev.cmd_sent) { /* tx_done already received */ ++ PRINTM(INFO, ++ "warning: tx_done already received: tx_dnld_rdy=0x%x int status=0x%x\n", ++ priv->uap_dev.cmd_sent, sdio_ireg); ++ } else { ++ priv->uap_dev.cmd_sent = FALSE; ++ priv->uap_dev.data_sent = FALSE; ++ if ( (priv->uap_dev.netdev->reg_state == NETREG_REGISTERED) && (skb_queue_len(&priv->adapter->tx_queue) < TX_LOW_WATERMARK)) { ++ os_start_queue(priv); ++ } ++ } ++ } ++ if (sdio_ireg & UP_LD_HOST_INT_STATUS) { ++ sd_card_to_host(priv); ++ } ++ ++ *ireg = sdio_ireg; ++ ret = UAP_STATUS_SUCCESS; ++ sdio_release_host(card->func); ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function disables the host interrupts. ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++sbi_disable_host_int(uap_private * priv) ++{ ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ int ret; ++ ++ ENTER(); ++ ++ sdio_claim_host(card->func); ++ ret = disable_host_int_mask(priv, HIM_DISABLE); ++ sdio_release_host(card->func); ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function enables the host interrupts. ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS ++ */ ++int ++sbi_enable_host_int(uap_private * priv) ++{ ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ int ret; ++ ++ ENTER(); ++ ++ sdio_claim_host(card->func); ++ ret = enable_host_int_mask(priv, HIM_ENABLE); ++ sdio_release_host(card->func); ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function de-registers the device. ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS ++ */ ++int ++sbi_unregister_dev(uap_private * priv) ++{ ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ ++ ENTER(); ++ ++ if (!card || !card->func) { ++ PRINTM(ERROR, "Error: card or function is NULL!\n"); ++ goto done; ++ } ++ ++ sdio_claim_host(card->func); ++ sdio_release_irq(card->func); ++ sdio_disable_func(card->func); ++ sdio_release_host(card->func); ++ ++ sdio_set_drvdata(card->func, NULL); ++ ++ done: ++ LEAVE(); ++ return UAP_STATUS_SUCCESS; ++} ++ ++/** ++ * @brief This function registers the device. ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++sbi_register_dev(uap_private * priv) ++{ ++ int ret = UAP_STATUS_FAILURE; ++ u8 reg; ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ struct sdio_func *func; ++ ++ ENTER(); ++ ++ if (!card || !card->func) { ++ PRINTM(ERROR, "Error: card or function is NULL!\n"); ++ goto done; ++ } ++ ++ func = card->func; ++ ++ /* Initialize the private structure */ ++ priv->uap_dev.ioport = 0; ++ ++ sdio_claim_host(func); ++ ++ ret = sdio_enable_func(func); ++ if (ret) { ++ PRINTM(FATAL, "sdio_enable_func() failed: ret=%d\n", ret); ++ goto release_host; ++ } ++ ++ ret = sdio_claim_irq(func, sbi_interrupt); ++ if (ret) { ++ PRINTM(FATAL, "sdio_claim_irq failed: ret=%d\n", ret); ++ goto disable_func; ++ } ++ ++ /* Read the IO port */ ++ ret = sbi_read_ioreg(priv, IO_PORT_0_REG, ®); ++ if (ret) ++ goto release_irq; ++ else ++ priv->uap_dev.ioport |= reg; ++ ++ ret = sbi_read_ioreg(priv, IO_PORT_1_REG, ®); ++ if (ret) ++ goto release_irq; ++ else ++ priv->uap_dev.ioport |= (reg << 8); ++ ++ ret = sbi_read_ioreg(priv, IO_PORT_2_REG, ®); ++ if (ret) ++ goto release_irq; ++ else ++ priv->uap_dev.ioport |= (reg << 16); ++ ++ PRINTM(INFO, "SDIO FUNC #%d IO port: 0x%x\n", func->num, ++ priv->uap_dev.ioport); ++ ++ ret = sdio_set_block_size(card->func, SD_BLOCK_SIZE); ++ if (ret) { ++ PRINTM(ERROR, "%s: cannot set SDIO block size\n", __FUNCTION__); ++ ret = UAP_STATUS_FAILURE; ++ goto release_irq; ++ } ++ priv->hotplug_device = &func->dev; ++ ++ if (helper_name == NULL) { ++ helper_name = DEFAULT_HELPER_NAME; ++ } ++ if (fw_name == NULL) { ++ fw_name = DEFAULT_FW_NAME; ++ } ++ sdio_release_host(func); ++ ++ sdio_set_drvdata(func, card); ++ ++ ret = UAP_STATUS_SUCCESS; ++ goto done; ++ ++ release_irq: ++ sdio_release_irq(func); ++ disable_func: ++ sdio_disable_func(func); ++ release_host: ++ sdio_release_host(func); ++ ++ done: ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function sends data to the card. ++ * ++ * @param priv A pointer to uap_private structure ++ * @param payload A pointer to the data/cmd buffer ++ * @param nb the length of data/cmd ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb) ++{ ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ int ret = UAP_STATUS_SUCCESS; ++ int buf_block_len; ++ int blksz; ++ int i = 0; ++ u8 *buf = NULL; ++#ifdef PXA3XX_DMA_ALIGN ++ void *tmpbuf = NULL; ++ int tmpbufsz; ++#endif ++ ++ ENTER(); ++ ++ if (!card || !card->func) { ++ PRINTM(ERROR, "card or function is NULL!\n"); ++ LEAVE(); ++ return UAP_STATUS_FAILURE; ++ } ++ buf = payload; ++#ifdef PXA3XX_DMA_ALIGN ++ if ((u32) payload & (PXA3XX_DMA_ALIGNMENT - 1)) { ++ tmpbufsz = ALIGN_SZ(nb, PXA3XX_DMA_ALIGNMENT); ++ tmpbuf = kmalloc(tmpbufsz, GFP_KERNEL); ++ memset(tmpbuf, 0, tmpbufsz); ++ /* Ensure 8-byte aligned CMD buffer */ ++ buf = (u8 *) ALIGN_ADDR(tmpbuf, PXA3XX_DMA_ALIGNMENT); ++ memcpy(buf, payload, nb); ++ } ++#endif ++ /* Allocate buffer and copy payload */ ++ blksz = SD_BLOCK_SIZE; ++ buf_block_len = (nb + blksz - 1) / blksz; ++ sdio_claim_host(card->func); ++#define MAX_WRITE_IOMEM_RETRY 2 ++ priv->uap_dev.cmd_sent = TRUE; ++ priv->uap_dev.data_sent = TRUE; ++ do { ++ /* Transfer data to card */ ++ ret = sdio_writesb(card->func, priv->uap_dev.ioport, buf, ++ buf_block_len * blksz); ++ if (ret < 0) { ++ i++; ++ PRINTM(ERROR, "host_to_card, write iomem (%d) failed: %d\n", i, ++ ret); ++ ret = UAP_STATUS_FAILURE; ++ if (i > MAX_WRITE_IOMEM_RETRY) ++ goto exit; ++ } else { ++ HEXDUMP("SDIO Blk Wr", payload, nb); ++ } ++ } while (ret == UAP_STATUS_FAILURE); ++ exit: ++ sdio_release_host(card->func); ++#ifdef PXA3XX_DMA_ALIGN ++ if (tmpbuf) ++ kfree(tmpbuf); ++#endif ++ if (ret == UAP_STATUS_FAILURE) { ++ priv->uap_dev.cmd_sent = FALSE; ++ priv->uap_dev.data_sent = FALSE; ++ } ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function reads CIS information. ++ * ++ * @param priv A pointer to uap_private structure ++ * @param cisinfo A pointer to CIS information output buffer ++ * @param cislen A pointer to length of CIS info output buffer ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++#if 0 ++static int ++sbi_get_cis_info(uap_private * priv, void *cisinfo, int *cislen) ++{ ++#define CIS_PTR (0x8000) ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ unsigned int i, cis_ptr = CIS_PTR; ++ int ret = UAP_STATUS_FAILURE; ++ ++ ENTER(); ++ ++ if (!card || !card->func) { ++ PRINTM(ERROR, "sbi_get_cis_info(): card or function is NULL!\n"); ++ goto exit; ++ } ++#define MAX_SDIO_CIS_INFO_LEN (256) ++ if (!cisinfo || (*cislen < MAX_SDIO_CIS_INFO_LEN)) { ++ PRINTM(WARN, "ERROR! get_cis_info: insufficient buffer passed\n"); ++ goto exit; ++ } ++ ++ *cislen = MAX_SDIO_CIS_INFO_LEN; ++ ++ sdio_claim_host(card->func); ++ ++ PRINTM(INFO, "cis_ptr=%#x\n", cis_ptr); ++ ++ /* Read the Tuple Data */ ++ for (i = 0; i < *cislen; i++) { ++ ((unsigned char *) cisinfo)[i] = ++ sdio_readb(card->func, cis_ptr + i, &ret); ++ if (ret) { ++ PRINTM(WARN, "get_cis_info error: ret=%d\n", ret); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ PRINTM(INFO, "cisinfo[%d]=%#x\n", i, ((unsigned char *) cisinfo)[i]); ++ } ++ ++ done: ++ sdio_release_host(card->func); ++ exit: ++ LEAVE(); ++ return ret; ++} ++#endif ++/** ++ * @brief This function downloads helper image to the card. ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++sbi_prog_helper(uap_private * priv) ++{ ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ u8 *helper = NULL; ++ int helperlen; ++ int ret = UAP_STATUS_SUCCESS; ++ void *tmphlprbuf = NULL; ++ int tmphlprbufsz; ++ u8 *hlprbuf; ++ int hlprblknow; ++ u32 tx_len; ++#ifdef FW_DOWNLOAD_SPEED ++ u32 tv1, tv2; ++#endif ++ ++ ENTER(); ++ ++ if (!card || !card->func) { ++ PRINTM(ERROR, "sbi_prog_helper(): card or function is NULL!\n"); ++ goto done; ++ } ++ ++ if (priv->fw_helper) { ++ helper = (u8 *) priv->fw_helper->data; ++ helperlen = priv->fw_helper->size; ++ } else { ++ PRINTM(MSG, "No helper image found! Terminating download.\n"); ++ LEAVE(); ++ return UAP_STATUS_FAILURE; ++ } ++ ++ PRINTM(INFO, "Downloading helper image (%d bytes), block size %d bytes\n", ++ helperlen, SD_BLOCK_SIZE); ++ ++#ifdef FW_DOWNLOAD_SPEED ++ tv1 = get_utimeofday(); ++#endif ++ ++#ifdef PXA3XX_DMA_ALIGN ++ tmphlprbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT); ++#else /* !PXA3XX_DMA_ALIGN */ ++ tmphlprbufsz = UAP_UPLD_SIZE; ++#endif /* !PXA3XX_DMA_ALIGN */ ++ tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL); ++ if (!tmphlprbuf) { ++ PRINTM(ERROR, ++ "Unable to allocate buffer for helper. Terminating download\n"); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ memset(tmphlprbuf, 0, tmphlprbufsz); ++#ifdef PXA3XX_DMA_ALIGN ++ hlprbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, PXA3XX_DMA_ALIGNMENT); ++#else /* !PXA3XX_DMA_ALIGN */ ++ hlprbuf = (u8 *) tmphlprbuf; ++#endif /* !PXA3XX_DMA_ALIGN */ ++ ++ sdio_claim_host(card->func); ++ ++ /* Perform helper data transfer */ ++ tx_len = (FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE) - INTF_HEADER_LEN; ++ hlprblknow = 0; ++ do { ++ /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */ ++ ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY); ++ if (ret < 0) { ++ PRINTM(FATAL, "Helper download poll status timeout @ %d\n", ++ hlprblknow); ++ goto done; ++ } ++ ++ /* More data? */ ++ if (hlprblknow >= helperlen) ++ break; ++ ++ /* Set blocksize to transfer - checking for last block */ ++ if (helperlen - hlprblknow < tx_len) ++ tx_len = helperlen - hlprblknow; ++ ++ /* Set length to the 4-byte header */ ++ *(u32 *) hlprbuf = uap_cpu_to_le32(tx_len); ++ ++ /* Copy payload to buffer */ ++ memcpy(&hlprbuf[INTF_HEADER_LEN], &helper[hlprblknow], tx_len); ++ ++ PRINTM(INFO, "."); ++ ++ /* Send data */ ++ ret = sdio_writesb(card->func, priv->uap_dev.ioport, ++ hlprbuf, FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE); ++ ++ if (ret < 0) { ++ PRINTM(FATAL, "IO error during helper download @ %d\n", hlprblknow); ++ goto done; ++ } ++ ++ hlprblknow += tx_len; ++ } while (TRUE); ++ ++#ifdef FW_DOWNLOAD_SPEED ++ tv2 = get_utimeofday(); ++ PRINTM(INFO, "helper: %ld.%03ld.%03ld ", tv1 / 1000000, ++ (tv1 % 1000000) / 1000, tv1 % 1000); ++ PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000, (tv2 % 1000000) / 1000, ++ tv2 % 1000); ++ tv2 -= tv1; ++ PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000, (tv2 % 1000000) / 1000, ++ tv2 % 1000); ++#endif ++ ++ /* Write last EOF data */ ++ PRINTM(INFO, "\nTransferring helper image EOF block\n"); ++ memset(hlprbuf, 0x0, SD_BLOCK_SIZE); ++ ret = sdio_writesb(card->func, priv->uap_dev.ioport, ++ hlprbuf, SD_BLOCK_SIZE); ++ ++ if (ret < 0) { ++ PRINTM(FATAL, "IO error in writing helper image EOF block\n"); ++ goto done; ++ } ++ ++ ret = UAP_STATUS_SUCCESS; ++ ++ done: ++ sdio_release_host(card->func); ++ if (tmphlprbuf) ++ kfree(tmphlprbuf); ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function downloads firmware image to the card. ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++sbi_prog_fw_w_helper(uap_private * priv) ++{ ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ u8 *firmware = NULL; ++ int firmwarelen; ++ u8 base0; ++ u8 base1; ++ int ret = UAP_STATUS_SUCCESS; ++ int offset; ++ void *tmpfwbuf = NULL; ++ int tmpfwbufsz; ++ u8 *fwbuf; ++ u16 len; ++ int txlen = 0; ++ int tx_blocks = 0; ++ int i = 0; ++ int tries = 0; ++#ifdef FW_DOWNLOAD_SPEED ++ u32 tv1, tv2; ++#endif ++ ++ ENTER(); ++ ++ if (!card || !card->func) { ++ PRINTM(ERROR, "sbi_prog_fw_w_helper(): card or function is NULL!\n"); ++ goto done; ++ } ++ ++ if (priv->firmware) { ++ firmware = (u8 *) priv->firmware->data; ++ firmwarelen = priv->firmware->size; ++ } else { ++ PRINTM(MSG, "No firmware image found! Terminating download.\n"); ++ LEAVE(); ++ return UAP_STATUS_FAILURE; ++ } ++ ++ PRINTM(INFO, "Downloading FW image (%d bytes)\n", firmwarelen); ++ ++#ifdef FW_DOWNLOAD_SPEED ++ tv1 = get_utimeofday(); ++#endif ++ ++#ifdef PXA3XX_DMA_ALIGN ++ tmpfwbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT); ++#else /* PXA3XX_DMA_ALIGN */ ++ tmpfwbufsz = UAP_UPLD_SIZE; ++#endif /* PXA3XX_DMA_ALIGN */ ++ tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL); ++ if (!tmpfwbuf) { ++ PRINTM(ERROR, ++ "Unable to allocate buffer for firmware. Terminating download.\n"); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ memset(tmpfwbuf, 0, tmpfwbufsz); ++#ifdef PXA3XX_DMA_ALIGN ++ /* Ensure 8-byte aligned firmware buffer */ ++ fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, PXA3XX_DMA_ALIGNMENT); ++#else /* PXA3XX_DMA_ALIGN */ ++ fwbuf = (u8 *) tmpfwbuf; ++#endif /* PXA3XX_DMA_ALIGN */ ++ ++ sdio_claim_host(card->func); ++ ++ /* Perform firmware data transfer */ ++ offset = 0; ++ do { ++ /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */ ++ ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY); ++ if (ret < 0) { ++ PRINTM(FATAL, "FW download with helper poll status timeout @ %d\n", ++ offset); ++ goto done; ++ } ++ ++ /* More data? */ ++ if (offset >= firmwarelen) ++ break; ++ ++ for (tries = 0; tries < MAX_POLL_TRIES; tries++) { ++ if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_0, &base0)) < 0) { ++ PRINTM(WARN, "Dev BASE0 register read failed:" ++ " base0=0x%04X(%d). Terminating download.\n", base0, ++ base0); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_1, &base1)) < 0) { ++ PRINTM(WARN, "Dev BASE1 register read failed:" ++ " base1=0x%04X(%d). Terminating download.\n", base1, ++ base1); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ len = (((u16) base1) << 8) | base0; ++ ++ /* For SD8688 wait until the length is not 0, 1 or 2 before ++ downloading the first FW block, since BOOT code writes the ++ register to indicate the helper/FW download winner, the value ++ could be 1 or 2 (Func1 or Func2). */ ++ if ((len && offset) || (len > 2)) ++ break; ++ udelay(10); ++ } ++ ++ if (len == 0) ++ break; ++ else if (len > UAP_UPLD_SIZE) { ++ PRINTM(FATAL, "FW download failure @ %d, invalid length %d\n", ++ offset, len); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ ++ txlen = len; ++ ++ if (len & BIT(0)) { ++ i++; ++ if (i > MAX_WRITE_IOMEM_RETRY) { ++ PRINTM(FATAL, ++ "FW download failure @ %d, over max retry count\n", ++ offset); ++ ret = UAP_STATUS_FAILURE; ++ goto done; ++ } ++ PRINTM(ERROR, "FW CRC error indicated by the helper:" ++ " len = 0x%04X, txlen = %d\n", len, txlen); ++ len &= ~BIT(0); ++ /* Setting this to 0 to resend from same offset */ ++ txlen = 0; ++ } else { ++ i = 0; ++ ++ /* Set blocksize to transfer - checking for last block */ ++ if (firmwarelen - offset < txlen) { ++ txlen = firmwarelen - offset; ++ } ++ PRINTM(INFO, "."); ++ ++ tx_blocks = (txlen + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE; ++ ++ /* Copy payload to buffer */ ++ memcpy(fwbuf, &firmware[offset], txlen); ++ } ++ ++ /* Send data */ ++ ret = sdio_writesb(card->func, priv->uap_dev.ioport, ++ fwbuf, tx_blocks * SD_BLOCK_SIZE); ++ ++ if (ret < 0) { ++ PRINTM(ERROR, "FW download, write iomem (%d) failed @ %d\n", i, ++ offset); ++ if (sbi_write_ioreg(priv, CONFIGURATION_REG, 0x04) < 0) { ++ PRINTM(ERROR, "write ioreg failed (CFG)\n"); ++ } ++ } ++ ++ offset += txlen; ++ } while (TRUE); ++ ++ PRINTM(INFO, "\nFW download over, size %d bytes\n", offset); ++ ++ ret = UAP_STATUS_SUCCESS; ++ done: ++#ifdef FW_DOWNLOAD_SPEED ++ tv2 = get_utimeofday(); ++ PRINTM(INFO, "FW: %ld.%03ld.%03ld ", tv1 / 1000000, ++ (tv1 % 1000000) / 1000, tv1 % 1000); ++ PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000, ++ (tv2 % 1000000) / 1000, tv2 % 1000); ++ tv2 -= tv1; ++ PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000, ++ (tv2 % 1000000) / 1000, tv2 % 1000); ++#endif ++ sdio_release_host(card->func); ++ if (tmpfwbuf) ++ kfree(tmpfwbuf); ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function checks if the firmware is ready to accept ++ * command or not. ++ * ++ * @param priv A pointer to uap_private structure ++ * @param pollnum Poll number ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++sbi_check_fw_status(uap_private * priv, int pollnum) ++{ ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ int ret = UAP_STATUS_SUCCESS; ++ u16 firmwarestat; ++ int tries; ++ ++ ENTER(); ++ ++ sdio_claim_host(card->func); ++ ++ /* Wait for firmware initialization event */ ++ for (tries = 0; tries < pollnum; tries++) { ++ if ((ret = sd_read_firmware_status(priv, &firmwarestat)) < 0) ++ continue; ++ if (firmwarestat == FIRMWARE_READY) { ++ ret = UAP_STATUS_SUCCESS; ++ break; ++ } else { ++ mdelay(10); ++ ret = UAP_STATUS_FAILURE; ++ } ++ } ++ ++ if (ret < 0) ++ goto done; ++ ++ ret = UAP_STATUS_SUCCESS; ++ sd_get_rx_unit(priv); ++ ++ done: ++ sdio_release_host(card->func); ++ ++ LEAVE(); ++ return ret; ++} ++ ++/** ++ * @brief This function set bus clock on/off ++ * ++ * @param priv A pointer to uap_private structure ++ * @param option TRUE--on , FALSE--off ++ * @return UAP_STATUS_SUCCESS ++ */ ++#if 0 ++static int ++sbi_set_bus_clock(uap_private * priv, u8 option) ++{ ++ ENTER(); ++ LEAVE(); ++ return UAP_STATUS_SUCCESS; ++} ++#endif ++ ++/** ++ * @brief This function wakeup firmware ++ * ++ * @param priv A pointer to uap_private structure ++ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE ++ */ ++int ++sbi_wakeup_firmware(uap_private * priv) ++{ ++ struct sdio_mmc_card *card = priv->uap_dev.card; ++ int ret = UAP_STATUS_SUCCESS; ++ ++ ENTER(); ++ ++ if (!card || !card->func) { ++ PRINTM(ERROR, "card or function is NULL!\n"); ++ LEAVE(); ++ return UAP_STATUS_FAILURE; ++ } ++ sdio_claim_host(card->func); ++ sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret); ++ sdio_release_host(card->func); ++ LEAVE(); ++ return ret; ++} +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h +--- backports-3.18.1-1.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h 1970-01-01 01:00:00.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h 2014-12-29 20:37:43.955764567 +0100 +@@ -0,0 +1,136 @@ ++/** @file uap_sdio_mmc.h ++ * @brief This file contains SDIO IF (interface) module ++ * related macros, enum, and structure. ++ * ++ * Copyright (C) 2007-2009, Marvell International Ltd. ++ * ++ * This software file (the "File") is distributed by Marvell International ++ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 ++ * (the "License"). You may use, redistribute and/or modify this File in ++ * accordance with the terms and conditions of the License, a copy of which ++ * is available along with the File in the gpl.txt file or by writing to ++ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++ * ++ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ++ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about ++ * this warranty disclaimer. ++ * ++ */ ++/**************************************************** ++Change log: ++ 10/10/07: initial version ++****************************************************/ ++ ++#ifndef _UAP_SDIO_MMC_H ++#define _UAP_SDIO_MMC_H ++ ++#include <linux/mmc/sdio.h> ++#include <linux/mmc/sdio_ids.h> ++#include <linux/mmc/sdio_func.h> ++#include <linux/mmc/card.h> ++ ++#include "uap_headers.h" ++ ++/** The number of times to try when waiting for downloaded firmware to ++ become active. (polling the scratch register). */ ++#define MAX_FIRMWARE_POLL_TRIES 100 ++ ++/** Firmware ready */ ++#define FIRMWARE_READY 0xfedc ++ ++/** Number of firmware blocks to transfer */ ++#define FIRMWARE_TRANSFER_NBLOCK 2 ++ ++/* Host Control Registers */ ++/** Host Control Registers : I/O port 0 */ ++#define IO_PORT_0_REG 0x00 ++/** Host Control Registers : I/O port 1 */ ++#define IO_PORT_1_REG 0x01 ++/** Host Control Registers : I/O port 2 */ ++#define IO_PORT_2_REG 0x02 ++ ++/** Host Control Registers : Configuration */ ++#define CONFIGURATION_REG 0x03 ++/** Host Control Registers : Host without Command 53 finish host */ ++#define HOST_WO_CMD53_FINISH_HOST (0x1U << 2) ++/** Host Control Registers : Host power up */ ++#define HOST_POWER_UP (0x1U << 1) ++/** Host Control Registers : Host power down */ ++#define HOST_POWER_DOWN (0x1U << 0) ++ ++/** Host Control Registers : Host interrupt mask */ ++#define HOST_INT_MASK_REG 0x04 ++/** Host Control Registers : Upload host interrupt mask */ ++#define UP_LD_HOST_INT_MASK (0x1U) ++/** Host Control Registers : Download host interrupt mask */ ++#define DN_LD_HOST_INT_MASK (0x2U) ++/** Enable Host interrupt mask */ ++#define HIM_ENABLE (UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK) ++/** Disable Host interrupt mask */ ++#define HIM_DISABLE 0xff ++ ++/** Host Control Registers : Host interrupt status */ ++#define HOST_INTSTATUS_REG 0x05 ++/** Host Control Registers : Upload host interrupt status */ ++#define UP_LD_HOST_INT_STATUS (0x1U) ++/** Host Control Registers : Download host interrupt status */ ++#define DN_LD_HOST_INT_STATUS (0x2U) ++ ++/** Host F1 read base 0 */ ++#define HOST_F1_RD_BASE_0 0x10 ++/** Host F1 read base 1 */ ++#define HOST_F1_RD_BASE_1 0x11 ++ ++/** Card Control Registers : Card status register */ ++#define CARD_STATUS_REG 0x20 ++/** Card Control Registers : Card I/O ready */ ++#define CARD_IO_READY (0x1U << 3) ++/** Card Control Registers : CIS card ready */ ++#define CIS_CARD_RDY (0x1U << 2) ++/** Card Control Registers : Upload card ready */ ++#define UP_LD_CARD_RDY (0x1U << 1) ++/** Card Control Registers : Download card ready */ ++#define DN_LD_CARD_RDY (0x1U << 0) ++ ++/** Card Control Registers : Card OCR 0 register */ ++#define CARD_OCR_0_REG 0x34 ++/** Card Control Registers : Card OCR 1 register */ ++#define CARD_OCR_1_REG 0x35 ++ ++/** Firmware status 0 register */ ++#define CARD_FW_STATUS0_REG 0x40 ++/** Firmware status 1 register */ ++#define CARD_FW_STATUS1_REG 0x41 ++/** Rx length register */ ++#define CARD_RX_LEN_REG 0x42 ++/** Rx unit register */ ++#define CARD_RX_UNIT_REG 0x43 ++ ++/** Chip Id Register 0 */ ++#define CARD_CHIP_ID_0_REG 0x801c ++/** Chip Id Register 1 */ ++#define CARD_CHIP_ID_1_REG 0x801d ++ ++#ifdef PXA3XX_DMA_ALIGN ++/** DMA alignment value for PXA3XX platforms */ ++#define PXA3XX_DMA_ALIGNMENT 8 ++/** Macros for Data Alignment : size */ ++#define ALIGN_SZ(p, a) \ ++ (((p) + ((a) - 1)) & ~((a) - 1)) ++ ++/** Macros for Data Alignment : address */ ++#define ALIGN_ADDR(p, a) \ ++ ((((u32)(p)) + (((u32)(a)) - 1)) & ~(((u32)(a)) - 1)) ++#endif /* PXA3XX_DMA_ALIGN */ ++ ++struct sdio_mmc_card ++{ ++ /** sdio_func structure pointer */ ++ struct sdio_func *func; ++ /** uap_private structure pointer */ ++ uap_private *priv; ++}; ++ ++#endif /* _UAP_SDIO_MMC_H */ +diff -Naur backports-3.18.1-1.org/drivers/net/wireless/Makefile backports-3.18.1-1/drivers/net/wireless/Makefile +--- backports-3.18.1-1.org/drivers/net/wireless/Makefile 2014-12-21 22:37:15.000000000 +0100 ++++ backports-3.18.1-1/drivers/net/wireless/Makefile 2014-12-29 20:40:33.632440784 +0100 +@@ -60,3 +60,5 @@ + + obj-$(CPTCFG_CW1200) += cw1200/ + obj-$(CPTCFG_RSI_91X) += rsi/ ++ ++obj-$(CPTCFG_LIBERTAS_UAP) += libertas_uap/ diff --git a/src/patches/crda-3.13-crypto_use_optional.patch b/src/patches/crda-3.13-crypto_use_optional.patch new file mode 100644 index 0000000..56ad6b7 --- /dev/null +++ b/src/patches/crda-3.13-crypto_use_optional.patch @@ -0,0 +1,22 @@ +Submitted By: hauke from OpenWRT +Date: 2009-04-17 +Initial Package Version: 1.0.2 +Origin: https://dev.openwrt.org/changeset/15405/trunk/package/crda/patches/101-make_... +Description: The patch was modified for version crda-3.13 by Erik Kapfer erik.kapfer@ipfire.org.. +This patch provides the following improvements: + * Crypto usage is optional. + +diff -Nur crda-3.13.orig/Makefile crda-3.13/Makefile +--- crda-3.13.orig/Makefile 2015-01-12 07:55:08.791183765 +0100 ++++ crda-3.13/Makefile 2015-01-12 07:56:35.437381029 +0100 +@@ -43,7 +43,9 @@ + + $(LIBREG): keys-ssl.c + +-else ++endif ++ ++ifeq ($(USE_GCRYPT),1) + CFLAGS += -DUSE_GCRYPT + LDLIBS += -lgcrypt + diff --git a/src/patches/linux-3.14.25-rt5592_no_special_txop_init.patch b/src/patches/linux-3.14.25-rt5592_no_special_txop_init.patch new file mode 100644 index 0000000..fe30c9e --- /dev/null +++ b/src/patches/linux-3.14.25-rt5592_no_special_txop_init.patch @@ -0,0 +1,13 @@ +diff -Naur linux-3.14.25.org/drivers/net/wireless/rt2x00/rt2800lib.c linux-3.14.25/drivers/net/wireless/rt2x00/rt2800lib.c +--- linux-3.14.25.org/drivers/net/wireless/rt2x00/rt2800lib.c 2014-11-21 18:23:44.000000000 +0100 ++++ linux-3.14.25/drivers/net/wireless/rt2x00/rt2800lib.c 2014-12-03 11:30:58.813355413 +0100 +@@ -4847,7 +4847,8 @@ + rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CWMIN, 0); + rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg); + +- reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; ++// reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; ++ reg = 0x00000002; + rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); + + rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); diff --git a/src/patches/linux-3.14.25_rt2x00_fix_bss_bcn_num.patch b/src/patches/linux-3.14.25_rt2x00_fix_bss_bcn_num.patch new file mode 100644 index 0000000..87ea39a --- /dev/null +++ b/src/patches/linux-3.14.25_rt2x00_fix_bss_bcn_num.patch @@ -0,0 +1,12 @@ +diff -Naur linux-3.14.25.org/drivers/net/wireless/rt2x00/rt2800lib.c linux-3.14.25/drivers/net/wireless/rt2x00/rt2800lib.c +--- linux-3.14.25.org/drivers/net/wireless/rt2x00/rt2800lib.c 2014-12-03 11:30:58.000000000 +0100 ++++ linux-3.14.25/drivers/net/wireless/rt2x00/rt2800lib.c 2014-12-03 12:15:45.743454351 +0100 +@@ -1557,7 +1557,7 @@ + if (!is_zero_ether_addr((const u8 *)conf->bssid)) { + reg = le32_to_cpu(conf->bssid[1]); + rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); +- rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); ++ rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 0); + conf->bssid[1] = cpu_to_le32(reg); + } + diff --git a/src/patches/u-boot/sunxi/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch b/src/patches/u-boot/sunxi/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch new file mode 100644 index 0000000..15aac6b --- /dev/null +++ b/src/patches/u-boot/sunxi/001-uboot-sunxi-509d96d4f1f602d62d36db660973249e16f9d088.patch @@ -0,0 +1,10002 @@ +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/cmd_boot.c u-boot-sunxi/arch/arm/cpu/armv7/cmd_boot.c +--- u-boot-2014.04/arch/arm/cpu/armv7/cmd_boot.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/cmd_boot.c 2014-09-06 16:58:35.193953144 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++/* ++ * Misc boot support ++ */ ++#include <common.h> ++#include <command.h> ++ ++#ifdef CONFIG_CMD_GO ++unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc, ++ char * const argv[]) ++{ ++ invalidate_icache_all(); ++ return entry(argc, argv); ++} ++#endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/Makefile u-boot-sunxi/arch/arm/cpu/armv7/Makefile +--- u-boot-2014.04/arch/arm/cpu/armv7/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/arch/arm/cpu/armv7/Makefile 2014-09-06 16:58:35.185953145 +0200 +@@ -11,8 +11,9 @@ + + obj-y += cpu.o + obj-y += syslib.o ++obj-y += cmd_boot.o + +-ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY),) ++ifneq ($(CONFIG_AM43XX)$(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA)$(CONFIG_MX6)$(CONFIG_TI81XX)$(CONFIG_AT91FAMILY)$(CONFIG_SUNXI),) + ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y) + obj-y += lowlevel_init.o + endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/board.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/board.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/board.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/board.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,166 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Some init for sunxi platform. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <i2c.h> ++#include <netdev.h> ++#include <miiphy.h> ++#include <serial.h> ++#ifdef CONFIG_SPL_BUILD ++#include <spl.h> ++#endif ++#include <asm/gpio.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/sys_proto.h> ++#include <asm/arch/timer.h> ++#include <asm/arch/watchdog.h> ++ ++#ifdef CONFIG_SPL_BUILD ++/* Pointer to the global data structure for SPL */ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/* The sunxi internal brom will try to loader external bootloader ++ * from mmc0, nand flash, mmc2. ++ * Unfortunately we can't check how SPL was loaded so assume ++ * it's always the first SD/MMC controller ++ */ ++u32 spl_boot_device(void) ++{ ++ return BOOT_DEVICE_MMC1; ++} ++ ++/* No confirmation data available in SPL yet. Hardcode bootmode */ ++u32 spl_boot_mode(void) ++{ ++ return MMCSD_MODE_RAW; ++} ++#endif ++ ++int gpio_init(void) ++{ ++#if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F) ++#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I) ++ /* disable GPB22,23 as uart0 tx,rx to avoid conflict */ ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT); ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT); ++#endif ++ sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF2_UART0_TX); ++ sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF4_UART0_RX); ++ sunxi_gpio_set_pull(SUNXI_GPF(4), 1); ++#elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)) ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB22_UART0_TX); ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB23_UART0_RX); ++ sunxi_gpio_set_pull(SUNXI_GPB(23), 1); ++#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN6I) ++ sunxi_gpio_set_cfgpin(SUNXI_GPH(20), 2); ++ sunxi_gpio_set_cfgpin(SUNXI_GPH(21), 2); ++ sunxi_gpio_set_pull(SUNXI_GPH(21), 1); ++#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN5I) ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB19_UART0_TX); ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB20_UART0_RX); ++ sunxi_gpio_set_pull(SUNXI_GPB(20), 1); ++#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_SUN5I) ++ sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG3_UART1_TX); ++ sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART1_RX); ++ sunxi_gpio_set_pull(SUNXI_GPG(4), 1); ++#elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_SUN8I) ++ sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL2_R_UART_TX); ++ sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL3_R_UART_RX); ++ sunxi_gpio_set_pull(SUNXI_GPL(3), 1); ++#else ++#error Unsupported console port number. Please fix pin mux settings in board.c ++#endif ++ ++ return 0; ++} ++ ++void reset_cpu(ulong addr) ++{ ++ watchdog_set(0); ++ while (1); ++} ++ ++/* do some early init */ ++void s_init(void) ++{ ++#if !defined CONFIG_SPL_BUILD && (defined CONFIG_SUN7I || defined CONFIG_SUN6I) ++ /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */ ++ asm volatile( ++ "mrc p15, 0, r0, c1, c0, 1\n" ++ "orr r0, r0, #1 << 6\n" ++ "mcr p15, 0, r0, c1, c0, 1\n"); ++#endif ++ ++ watchdog_init(); ++ clock_init(); ++ timer_init(); ++ gpio_init(); ++ i2c_init_board(); ++ ++#ifdef CONFIG_SPL_BUILD ++ gd = &gdata; ++ preloader_console_init(); ++ ++#ifdef CONFIG_SPL_I2C_SUPPORT ++ /* Needed early by sunxi_board_init if PMU is enabled */ ++ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); ++#endif ++#endif ++/* No SPL on sun6i, so we do sunxi_board_init() from non spl there */ ++#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I) ++ sunxi_board_init(); ++#endif ++} ++ ++#ifndef CONFIG_SYS_DCACHE_OFF ++void enable_caches(void) ++{ ++ /* Enable D-cache. I-cache is already enabled in start.S */ ++ dcache_enable(); ++} ++#endif ++ ++#ifdef CONFIG_CMD_NET ++/* ++ * Initializes on-chip ethernet controllers. ++ * to override, implement board_eth_init() ++ */ ++int cpu_eth_init(bd_t *bis) ++{ ++ __maybe_unused int rc; ++ ++#ifdef CONFIG_MACPWR ++ gpio_direction_output(CONFIG_MACPWR, 1); ++ mdelay(200); ++#endif ++ ++#ifdef CONFIG_SUNXI_EMAC ++ rc = sunxi_emac_initialize(bis); ++ if (rc < 0) { ++ printf("sunxi: failed to initialize emac\n"); ++ return rc; ++ } ++#endif ++ ++#ifdef CONFIG_SUNXI_GMAC ++ rc = sunxi_gmac_initialize(bis); ++ if (rc < 0) { ++ printf("sunxi: failed to initialize gmac\n"); ++ return rc; ++ } ++#endif ++ ++ return 0; ++} ++#endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/sys_proto.h> ++ ++int clock_init(void) ++{ ++#ifdef CONFIG_SPL_BUILD ++ clock_init_safe(); ++#endif ++ clock_init_uart(); ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock_sun4i.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock_sun4i.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock_sun4i.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock_sun4i.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,188 @@ ++/* ++ * sun4i, sun5i and sun7i specific clock code ++ * ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/sys_proto.h> ++ ++#ifdef CONFIG_SPL_BUILD ++void clock_init_safe(void) ++{ ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ /* Set safe defaults until PMU is configured */ ++ writel(AXI_DIV_1 << AXI_DIV_SHIFT | ++ AHB_DIV_2 << AHB_DIV_SHIFT | ++ APB0_DIV_1 << APB0_DIV_SHIFT | ++ CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_ahb_apb0_cfg); ++ writel(PLL1_CFG_DEFAULT, &ccm->pll1_cfg); ++ sdelay(200); ++ writel(AXI_DIV_1 << AXI_DIV_SHIFT | ++ AHB_DIV_2 << AHB_DIV_SHIFT | ++ APB0_DIV_1 << APB0_DIV_SHIFT | ++ CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_ahb_apb0_cfg); ++#ifdef CONFIG_SUN7I ++ writel(0x1 << AHB_GATE_OFFSET_DMA | readl(&ccm->ahb_gate0), ++ &ccm->ahb_gate0); ++#endif ++ writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); ++} ++#endif ++ ++void clock_init_uart(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ /* uart clock source is apb1 */ ++ writel(APB1_CLK_SRC_OSC24M| ++ APB1_CLK_RATE_N_1| ++ APB1_CLK_RATE_M(1), ++ &ccm->apb1_clk_div_cfg); ++ ++ /* open the clock for uart */ ++ setbits_le32(&ccm->apb1_gate, ++ CLK_GATE_OPEN << (APB1_GATE_UART_SHIFT+CONFIG_CONS_INDEX-1)); ++} ++ ++int clock_twi_onoff(int port, int state) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ if (port > 2) ++ return -1; ++ ++ /* set the apb clock gate for twi */ ++ if (state) ++ setbits_le32(&ccm->apb1_gate, ++ CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT+port)); ++ else ++ clrbits_le32(&ccm->apb1_gate, ++ CLK_GATE_OPEN << (APB1_GATE_TWI_SHIFT+port)); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_SPL_BUILD ++#define PLL1_CFG(N, K, M, P) ( 1 << CCM_PLL1_CFG_ENABLE_SHIFT | \ ++ 0 << CCM_PLL1_CFG_VCO_RST_SHIFT | \ ++ 8 << CCM_PLL1_CFG_VCO_BIAS_SHIFT | \ ++ 0 << CCM_PLL1_CFG_PLL4_EXCH_SHIFT | \ ++ 16 << CCM_PLL1_CFG_BIAS_CUR_SHIFT | \ ++ (P)<< CCM_PLL1_CFG_DIVP_SHIFT | \ ++ 2 << CCM_PLL1_CFG_LCK_TMR_SHIFT | \ ++ (N)<< CCM_PLL1_CFG_FACTOR_N_SHIFT | \ ++ (K)<< CCM_PLL1_CFG_FACTOR_K_SHIFT | \ ++ 0 << CCM_PLL1_CFG_SIG_DELT_PAT_IN_SHIFT | \ ++ 0 << CCM_PLL1_CFG_SIG_DELT_PAT_EN_SHIFT | \ ++ (M)<< CCM_PLL1_CFG_FACTOR_M_SHIFT) ++ ++static struct { ++ u32 pll1_cfg; ++ unsigned int freq; ++} pll1_para[] = { ++ /* This array must be ordered by frequency. */ ++ { PLL1_CFG(16, 0, 0, 0), 384000000 }, ++ { PLL1_CFG(16, 1, 0, 0), 768000000 }, ++ { PLL1_CFG(20, 1, 0, 0), 960000000 }, ++ { PLL1_CFG(21, 1, 0, 0), 1008000000}, ++ { PLL1_CFG(22, 1, 0, 0), 1056000000}, ++ { PLL1_CFG(23, 1, 0, 0), 1104000000}, ++ { PLL1_CFG(24, 1, 0, 0), 1152000000}, ++ { PLL1_CFG(25, 1, 0, 0), 1200000000}, ++ { PLL1_CFG(26, 1, 0, 0), 1248000000}, ++ { PLL1_CFG(27, 1, 0, 0), 1296000000}, ++ { PLL1_CFG(28, 1, 0, 0), 1344000000}, ++ { PLL1_CFG(29, 1, 0, 0), 1392000000}, ++ { PLL1_CFG(30, 1, 0, 0), 1440000000}, ++ { PLL1_CFG(31, 1, 0, 0), 1488000000}, ++ /* Final catchall entry */ ++ { PLL1_CFG(31, 1, 0, 0), ~0}, ++}; ++ ++void clock_set_pll1(unsigned int hz) ++{ ++ int i = 0; ++ int axi, ahb, apb0; ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ /* Find target frequency */ ++ while (pll1_para[i].freq < hz) ++ i++; ++ ++ hz = pll1_para[i].freq; ++ ++ /* Calculate system clock divisors */ ++ axi = DIV_ROUND_UP(hz, 432000000); /* Max 450MHz */ ++ ahb = DIV_ROUND_UP(hz/axi, 204000000); /* Max 250MHz */ ++ apb0 = 2; /* Max 150MHz */ ++ ++ printf("CPU: %uHz, AXI/AHB/APB: %d/%d/%d\n", hz, axi, ahb, apb0); ++ ++ /* Map divisors to register values */ ++ axi = axi - 1; ++ if (ahb > 4) ++ ahb = 3; ++ else if (ahb > 2) ++ ahb = 2; ++ else if (ahb > 1) ++ ahb = 1; ++ else ++ ahb = 0; ++ ++ apb0 = apb0 - 1; ++ ++ /* Switch to 24MHz clock while changing PLL1 */ ++ writel(AXI_DIV_1 << AXI_DIV_SHIFT | ++ AHB_DIV_2 << AHB_DIV_SHIFT | ++ APB0_DIV_1 << APB0_DIV_SHIFT | ++ CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_ahb_apb0_cfg); ++ sdelay(20); ++ ++ /* Configure sys clock divisors */ ++ writel(axi << AXI_DIV_SHIFT | ++ ahb << AHB_DIV_SHIFT | ++ apb0 << APB0_DIV_SHIFT | ++ CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_ahb_apb0_cfg); ++ ++ /* Configure PLL1 at the desired frequency */ ++ writel(pll1_para[i].pll1_cfg, &ccm->pll1_cfg); ++ sdelay(200); ++ ++ /* Switch CPU to PLL1 */ ++ writel(axi << AXI_DIV_SHIFT | ++ ahb << AHB_DIV_SHIFT | ++ apb0 << APB0_DIV_SHIFT | ++ CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_ahb_apb0_cfg); ++ sdelay(20); ++} ++#endif ++ ++unsigned int clock_get_pll6(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ uint32_t rval = readl(&ccm->pll6_cfg); ++ int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT); ++ int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1; ++ return 24000000 * n * k / 2; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock_sun6i.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock_sun6i.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/clock_sun6i.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/clock_sun6i.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,110 @@ ++/* ++ * sun6i specific clock code ++ * ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/prcm.h> ++#include <asm/arch/sys_proto.h> ++ ++#ifdef CONFIG_SPL_BUILD ++void clock_init_safe(void) ++{ ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ struct sunxi_prcm_reg * const prcm = ++ (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE; ++ ++ /* Set PLL ldo voltage without this PLL6 does not work properly */ ++ writel(PRCM_PLL_CTRL_LDO_DIGITAL_EN | PRCM_PLL_CTRL_LDO_ANALOG_EN | ++ PRCM_PLL_CTRL_EXT_OSC_EN | PRCM_PLL_CTRL_LDO_OUT_L(1140) | ++ PRCM_PLL_CTRL_LDO_KEY, &prcm->pll_ctrl1); ++ writel(PRCM_PLL_CTRL_LDO_DIGITAL_EN | PRCM_PLL_CTRL_LDO_ANALOG_EN | ++ PRCM_PLL_CTRL_EXT_OSC_EN | PRCM_PLL_CTRL_LDO_OUT_L(1140) | ++ PRCM_PLL_CTRL_LDO_KEY, &prcm->pll_ctrl1); ++ writel(PRCM_PLL_CTRL_LDO_DIGITAL_EN | PRCM_PLL_CTRL_LDO_ANALOG_EN | ++ PRCM_PLL_CTRL_EXT_OSC_EN | PRCM_PLL_CTRL_LDO_OUT_L(1140), ++ &prcm->pll_ctrl1); ++ ++ /* AXI and PLL1 settings from boot0 / boot1, PLL1 set to 486 Mhz */ ++ writel(AXI_DIV_3 << AXI_DIV_SHIFT | ++ ATB_DIV_2 << ATB_DIV_SHIFT | ++ CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_axi_cfg); ++ writel(PLL1_CFG_DEFAULT, &ccm->pll1_cfg); ++ sdelay(200); ++ writel(AXI_DIV_3 << AXI_DIV_SHIFT | ++ ATB_DIV_2 << ATB_DIV_SHIFT | ++ CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, ++ &ccm->cpu_axi_cfg); ++ ++ writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); ++} ++#endif ++ ++void clock_init_uart(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++#if CONFIG_CONS_INDEX < 5 ++ /* uart clock source is apb2 */ ++ writel(APB2_CLK_SRC_OSC24M| ++ APB2_CLK_RATE_N_1| ++ APB2_CLK_RATE_M(1), ++ &ccm->apb2_div); ++ ++ /* open the clock for uart */ ++ setbits_le32(&ccm->apb2_gate, ++ CLK_GATE_OPEN << (APB2_GATE_UART_SHIFT+CONFIG_CONS_INDEX-1)); ++ ++ /* deassert uart reset */ ++ setbits_le32(&ccm->apb2_reset_cfg, ++ 1 << (APB2_RESET_UART_SHIFT+CONFIG_CONS_INDEX-1)); ++#else ++ /* enable R_PIO and R_UART clocks, and de-assert resets */ ++ prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_UART); ++#endif ++ ++ /* Dup with clock_init_safe(), drop once sun6i SPL support lands */ ++ writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); ++} ++ ++int clock_twi_onoff(int port, int state) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ if (port > 3) ++ return -1; ++ ++ /* set the apb clock gate for twi */ ++ if (state) ++ setbits_le32(&ccm->apb2_gate, ++ CLK_GATE_OPEN << (APB2_GATE_TWI_SHIFT+port)); ++ else ++ clrbits_le32(&ccm->apb2_gate, ++ CLK_GATE_OPEN << (APB2_GATE_TWI_SHIFT+port)); ++ ++ return 0; ++} ++ ++unsigned int clock_get_pll6(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ uint32_t rval = readl(&ccm->pll6_cfg); ++ int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1; ++ int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1; ++ return 24000000 * n * k / 2; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cmd_watchdog.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,29 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/watchdog.h> ++ ++int do_sunxi_watchdog(cmd_tbl_t *cmdtp, int flag, int argc, const char *argv[]) ++{ ++ unsigned long interval; ++ ++ if (argc < 2) { ++ printf("usage: watchdog seconds\n"); ++ printf("over %d to disable watchdog\n", WDT_MAX_TIMEOUT); ++ } ++ interval = simple_strtoul(argv[1], NULL, 10); ++ watchdog_set((unsigned int)interval); ++ ++ return 0; ++} ++ ++U_BOOT_CMD( ++ watchdog, 2, 1, do_sunxi_watchdog, ++ "Set watchdog [0 - 16]. [17+} disables", ++ "" ++); +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/config.mk u-boot-sunxi/arch/arm/cpu/armv7/sunxi/config.mk +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/config.mk 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/config.mk 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,8 @@ ++# Build a combined spl + u-boot image ++ifdef CONFIG_SPL ++ifndef CONFIG_SPL_BUILD ++ifndef CONFIG_SPL_FEL ++ALL-y += u-boot-sunxi-with-spl.bin ++endif ++endif ++endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/cpu_info.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cpu_info.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/cpu_info.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/cpu_info.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,38 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/cpu.h> ++ ++#ifdef CONFIG_DISPLAY_CPUINFO ++int print_cpuinfo(void) ++{ ++#ifdef CONFIG_SUN4I ++ puts("CPU: Allwinner A10 (SUN4I)\n"); ++#elif defined CONFIG_SUN5I ++ u32 val = readl(SUNXI_SID_BASE + 0x08); ++ switch ((val >> 12) & 0xf) { ++ case 0: puts("CPU: Allwinner A12 (SUN5I)\n"); break; ++ case 3: puts("CPU: Allwinner A13 (SUN5I)\n"); break; ++ case 7: puts("CPU: Allwinner A10s (SUN5I)\n"); break; ++ default: puts("CPU: Allwinner A1X (SUN5I)\n"); ++ } ++#elif defined CONFIG_SUN6I ++ puts("CPU: Allwinner A31 (SUN6I)\n"); ++#elif defined CONFIG_SUN7I ++ puts("CPU: Allwinner A20 (SUN7I)\n"); ++#elif defined CONFIG_SUN8I ++ puts("CPU: Allwinner A23 (SUN8I)\n"); ++#else ++#warning Please update cpu_info.c with correct CPU information ++ puts("CPU: SUNXI Family\n"); ++#endif ++ return 0; ++} ++#endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/dram.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/dram.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/dram.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/dram.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,693 @@ ++/* ++ * sunxi DRAM controller initialization ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * Based on sun4i Linux kernel sources mach-sunxi/pm/standby/dram*.c ++ * and earlier U-Boot Allwiner A10 SPL work ++ * ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++/* ++ * Unfortunately the only documentation we have on the sun7i DRAM ++ * controller is Allwinner boot0 + boot1 code, and that code uses ++ * magic numbers & shifts with no explanations. Hence this code is ++ * rather undocumented and full of magic. ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/dram.h> ++#include <asm/arch/timer.h> ++#include <asm/arch/sys_proto.h> ++ ++#define CPU_CFG_CHIP_VER(n) ((n) << 6) ++#define CPU_CFG_CHIP_VER_MASK CPU_CFG_CHIP_VER(0x3) ++#define CPU_CFG_CHIP_REV_A 0x0 ++#define CPU_CFG_CHIP_REV_C1 0x1 ++#define CPU_CFG_CHIP_REV_C2 0x2 ++#define CPU_CFG_CHIP_REV_B 0x3 ++ ++/* ++ * Wait up to 1s for mask to be clear in given reg. ++ */ ++static void await_completion(u32 *reg, u32 mask) ++{ ++ unsigned long tmo = timer_get_us() + 1000000; ++ ++ while (readl(reg) & mask) { ++ if (timer_get_us() > tmo) ++ panic("Timeout initialising DRAM\n"); ++ } ++} ++ ++static void mctl_ddr3_reset(void) ++{ ++ struct sunxi_dram_reg *dram = ++ (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++#ifdef CONFIG_SUN4I ++ struct sunxi_timer_reg *timer = ++ (struct sunxi_timer_reg *)SUNXI_TIMER_BASE; ++ u32 reg_val; ++ ++ writel(0, &timer->cpu_cfg); ++ reg_val = readl(&timer->cpu_cfg); ++ ++ if ((reg_val & CPU_CFG_CHIP_VER_MASK) != ++ CPU_CFG_CHIP_VER(CPU_CFG_CHIP_REV_A)) { ++ setbits_le32(&dram->mcr, DRAM_MCR_RESET); ++ udelay(2); ++ clrbits_le32(&dram->mcr, DRAM_MCR_RESET); ++ } else ++#endif ++ { ++ clrbits_le32(&dram->mcr, DRAM_MCR_RESET); ++ udelay(2); ++ setbits_le32(&dram->mcr, DRAM_MCR_RESET); ++ } ++} ++ ++static void mctl_set_drive(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++#ifdef CONFIG_SUN7I ++ clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3) | (0x3 << 28), ++#else ++ clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3), ++#endif ++ DRAM_MCR_MODE_EN(0x3) | ++ 0xffc); ++} ++ ++static void mctl_itm_disable(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++ clrsetbits_le32(&dram->ccr, DRAM_CCR_INIT, DRAM_CCR_ITM_OFF); ++} ++ ++static void mctl_itm_enable(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++ clrbits_le32(&dram->ccr, DRAM_CCR_ITM_OFF); ++} ++ ++static void mctl_enable_dll0(u32 phase) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++ clrsetbits_le32(&dram->dllcr[0], 0x3f << 6, ++ ((phase >> 16) & 0x3f) << 6); ++ clrsetbits_le32(&dram->dllcr[0], DRAM_DLLCR_NRESET, DRAM_DLLCR_DISABLE); ++ udelay(2); ++ ++ clrbits_le32(&dram->dllcr[0], DRAM_DLLCR_NRESET | DRAM_DLLCR_DISABLE); ++ udelay(22); ++ ++ clrsetbits_le32(&dram->dllcr[0], DRAM_DLLCR_DISABLE, DRAM_DLLCR_NRESET); ++ udelay(22); ++} ++ ++/* ++ * Note: This differs from pm/standby in that it checks the bus width ++ */ ++static void mctl_enable_dllx(u32 phase) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 i, n, bus_width; ++ ++ bus_width = readl(&dram->dcr); ++ ++ if ((bus_width & DRAM_DCR_BUS_WIDTH_MASK) == ++ DRAM_DCR_BUS_WIDTH(DRAM_DCR_BUS_WIDTH_32BIT)) ++ n = DRAM_DCR_NR_DLLCR_32BIT; ++ else ++ n = DRAM_DCR_NR_DLLCR_16BIT; ++ ++ for (i = 1; i < n; i++) { ++ clrsetbits_le32(&dram->dllcr[i], 0xf << 14, ++ (phase & 0xf) << 14); ++ clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET, ++ DRAM_DLLCR_DISABLE); ++ phase >>= 4; ++ } ++ udelay(2); ++ ++ for (i = 1; i < n; i++) ++ clrbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET | ++ DRAM_DLLCR_DISABLE); ++ udelay(22); ++ ++ for (i = 1; i < n; i++) ++ clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_DISABLE, ++ DRAM_DLLCR_NRESET); ++ udelay(22); ++} ++ ++static u32 hpcr_value[32] = { ++#ifdef CONFIG_SUN5I ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, ++ 0x1031, 0x1031, 0x0735, 0x1035, ++ 0x1035, 0x0731, 0x1031, 0, ++ 0x0301, 0x0301, 0x0301, 0x0301, ++ 0x0301, 0x0301, 0x0301, 0 ++#endif ++#ifdef CONFIG_SUN4I ++ 0x0301, 0x0301, 0x0301, 0x0301, ++ 0x0301, 0x0301, 0, 0, ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, ++ 0x1031, 0x1031, 0x0735, 0x5031, ++ 0x1035, 0x0731, 0x1031, 0x0735, ++ 0x1035, 0x1031, 0x0731, 0x1035, ++ 0x1031, 0x0301, 0x0301, 0x0731 ++#endif ++#ifdef CONFIG_SUN7I ++ 0x0301, 0x0301, 0x0301, 0x0301, ++ 0x0301, 0x0301, 0x0301, 0x0301, ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, ++ 0x1031, 0x1031, 0x0735, 0x1035, ++ 0x1035, 0x0731, 0x1031, 0x0735, ++ 0x1035, 0x1031, 0x0731, 0x1035, ++ 0x0001, 0x1031, 0, 0x1031 ++ /* last row differs from boot0 source table ++ * 0x1031, 0x0301, 0x0301, 0x0731 ++ * but boot0 code skips #28 and #30, and sets #29 and #31 to the ++ * value from #28 entry (0x1031) ++ */ ++#endif ++}; ++ ++static void mctl_configure_hostport(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 i; ++ ++ for (i = 0; i < 32; i++) ++ writel(hpcr_value[i], &dram->hpcr[i]); ++} ++ ++static void mctl_setup_dram_clock(u32 clk) ++{ ++ u32 reg_val; ++ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ /* setup DRAM PLL */ ++ reg_val = readl(&ccm->pll5_cfg); ++ reg_val &= ~CCM_PLL5_CTRL_M_MASK; /* set M to 0 (x1) */ ++ reg_val &= ~CCM_PLL5_CTRL_K_MASK; /* set K to 0 (x1) */ ++ reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */ ++ reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */ ++ if (clk >= 540 && clk < 552) { ++ /* dram = 540MHz, pll5p = 540MHz */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15)); ++ reg_val |= CCM_PLL5_CTRL_P(1); ++ } else if (clk >= 512 && clk < 528) { ++ /* dram = 512MHz, pll5p = 384MHz */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16)); ++ reg_val |= CCM_PLL5_CTRL_P(2); ++ } else if (clk >= 496 && clk < 504) { ++ /* dram = 496MHz, pll5p = 372MHz */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31)); ++ reg_val |= CCM_PLL5_CTRL_P(2); ++ } else if (clk >= 468 && clk < 480) { ++ /* dram = 468MHz, pll5p = 468MHz */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13)); ++ reg_val |= CCM_PLL5_CTRL_P(1); ++ } else if (clk >= 396 && clk < 408) { ++ /* dram = 396MHz, pll5p = 396MHz */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11)); ++ reg_val |= CCM_PLL5_CTRL_P(1); ++ } else { ++ /* any other frequency that is a multiple of 24 */ ++ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); ++ reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2)); ++ reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24)); ++ reg_val |= CCM_PLL5_CTRL_P(CCM_PLL5_CTRL_P_X(2)); ++ } ++ reg_val &= ~CCM_PLL5_CTRL_VCO_GAIN; /* PLL VCO Gain off */ ++ reg_val |= CCM_PLL5_CTRL_EN; /* PLL On */ ++ writel(reg_val, &ccm->pll5_cfg); ++ udelay(5500); ++ ++ setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_DDR_CLK); ++ ++#if defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I) ++ /* reset GPS */ ++ clrbits_le32(&ccm->gps_clk_cfg, CCM_GPS_CTRL_RESET | CCM_GPS_CTRL_GATE); ++ setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS); ++ udelay(1); ++ clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS); ++#endif ++ ++#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) ++ /* setup MBUS clock */ ++ reg_val = CCM_MBUS_CTRL_GATE | ++#if defined(CONFIG_SUN7I) && defined(CONFIG_FAST_MBUS) ++ CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) | ++ CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) | ++ CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(3)); ++#elif defined(CONFIG_SUN7I) && !defined(CONFIG_FAST_MBUS) ++ CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) | ++ CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(2)) | ++ CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2)); ++#else /* defined(CONFIG_SUN5I) */ ++ CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL5) | ++ CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) | ++ CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2)); ++#endif ++ writel(reg_val, &ccm->mbus_clk_cfg); ++#endif ++ ++ /* ++ * open DRAMC AHB & DLL register clock ++ * close it first ++ */ ++#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) ++ clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL); ++#else ++ clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM); ++#endif ++ udelay(22); ++ ++ /* then open it */ ++#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) ++ setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL); ++#else ++ setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM); ++#endif ++ udelay(22); ++} ++ ++static int dramc_scan_readpipe(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 reg_val; ++ ++ /* data training trigger */ ++#ifdef CONFIG_SUN7I ++ clrbits_le32(&dram->csr, DRAM_CSR_FAILED); ++#endif ++ setbits_le32(&dram->ccr, DRAM_CCR_DATA_TRAINING); ++ ++ /* check whether data training process has completed */ ++ await_completion(&dram->ccr, DRAM_CCR_DATA_TRAINING); ++ ++ /* check data training result */ ++ reg_val = readl(&dram->csr); ++ if (reg_val & DRAM_CSR_FAILED) ++ return -1; ++ ++ return 0; ++} ++ ++static int dramc_scan_dll_para(void) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ const u32 dqs_dly[7] = {0x3, 0x2, 0x1, 0x0, 0xe, 0xd, 0xc}; ++ const u32 clk_dly[15] = {0x07, 0x06, 0x05, 0x04, 0x03, ++ 0x02, 0x01, 0x00, 0x08, 0x10, ++ 0x18, 0x20, 0x28, 0x30, 0x38}; ++ u32 clk_dqs_count[15]; ++ u32 dqs_i, clk_i, cr_i; ++ u32 max_val, min_val; ++ u32 dqs_index, clk_index; ++ ++ /* Find DQS_DLY Pass Count for every CLK_DLY */ ++ for (clk_i = 0; clk_i < 15; clk_i++) { ++ clk_dqs_count[clk_i] = 0; ++ clrsetbits_le32(&dram->dllcr[0], 0x3f << 6, ++ (clk_dly[clk_i] & 0x3f) << 6); ++ for (dqs_i = 0; dqs_i < 7; dqs_i++) { ++ for (cr_i = 1; cr_i < 5; cr_i++) { ++ clrsetbits_le32(&dram->dllcr[cr_i], ++ 0x4f << 14, ++ (dqs_dly[dqs_i] & 0x4f) << 14); ++ } ++ udelay(2); ++ if (dramc_scan_readpipe() == 0) ++ clk_dqs_count[clk_i]++; ++ } ++ } ++ /* Test DQS_DLY Pass Count for every CLK_DLY from up to down */ ++ for (dqs_i = 15; dqs_i > 0; dqs_i--) { ++ max_val = 15; ++ min_val = 15; ++ for (clk_i = 0; clk_i < 15; clk_i++) { ++ if (clk_dqs_count[clk_i] == dqs_i) { ++ max_val = clk_i; ++ if (min_val == 15) ++ min_val = clk_i; ++ } ++ } ++ if (max_val < 15) ++ break; ++ } ++ ++ /* Check if Find a CLK_DLY failed */ ++ if (!dqs_i) ++ goto fail; ++ ++ /* Find the middle index of CLK_DLY */ ++ clk_index = (max_val + min_val) >> 1; ++ if ((max_val == (15 - 1)) && (min_val > 0)) ++ /* if CLK_DLY[MCTL_CLK_DLY_COUNT] is very good, then the middle ++ * value can be more close to the max_val ++ */ ++ clk_index = (15 + clk_index) >> 1; ++ else if ((max_val < (15 - 1)) && (min_val == 0)) ++ /* if CLK_DLY[0] is very good, then the middle value can be more ++ * close to the min_val ++ */ ++ clk_index >>= 1; ++ if (clk_dqs_count[clk_index] < dqs_i) ++ clk_index = min_val; ++ ++ /* Find the middle index of DQS_DLY for the CLK_DLY got above, and Scan ++ * read pipe again ++ */ ++ clrsetbits_le32(&dram->dllcr[0], 0x3f << 6, ++ (clk_dly[clk_index] & 0x3f) << 6); ++ max_val = 7; ++ min_val = 7; ++ for (dqs_i = 0; dqs_i < 7; dqs_i++) { ++ clk_dqs_count[dqs_i] = 0; ++ for (cr_i = 1; cr_i < 5; cr_i++) { ++ clrsetbits_le32(&dram->dllcr[cr_i], ++ 0x4f << 14, ++ (dqs_dly[dqs_i] & 0x4f) << 14); ++ } ++ udelay(2); ++ if (dramc_scan_readpipe() == 0) { ++ clk_dqs_count[dqs_i] = 1; ++ max_val = dqs_i; ++ if (min_val == 7) ++ min_val = dqs_i; ++ } ++ } ++ ++ if (max_val < 7) { ++ dqs_index = (max_val + min_val) >> 1; ++ if ((max_val == (7-1)) && (min_val > 0)) ++ dqs_index = (7 + dqs_index) >> 1; ++ else if ((max_val < (7-1)) && (min_val == 0)) ++ dqs_index >>= 1; ++ if (!clk_dqs_count[dqs_index]) ++ dqs_index = min_val; ++ for (cr_i = 1; cr_i < 5; cr_i++) { ++ clrsetbits_le32(&dram->dllcr[cr_i], ++ 0x4f << 14, ++ (dqs_dly[dqs_index] & 0x4f) << 14); ++ } ++ udelay(2); ++ return dramc_scan_readpipe(); ++ } ++ ++fail: ++ clrbits_le32(&dram->dllcr[0], 0x3f << 6); ++ for (cr_i = 1; cr_i < 5; cr_i++) ++ clrbits_le32(&dram->dllcr[cr_i], 0x4f << 14); ++ udelay(2); ++ ++ return dramc_scan_readpipe(); ++} ++ ++static void dramc_clock_output_en(u32 on) ++{ ++#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ ++ if (on) ++ setbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT); ++ else ++ clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT); ++#endif ++#ifdef CONFIG_SUN4I ++ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ if (on) ++ setbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT); ++ else ++ clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT); ++#endif ++} ++ ++static const u16 tRFC_table[2][6] = { ++ /* 256Mb 512Mb 1Gb 2Gb 4Gb 8Gb */ ++ /* DDR2 75ns 105ns 127.5ns 195ns 327.5ns invalid */ ++ { 77, 108, 131, 200, 336, 336 }, ++ /* DDR3 invalid 90ns 110ns 160ns 300ns 350ns */ ++ { 93, 93, 113, 164, 308, 359 } ++}; ++ ++static void dramc_set_autorefresh_cycle(u32 clk, u32 type, u32 density) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 tRFC, tREFI; ++ ++ tRFC = (tRFC_table[type][density] * clk + 1023) >> 10; ++ tREFI = (7987 * clk) >> 10; /* <= 7.8us */ ++ ++ writel(DRAM_DRR_TREFI(tREFI) | DRAM_DRR_TRFC(tRFC), &dram->drr); ++} ++ ++unsigned long dramc_init(struct dram_para *para) ++{ ++ struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; ++ u32 reg_val; ++ u32 density; ++ int ret_val; ++ ++ /* check input dram parameter structure */ ++ if (!para) ++ return 0; ++ ++ /* setup DRAM relative clock */ ++ mctl_setup_dram_clock(para->clock); ++ ++#ifdef CONFIG_SUN5I ++ /* Disable any pad power save control */ ++ writel(0, &dram->ppwrsctl); ++#endif ++ ++ /* reset external DRAM */ ++#ifndef CONFIG_SUN7I ++ mctl_ddr3_reset(); ++#endif ++ mctl_set_drive(); ++ ++ /* dram clock off */ ++ dramc_clock_output_en(0); ++ ++#ifdef CONFIG_SUN4I ++ /* select dram controller 1 */ ++ writel(DRAM_CSEL_MAGIC, &dram->csel); ++#endif ++ ++ mctl_itm_disable(); ++ mctl_enable_dll0(para->tpr3); ++ ++ /* configure external DRAM */ ++ reg_val = 0x0; ++ if (para->type == DRAM_MEMORY_TYPE_DDR3) ++ reg_val |= DRAM_DCR_TYPE_DDR3; ++ reg_val |= DRAM_DCR_IO_WIDTH(para->io_width >> 3); ++ ++ if (para->density == 256) ++ density = DRAM_DCR_CHIP_DENSITY_256M; ++ else if (para->density == 512) ++ density = DRAM_DCR_CHIP_DENSITY_512M; ++ else if (para->density == 1024) ++ density = DRAM_DCR_CHIP_DENSITY_1024M; ++ else if (para->density == 2048) ++ density = DRAM_DCR_CHIP_DENSITY_2048M; ++ else if (para->density == 4096) ++ density = DRAM_DCR_CHIP_DENSITY_4096M; ++ else if (para->density == 8192) ++ density = DRAM_DCR_CHIP_DENSITY_8192M; ++ else ++ density = DRAM_DCR_CHIP_DENSITY_256M; ++ ++ reg_val |= DRAM_DCR_CHIP_DENSITY(density); ++ reg_val |= DRAM_DCR_BUS_WIDTH((para->bus_width >> 3) - 1); ++ reg_val |= DRAM_DCR_RANK_SEL(para->rank_num - 1); ++ reg_val |= DRAM_DCR_CMD_RANK_ALL; ++ reg_val |= DRAM_DCR_MODE(DRAM_DCR_MODE_INTERLEAVE); ++ writel(reg_val, &dram->dcr); ++ ++#ifdef CONFIG_SUN7I ++ setbits_le32(&dram->zqcr1, (0x1 << 24) | (0x1 << 1)); ++ if (para->tpr4 & 0x2) ++ clrsetbits_le32(&dram->zqcr1, (0x1 << 24), (0x1 << 1)); ++ dramc_clock_output_en(1); ++#endif ++ ++#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)) ++ /* set odt impendance divide ratio */ ++ reg_val = ((para->zq) >> 8) & 0xfffff; ++ reg_val |= ((para->zq) & 0xff) << 20; ++ reg_val |= (para->zq) & 0xf0000000; ++ writel(reg_val, &dram->zqcr0); ++#endif ++ ++#ifdef CONFIG_SUN7I ++ /* Set CKE Delay to about 1ms */ ++ setbits_le32(&dram->idcr, 0x1ffff); ++#endif ++ ++#ifdef CONFIG_SUN7I ++ if ((readl(&dram->ppwrsctl) & 0x1) != 0x1) ++ mctl_ddr3_reset(); ++ else ++ setbits_le32(&dram->mcr, DRAM_MCR_RESET); ++#else ++ /* dram clock on */ ++ dramc_clock_output_en(1); ++#endif ++ ++ udelay(1); ++ ++ await_completion(&dram->ccr, DRAM_CCR_INIT); ++ ++ mctl_enable_dllx(para->tpr3); ++ ++#ifdef CONFIG_SUN4I ++ /* set odt impedance divide ratio */ ++ reg_val = ((para->zq) >> 8) & 0xfffff; ++ reg_val |= ((para->zq) & 0xff) << 20; ++ reg_val |= (para->zq) & 0xf0000000; ++ writel(reg_val, &dram->zqcr0); ++#endif ++ ++#ifdef CONFIG_SUN4I ++ /* set I/O configure register */ ++ reg_val = 0x00cc0000; ++ reg_val |= (para->odt_en) & 0x3; ++ reg_val |= ((para->odt_en) & 0x3) << 30; ++ writel(reg_val, &dram->iocr); ++#endif ++ ++ /* set refresh period */ ++ dramc_set_autorefresh_cycle(para->clock, para->type - 2, density); ++ ++ /* set timing parameters */ ++ writel(para->tpr0, &dram->tpr0); ++ writel(para->tpr1, &dram->tpr1); ++ writel(para->tpr2, &dram->tpr2); ++ ++ if (para->type == DRAM_MEMORY_TYPE_DDR3) { ++ reg_val = DRAM_MR_BURST_LENGTH(0x0); ++#if (defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I)) ++ reg_val |= DRAM_MR_POWER_DOWN; ++#endif ++ reg_val |= DRAM_MR_CAS_LAT(para->cas - 4); ++ reg_val |= DRAM_MR_WRITE_RECOVERY(0x5); ++ } else if (para->type == DRAM_MEMORY_TYPE_DDR2) { ++ reg_val = DRAM_MR_BURST_LENGTH(0x2); ++ reg_val |= DRAM_MR_CAS_LAT(para->cas); ++ reg_val |= DRAM_MR_WRITE_RECOVERY(0x5); ++ } ++ writel(reg_val, &dram->mr); ++ ++ writel(para->emr1, &dram->emr); ++ writel(para->emr2, &dram->emr2); ++ writel(para->emr3, &dram->emr3); ++ ++ /* set DQS window mode */ ++ clrsetbits_le32(&dram->ccr, DRAM_CCR_DQS_DRIFT_COMP, DRAM_CCR_DQS_GATE); ++ ++#ifdef CONFIG_SUN7I ++ /* Command rate timing mode 2T & 1T */ ++ if (para->tpr4 & 0x1) ++ setbits_le32(&dram->ccr, DRAM_CCR_COMMAND_RATE_1T); ++#endif ++ /* reset external DRAM */ ++ setbits_le32(&dram->ccr, DRAM_CCR_INIT); ++ await_completion(&dram->ccr, DRAM_CCR_INIT); ++ ++#ifdef CONFIG_SUN7I ++ /* setup zq calibration manual */ ++ reg_val = readl(&dram->ppwrsctl); ++ if ((reg_val & 0x1) == 1) { ++ /* super_standby_flag = 1 */ ++ ++ reg_val = readl(0x01c20c00 + 0x120); /* rtc */ ++ reg_val &= 0x000fffff; ++ reg_val |= 0x17b00000; ++ writel(reg_val, &dram->zqcr0); ++ ++ /* exit self-refresh state */ ++ clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27); ++ /* check whether command has been executed */ ++ await_completion(&dram->dcr, 0x1 << 31); ++ ++ udelay(2); ++ ++ /* dram pad hold off */ ++ setbits_le32(&dram->ppwrsctl, 0x16510000); ++ ++ await_completion(&dram->ppwrsctl, 0x1); ++ ++ /* exit self-refresh state */ ++ clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x12 << 27); ++ ++ /* check whether command has been executed */ ++ await_completion(&dram->dcr, 0x1 << 31); ++ ++ udelay(2); ++ ++ /* issue a refresh command */ ++ clrsetbits_le32(&dram->dcr, 0x1f << 27, 0x13 << 27); ++ await_completion(&dram->dcr, 0x1 << 31); ++ ++ udelay(2); ++ } ++#endif ++ ++ /* scan read pipe value */ ++ mctl_itm_enable(); ++ if (para->tpr3 & (0x1 << 31)) { ++ ret_val = dramc_scan_dll_para(); ++ if (ret_val == 0) ++ para->tpr3 = ++ (((readl(&dram->dllcr[0]) >> 6) & 0x3f) << 16) | ++ (((readl(&dram->dllcr[1]) >> 14) & 0xf) << 0) | ++ (((readl(&dram->dllcr[2]) >> 14) & 0xf) << 4) | ++ (((readl(&dram->dllcr[3]) >> 14) & 0xf) << 8) | ++ (((readl(&dram->dllcr[4]) >> 14) & 0xf) << 12 ++ ); ++ } else { ++ ret_val = dramc_scan_readpipe(); ++ } ++ ++ if (ret_val < 0) ++ return 0; ++ ++ /* configure all host port */ ++ mctl_configure_hostport(); ++ ++ return get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/early_print.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/early_print.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/early_print.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/early_print.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,55 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Early uart print for debugging. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/cpu.h> ++#include <asm/arch/early_print.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/sys_proto.h> ++ ++static int uart_initialized = 0; ++ ++#if CONFIG_CONS_INDEX < 5 ++#define UART CONFIG_CONS_INDEX-1 ++#else ++/* SUNXI_R_UART_BASE */ ++#define UART 2922 ++#endif ++ ++void uart_init(void) { ++ ++ /* select dll dlh */ ++ writel(UART_LCR_DLAB, UART_LCR(UART)); ++ /* set baudrate */ ++ writel(0, UART_DLH(UART)); ++ writel(BAUD_115200, UART_DLL(UART)); ++ /* set line control */ ++ writel(LC_8_N_1, UART_LCR(UART)); ++ ++ uart_initialized = 1; ++} ++ ++#define TX_READY (readl(UART_LSR(UART)) & UART_LSR_TEMT) ++ ++void uart_putc(char c) { ++ ++ while (!TX_READY) ++ ; ++ writel(c, UART_THR(UART)); ++} ++ ++void uart_puts(const char *s) { ++ ++ while (*s) ++ uart_putc(*s++); ++} ++ ++ +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/Makefile u-boot-sunxi/arch/arm/cpu/armv7/sunxi/Makefile +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/Makefile 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,44 @@ ++# ++# (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++# ++# Based on some other Makefile ++# (C) Copyright 2000-2003 ++# Wolfgang Denk, DENX Software Engineering, wd@denx.de. ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++obj-y += timer.o ++obj-y += board.o ++obj-y += clock.o ++obj-y += pinmux.o ++obj-y += watchdog.o ++obj-$(CONFIG_SUN6I) += prcm.o ++obj-$(CONFIG_SUN8I) += prcm.o ++obj-$(CONFIG_SUN6I) += p2wi.o ++obj-$(CONFIG_SUN4I) += clock_sun4i.o ++obj-$(CONFIG_SUN5I) += clock_sun4i.o ++obj-$(CONFIG_SUN6I) += clock_sun6i.o ++obj-$(CONFIG_SUN7I) += clock_sun4i.o ++obj-$(CONFIG_SUN8I) += clock_sun6i.o ++ifdef DEBUG ++obj-y += early_print.o ++endif ++obj-$(CONFIG_BOARD_POSTCLK_INIT) += postclk_init.o ++obj-$(CONFIG_SYS_SECONDARY_ON) += secondary_init.o ++obj-$(CONFIG_SYS_SECONDARY_ON) += smp.o ++ ++ifndef CONFIG_SPL_BUILD ++obj-y += cpu_info.o ++ifdef CONFIG_CMD_WATCHDOG ++obj-$(CONFIG_CMD_WATCHDOG) += cmd_watchdog.o ++endif ++endif ++ ++ifdef CONFIG_SPL_BUILD ++obj-$(CONFIG_SUN4I) += dram.o ++obj-$(CONFIG_SUN5I) += dram.o ++obj-$(CONFIG_SUN7I) += dram.o ++ifdef CONFIG_SPL_FEL ++obj-y += start.o ++endif ++endif +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/p2wi.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/p2wi.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/p2wi.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/p2wi.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,120 @@ ++/* ++ * Sunxi A31 Power Management Unit ++ * ++ * (C) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://linux-sunxi.org ++ * ++ * Based on sun6i sources and earlier U-Boot Allwiner A10 SPL work ++ * ++ * (C) Copyright 2006-2013 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <errno.h> ++#include <asm/io.h> ++#include <asm/arch/cpu.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/p2wi.h> ++#include <asm/arch/prcm.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/sys_proto.h> ++ ++void p2wi_init(void) ++{ ++ struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; ++ ++ /* Enable p2wi and PIO clk, and de-assert their resets */ ++ prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_P2WI); ++ ++ sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUNXI_GPL0_R_P2WI_SCK); ++ sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUNXI_GPL1_R_P2WI_SDA); ++ ++ /* Reset p2wi controller and set clock to CLKIN(12)/8 = 1.5 MHz */ ++ writel(P2WI_CTRL_RESET, &p2wi->ctrl); ++ sdelay(0x100); ++ writel(P2WI_CC_SDA_OUT_DELAY(1) | P2WI_CC_CLK_DIV(8), ++ &p2wi->cc); ++} ++ ++int p2wi_set_pmu_address(u8 slave_addr, u8 ctrl_reg, u8 init_data) ++{ ++ struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; ++ int i; ++ ++ writel(P2WI_PM_DEV_ADDR(slave_addr) | ++ P2WI_PM_CTRL_ADDR(ctrl_reg) | ++ P2WI_PM_INIT_DATA(init_data) | ++ P2WI_PM_INIT_SEND, ++ &p2wi->pm); ++ for (i = 0xffffff; i != 0; i--) ++ if (!(readl(&p2wi->pm) & P2WI_PM_INIT_SEND)) ++ break; ++ if (readl(&p2wi->pm) & P2WI_PM_INIT_SEND) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++int p2wi_read(const u8 addr, u8 *data) ++{ ++ struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; ++ int i, ret = 0; ++ u8 reg; ++ ++ writel(P2WI_DATADDR_BYTE_1(addr), &p2wi->dataddr0); ++ writel(P2WI_DATA_NUM_BYTES(1) | ++ P2WI_DATA_NUM_BYTES_READ, &p2wi->numbytes); ++ writel(P2WI_STAT_TRANS_DONE, &p2wi->status); ++ writel(P2WI_CTRL_TRANS_START, &p2wi->ctrl); ++ ++ for (i = 0xffffff; i != 0; i--) { ++ reg = readl(&p2wi->status); ++ if (reg & P2WI_STAT_TRANS_ERR) { ++ ret = -EIO; ++ break; ++ } ++ if (reg & P2WI_STAT_TRANS_DONE) ++ break; ++ } ++ ++ if (i == 0) ++ ret = -ETIME; ++ ++ *data = readl(&p2wi->data0) & P2WI_DATA_BYTE_1_MASK; ++ writel(reg, &p2wi->status); /* Clear status bits */ ++ return ret; ++} ++ ++int p2wi_write(const u8 addr, u8 data) ++{ ++ struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; ++ int i, ret = 0; ++ u8 reg; ++ ++ writel(P2WI_DATADDR_BYTE_1(addr), &p2wi->dataddr0); ++ writel(P2WI_DATA_BYTE_1(data), &p2wi->data0); ++ writel(P2WI_DATA_NUM_BYTES(1), &p2wi->numbytes); ++ writel(P2WI_STAT_TRANS_DONE, &p2wi->status); ++ writel(P2WI_CTRL_TRANS_START, &p2wi->ctrl); ++ ++ for (i = 0xffffff; i != 0; i--) { ++ reg = readl(&p2wi->status); ++ if (reg & P2WI_STAT_TRANS_ERR) { ++ ret = -EIO; ++ break; ++ } ++ if (reg & P2WI_STAT_TRANS_DONE) ++ break; ++ } ++ ++ if (i == 0) ++ ret = -ETIME; ++ ++ writel(reg, &p2wi->status); /* Clear status bits */ ++ return ret; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/pinmux.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/pinmux.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/pinmux.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/pinmux.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,61 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/gpio.h> ++ ++int sunxi_gpio_set_cfgpin(u32 pin, u32 val) ++{ ++ u32 bank = GPIO_BANK(pin); ++ u32 index = GPIO_CFG_INDEX(pin); ++ u32 offset = GPIO_CFG_OFFSET(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ clrsetbits_le32(&pio->cfg[0] + index, 0xf << offset, val << offset); ++ ++ return 0; ++} ++ ++int sunxi_gpio_get_cfgpin(u32 pin) ++{ ++ u32 cfg; ++ u32 bank = GPIO_BANK(pin); ++ u32 index = GPIO_CFG_INDEX(pin); ++ u32 offset = GPIO_CFG_OFFSET(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ cfg = readl(&pio->cfg[0] + index); ++ cfg >>= offset; ++ ++ return cfg & 0xf; ++} ++ ++int sunxi_gpio_set_drv(u32 pin, u32 val) ++{ ++ u32 bank = GPIO_BANK(pin); ++ u32 index = GPIO_DRV_INDEX(pin); ++ u32 offset = GPIO_DRV_OFFSET(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ clrsetbits_le32(&pio->drv[0] + index, 0x3 << offset, val << offset); ++ ++ return 0; ++} ++ ++int sunxi_gpio_set_pull(u32 pin, u32 val) ++{ ++ u32 bank = GPIO_BANK(pin); ++ u32 index = GPIO_PULL_INDEX(pin); ++ u32 offset = GPIO_PULL_OFFSET(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ clrsetbits_le32(&pio->pull[0] + index, 0x3 << offset, val << offset); ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/postclk_init.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/postclk_init.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/postclk_init.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/postclk_init.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik carl@ok-labs.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#if defined(CONFIG_SYS_SECONDARY_ON) ++#include <asm/arch/smp.h> ++#endif ++ ++ ++int board_postclk_init(void) ++{ ++#if defined(CONFIG_SYS_SECONDARY_ON) ++ startup_secondaries(); ++#endif ++ return 0; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/prcm.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/prcm.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/prcm.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/prcm.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,35 @@ ++/* ++ * Sunxi A31 Power Management Unit ++ * ++ * (C) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://linux-sunxi.org ++ * ++ * Based on sun6i sources and earlier U-Boot Allwiner A10 SPL work ++ * ++ * (C) Copyright 2006-2013 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <errno.h> ++#include <asm/io.h> ++#include <asm/arch/cpu.h> ++#include <asm/arch/prcm.h> ++#include <asm/arch/sys_proto.h> ++ ++/* APB0 clock gate and reset bit offsets are the same. */ ++void prcm_apb0_enable(u32 flags) ++{ ++ struct sunxi_prcm_reg *prcm = ++ (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE; ++ ++ /* open the clock for module */ ++ setbits_le32(&prcm->apb0_gate, flags); ++ ++ /* deassert reset for module */ ++ setbits_le32(&prcm->apb0_reset, flags); ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/secondary_init.S u-boot-sunxi/arch/arm/cpu/armv7/sunxi/secondary_init.S +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/secondary_init.S 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/secondary_init.S 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,31 @@ ++/* ++ * A lowlevel_init function that sets up the stack to call a C function to ++ * perform further init. ++ * ++ * (C) Copyright 2013 ++ * Carl van Schaik carl@ok-labs.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#include <asm-offsets.h> ++#include <config.h> ++#include <linux/linkage.h> ++ ++ENTRY(secondary_init) ++ /* Get cpu number : r5 */ ++ mrc p15, 0, r5, c0, c0, 5 ++ and r5, r5, #0xff ++ ++ /* ++ * Setup a secondary stack, each core gets 128 bytes. ++ */ ++ ldr sp, =secondary_stack ++ mov r0, #0x80 ++ add sp, sp, r0, lsl r5 ++ ++ /* ++ * Jump to C ++ */ ++ bl secondary_start ++ENDPROC(secondary_init) ++ +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/smp.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/smp.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/smp.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/smp.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,80 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik carl@ok-labs.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/smp.h> ++#include <asm/arch/cpucfg.h> ++ ++/* Right now we assume only a single secondary as in sun7i */ ++#if defined(CONFIG_SUN7I) ++#define NUM_CORES 2 ++#else ++#error unsupported SoC ++#endif ++ ++static void secondary_pen(void) ++{ ++ struct sunxi_cpucfg *cpucfg = (struct sunxi_cpucfg *)SUNXI_CPUCFG_BASE; ++ ++ while (1) { ++ __asm__ __volatile__("wfe" ::: "memory"); ++ ++ unsigned long boot_addr = readl(&cpucfg->boot_addr); ++ ++ __asm__ __volatile__( ++ "mov r14, %0 \n" ++ "bx r14 \n" ++ : : "r" (boot_addr) ++ ); ++ }; ++} ++ ++u32 secondary_stack[32*(NUM_CORES-1)]; ++ ++void secondary_start(void) ++{ ++ secondary_pen(); ++} ++ ++/* Power on secondaries */ ++void startup_secondaries(void) ++{ ++ int i; ++ struct sunxi_cpucfg *cpucfg = (struct sunxi_cpucfg *)SUNXI_CPUCFG_BASE; ++ ++ writel((u32)secondary_init, &cpucfg->boot_addr); ++ ++ for (i = 1; i < NUM_CORES; i++) { ++ /* Assert CPU reset just in case */ ++ writel(CPU_RESET_SET, &cpucfg->cpu[i].reset_ctrl); ++ /* Ensure CPU reset also invalidates L1 caches */ ++ clrbits_le32(&cpucfg->general_ctrl, ++ GENERAL_CTRL_NO_L1_RESET_CPU(i)); ++ /* Lock CPU */ ++ clrbits_le32(&cpucfg->debug1_ctrl, 1 << i); ++ ++ /* Ramp up power to CPU1 */ ++ assert(i == 1); ++ u32 j = 0xff << 1; ++ do { ++ j = j >> 1; ++ writel(j, &cpucfg->cpu1_power_clamp); ++ } while (j != 0); ++ ++ udelay(10*1000); /* 10ms */ ++ ++ clrbits_le32(&cpucfg->cpu1_power_off, 1); ++ /* Release CPU reset */ ++ writel(CPU_RESET_CLEAR, &cpucfg->cpu[i].reset_ctrl); ++ ++ /* Unlock CPU */ ++ setbits_le32(&cpucfg->debug1_ctrl, 1 << i); ++ ++ printf("Secondary CPU%d power-on\n", i); ++ } ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/start.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/start.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/start.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/start.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1 @@ ++/* Intentionally empty. Only needed to get FEL SPL link line right */ +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/timer.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/timer.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/timer.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/timer.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,113 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/arch/timer.h> ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++#define TIMER_MODE (0x0 << 7) /* continuous mode */ ++#define TIMER_DIV (0x0 << 4) /* pre scale 1 */ ++#define TIMER_SRC (0x1 << 2) /* osc24m */ ++#define TIMER_RELOAD (0x1 << 1) /* reload internal value */ ++#define TIMER_EN (0x1 << 0) /* enable timer */ ++ ++#define TIMER_CLOCK (24 * 1000 * 1000) ++#define COUNT_TO_USEC(x) ((x) / 24) ++#define USEC_TO_COUNT(x) ((x) * 24) ++#define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ) ++#define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ) ++ ++#define TIMER_LOAD_VAL 0xffffffff ++ ++#define TIMER_NUM 0 /* we use timer 0 */ ++ ++/* read the 32-bit timer */ ++static ulong read_timer(void) ++{ ++ struct sunxi_timer_reg *timers = ++ (struct sunxi_timer_reg *)SUNXI_TIMER_BASE; ++ struct sunxi_timer *timer = &timers->timer[TIMER_NUM]; ++ ++ /* ++ * The hardware timer counts down, therefore we invert to ++ * produce an incrementing timer. ++ */ ++ return ~readl(&timer->val); ++} ++ ++/* init timer register */ ++int timer_init(void) ++{ ++ struct sunxi_timer_reg *timers = ++ (struct sunxi_timer_reg *)SUNXI_TIMER_BASE; ++ struct sunxi_timer *timer = &timers->timer[TIMER_NUM]; ++ writel(TIMER_LOAD_VAL, &timer->inter); ++ writel(TIMER_MODE | TIMER_DIV | TIMER_SRC | TIMER_RELOAD | TIMER_EN, ++ &timer->ctl); ++ ++ return 0; ++} ++ ++/* timer without interrupts */ ++ulong get_timer(ulong base) ++{ ++ return get_timer_masked() - base; ++} ++ ++ulong get_timer_masked(void) ++{ ++ /* current tick value */ ++ ulong now = TICKS_TO_HZ(read_timer()); ++ ++ if (now >= gd->arch.lastinc) /* normal (non rollover) */ ++ gd->arch.tbl += (now - gd->arch.lastinc); ++ else { ++ /* rollover */ ++ gd->arch.tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) ++ - gd->arch.lastinc) + now; ++ } ++ gd->arch.lastinc = now; ++ ++ return gd->arch.tbl; ++} ++ ++/* delay x useconds */ ++void __udelay(unsigned long usec) ++{ ++ long tmo = USEC_TO_COUNT(usec); ++ ulong now, last = read_timer(); ++ ++ while (tmo > 0) { ++ now = read_timer(); ++ if (now > last) /* normal (non rollover) */ ++ tmo -= now - last; ++ else /* rollover */ ++ tmo -= TIMER_LOAD_VAL - last + now; ++ last = now; ++ } ++} ++ ++/* ++ * This function is derived from PowerPC code (read timebase as long long). ++ * On ARM it just returns the timer value. ++ */ ++unsigned long long get_ticks(void) ++{ ++ return get_timer(0); ++} ++ ++/* ++ * This function is derived from PowerPC code (timebase clock frequency). ++ * On ARM it returns the number of timer ticks per second. ++ */ ++ulong get_tbclk(void) ++{ ++ return CONFIG_SYS_HZ; ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,77 @@ ++/* ++ * (C) Copyright 2013 ++ * Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") ++OUTPUT_ARCH(arm) ++ENTRY(s_init) ++SECTIONS ++{ ++ . = 0x00002000; ++ ++ . = ALIGN(4); ++ .text : ++ { ++ *(.text.s_init) ++ *(.text*) ++ } ++ ++ . = ALIGN(4); ++ .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } ++ ++ . = ALIGN(4); ++ .data : { ++ *(.data*) ++ } ++ ++ . = ALIGN(4); ++ . = .; ++ ++ . = ALIGN(4); ++ .rel.dyn : { ++ __rel_dyn_start = .; ++ *(.rel*) ++ __rel_dyn_end = .; ++ } ++ ++ .dynsym : { ++ __dynsym_start = .; ++ *(.dynsym) ++ } ++ ++ . = ALIGN(4); ++ .note.gnu.build-id : ++ { ++ *(.note.gnu.build-id) ++ } ++ _end = .; ++ ++ . = ALIGN(4096); ++ .mmutable : { ++ *(.mmutable) ++ } ++ ++ .bss_start __rel_dyn_start (OVERLAY) : { ++ KEEP(*(.__bss_start)); ++ __bss_base = .; ++ } ++ ++ .bss __bss_base (OVERLAY) : { ++ *(.bss*) ++ . = ALIGN(4); ++ __bss_limit = .; ++ } ++ ++ .bss_end __bss_limit (OVERLAY) : { ++ KEEP(*(.__bss_end)); ++ } ++ ++ /DISCARD/ : { *(.dynstr*) } ++ /DISCARD/ : { *(.dynamic*) } ++ /DISCARD/ : { *(.plt*) } ++ /DISCARD/ : { *(.interp*) } ++ /DISCARD/ : { *(.gnu*) } ++ /DISCARD/ : { *(.note*) } ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,52 @@ ++/* ++ * (C) Copyright 2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Based on omap-common/u-boot-spl.lds: ++ * ++ * (C) Copyright 2002 ++ * Gary Jennejohn, DENX Software Engineering, garyj@denx.de ++ * ++ * (C) Copyright 2010 ++ * Texas Instruments, <www.ti.com> ++ * Aneesh V aneesh@ti.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\ ++ LENGTH = CONFIG_SPL_MAX_SIZE } ++MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ ++ LENGTH = CONFIG_SPL_BSS_MAX_SIZE } ++ ++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") ++OUTPUT_ARCH(arm) ++ENTRY(_start) ++SECTIONS ++{ ++ .text : ++ { ++ __start = .; ++ arch/arm/cpu/armv7/start.o (.text) ++ *(.text*) ++ } > .sram ++ ++ . = ALIGN(4); ++ .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram ++ ++ . = ALIGN(4); ++ .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram ++ ++ . = ALIGN(4); ++ __image_copy_end = .; ++ _end = .; ++ ++ .bss : ++ { ++ . = ALIGN(4); ++ __bss_start = .; ++ *(.bss*) ++ . = ALIGN(4); ++ __bss_end = .; ++ } > .sdram ++} +diff -ruN u-boot-2014.04/arch/arm/cpu/armv7/sunxi/watchdog.c u-boot-sunxi/arch/arm/cpu/armv7/sunxi/watchdog.c +--- u-boot-2014.04/arch/arm/cpu/armv7/sunxi/watchdog.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/cpu/armv7/sunxi/watchdog.c 2014-09-06 16:58:35.317953141 +0200 +@@ -0,0 +1,83 @@ ++/* ++ * Watchdog driver for the Allwinner sunxi platform. ++ * Copyright (C) 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://www.linux-sunxi.org/ ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <asm/io.h> ++#include <asm/arch/timer.h> ++#include <asm/arch/watchdog.h> ++#include <common.h> ++#include <watchdog.h> ++ ++ ++#define WDT_CTRL_RESTART (0x1 << 0) ++#define WDT_CTRL_KEY (0x0a57 << 1) ++ ++#define WDT_MODE_EN (0x1 << 0) ++#define WDT_MODE_RESET_EN (0x1 << 1) ++#define WDT_MAX_TIMEOUT 16 ++#define WDT_MODE_TIMEOUT(n) \ ++ (wdt_timeout_map[(n) < WDT_MAX_TIMEOUT ? (n) : WDT_MAX_TIMEOUT] << 3) ++ ++ ++/* ++ * Watchdog timeout table. The sunxi cores only use 4 bits for the watchdog as ++ * set by the table below. The gaps are filled by rounding up to the next ++ * second up. ++ */ ++const unsigned int wdt_timeout_map[] = { ++ [0] = 0b0000, /* 0.5s*/ ++ [1] = 0b0001, /* 1s */ ++ [2] = 0b0010, /* 2s */ ++ [3] = 0b0011, /* 3s */ ++ [4] = 0b0100, /* 4s */ ++ [5] = 0b0101, /* 5s */ ++ [6] = 0b0110, /* 6s */ ++ [7] = 0b0111, /* 8s */ ++ [8] = 0b0111, /* 8s */ ++ [9] = 0b1000, /* 10s */ ++ [10] = 0b1000, /* 10s */ ++ [11] = 0b1001, /* 12s */ ++ [12] = 0b1001, /* 12s */ ++ [13] = 0b1010, /* 14s */ ++ [14] = 0b1010, /* 14s */ ++ [15] = 0b1011, /* 16s */ ++ [16] = 0b1011, /* 16s */ ++}; ++ ++ ++void watchdog_reset(void) ++{ ++ static const struct sunxi_wdog *wdog = ++ &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog; ++ ++ writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl); ++} ++ ++void watchdog_set(int timeout) ++{ ++ static struct sunxi_wdog *const wdog = ++ &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog; ++ ++ /* Set timeout, reset & enable */ ++ if (timeout >= 0) { ++ writel(WDT_MODE_TIMEOUT(timeout) | ++ WDT_MODE_RESET_EN | WDT_MODE_EN, ++ &wdog->mode); ++ } else { ++ writel(0, &wdog->mode); ++ } ++ watchdog_reset(); ++} ++ ++void watchdog_init(void) ++{ ++#ifdef CONFIG_WATCHDOG ++ watchdog_set(WDT_MAX_TIMEOUT); ++#else ++ watchdog_set(WDT_OFF); /* no timeout */ ++#endif ++} +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,33 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_CLOCK_H ++#define _SUNXI_CLOCK_H ++ ++#include <linux/types.h> ++ ++#define CLK_GATE_OPEN 0x1 ++#define CLK_GATE_CLOSE 0x0 ++ ++/* clock control module regs definition */ ++#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I) ++#include <asm/arch/clock_sun6i.h> ++#else ++#include <asm/arch/clock_sun4i.h> ++#endif ++ ++#ifndef __ASSEMBLY__ ++int clock_init(void); ++int clock_twi_onoff(int port, int state); ++void clock_set_pll1(unsigned int hz); ++unsigned int clock_get_pll6(void); ++void clock_init_safe(void); ++void clock_init_uart(void); ++#endif ++ ++#endif /* _SUNXI_CLOCK_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock_sun4i.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock_sun4i.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock_sun4i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock_sun4i.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,256 @@ ++/* ++ * sun4i, sun5i and sun7i clock register definitions ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_CLOCK_SUN4I_H ++#define _SUNXI_CLOCK_SUN4I_H ++ ++struct sunxi_ccm_reg { ++ u32 pll1_cfg; /* 0x00 pll1 control */ ++ u32 pll1_tun; /* 0x04 pll1 tuning */ ++ u32 pll2_cfg; /* 0x08 pll2 control */ ++ u32 pll2_tun; /* 0x0c pll2 tuning */ ++ u32 pll3_cfg; /* 0x10 pll3 control */ ++ u8 res0[0x4]; ++ u32 pll4_cfg; /* 0x18 pll4 control */ ++ u8 res1[0x4]; ++ u32 pll5_cfg; /* 0x20 pll5 control */ ++ u32 pll5_tun; /* 0x24 pll5 tuning */ ++ u32 pll6_cfg; /* 0x28 pll6 control */ ++ u32 pll6_tun; /* 0x2c pll6 tuning */ ++ u32 pll7_cfg; /* 0x30 pll7 control */ ++ u32 pll1_tun2; /* 0x34 pll5 tuning2 */ ++ u8 res2[0x4]; ++ u32 pll5_tun2; /* 0x3c pll5 tuning2 */ ++ u8 res3[0xc]; ++ u32 pll_lock_dbg; /* 0x4c pll lock time debug */ ++ u32 osc24m_cfg; /* 0x50 osc24m control */ ++ u32 cpu_ahb_apb0_cfg; /* 0x54 cpu,ahb and apb0 divide ratio */ ++ u32 apb1_clk_div_cfg; /* 0x58 apb1 clock dividor */ ++ u32 axi_gate; /* 0x5c axi module clock gating */ ++ u32 ahb_gate0; /* 0x60 ahb module clock gating 0 */ ++ u32 ahb_gate1; /* 0x64 ahb module clock gating 1 */ ++ u32 apb0_gate; /* 0x68 apb0 module clock gating */ ++ u32 apb1_gate; /* 0x6c apb1 module clock gating */ ++ u8 res4[0x10]; ++ u32 nand_sclk_cfg; /* 0x80 nand sub clock control */ ++ u32 ms_sclk_cfg; /* 0x84 memory stick sub clock control */ ++ u32 sd0_clk_cfg; /* 0x88 sd0 clock control */ ++ u32 sd1_clk_cfg; /* 0x8c sd1 clock control */ ++ u32 sd2_clk_cfg; /* 0x90 sd2 clock control */ ++ u32 sd3_clk_cfg; /* 0x94 sd3 clock control */ ++ u32 ts_clk_cfg; /* 0x98 transport stream clock control */ ++ u32 ss_clk_cfg; /* 0x9c */ ++ u32 spi0_clk_cfg; /* 0xa0 */ ++ u32 spi1_clk_cfg; /* 0xa4 */ ++ u32 spi2_clk_cfg; /* 0xa8 */ ++ u32 pata_clk_cfg; /* 0xac */ ++ u32 ir0_clk_cfg; /* 0xb0 */ ++ u32 ir1_clk_cfg; /* 0xb4 */ ++ u32 iis_clk_cfg; /* 0xb8 */ ++ u32 ac97_clk_cfg; /* 0xbc */ ++ u32 spdif_clk_cfg; /* 0xc0 */ ++ u32 keypad_clk_cfg; /* 0xc4 */ ++ u32 sata_clk_cfg; /* 0xc8 */ ++ u32 usb_clk_cfg; /* 0xcc */ ++ u32 gps_clk_cfg; /* 0xd0 */ ++ u32 spi3_clk_cfg; /* 0xd4 */ ++ u8 res5[0x28]; ++ u32 dram_clk_cfg; /* 0x100 */ ++ u32 be0_clk_cfg; /* 0x104 */ ++ u32 be1_clk_cfg; /* 0x108 */ ++ u32 fe0_clk_cfg; /* 0x10c */ ++ u32 fe1_clk_cfg; /* 0x110 */ ++ u32 mp_clk_cfg; /* 0x114 */ ++ u32 lcd0_ch0_clk_cfg; /* 0x118 */ ++ u32 lcd1_ch0_clk_cfg; /* 0x11c */ ++ u32 csi_isp_clk_cfg; /* 0x120 */ ++ u8 res6[0x4]; ++ u32 tvd_clk_reg; /* 0x128 */ ++ u32 lcd0_ch1_clk_cfg; /* 0x12c */ ++ u32 lcd1_ch1_clk_cfg; /* 0x130 */ ++ u32 csi0_clk_cfg; /* 0x134 */ ++ u32 csi1_clk_cfg; /* 0x138 */ ++ u32 ve_clk_cfg; /* 0x13c */ ++ u32 audio_codec_clk_cfg; /* 0x140 */ ++ u32 avs_clk_cfg; /* 0x144 */ ++ u32 ace_clk_cfg; /* 0x148 */ ++ u32 lvds_clk_cfg; /* 0x14c */ ++ u32 hdmi_clk_cfg; /* 0x150 */ ++ u32 mali_clk_cfg; /* 0x154 */ ++ u8 res7[0x4]; ++ u32 mbus_clk_cfg; /* 0x15c */ ++ u8 res8[0x4]; ++ u32 gmac_clk_cfg; /* 0x164 */ ++}; ++ ++/* apb1 bit field */ ++#define APB1_CLK_SRC_OSC24M (0x0 << 24) ++#define APB1_CLK_SRC_PLL6 (0x1 << 24) ++#define APB1_CLK_SRC_LOSC (0x2 << 24) ++#define APB1_CLK_SRC_MASK (0x3 << 24) ++#define APB1_CLK_RATE_N_1 (0x0 << 16) ++#define APB1_CLK_RATE_N_2 (0x1 << 16) ++#define APB1_CLK_RATE_N_4 (0x2 << 16) ++#define APB1_CLK_RATE_N_8 (0x3 << 16) ++#define APB1_CLK_RATE_N_MASK (3 << 16) ++#define APB1_CLK_RATE_M(m) (((m)-1) << 0) ++#define APB1_CLK_RATE_M_MASK (0x1f << 0) ++ ++/* apb1 gate field */ ++#define APB1_GATE_UART_SHIFT (16) ++#define APB1_GATE_UART_MASK (0xff << APB1_GATE_UART_SHIFT) ++#define APB1_GATE_TWI_SHIFT (0) ++#define APB1_GATE_TWI_MASK (0xf << APB1_GATE_TWI_SHIFT) ++ ++/* clock divide */ ++#define AXI_DIV_SHIFT (0) ++#define AXI_DIV_1 0 ++#define AXI_DIV_2 1 ++#define AXI_DIV_3 2 ++#define AXI_DIV_4 3 ++#define AHB_DIV_SHIFT (4) ++#define AHB_DIV_1 0 ++#define AHB_DIV_2 1 ++#define AHB_DIV_4 2 ++#define AHB_DIV_8 3 ++#define APB0_DIV_SHIFT (8) ++#define APB0_DIV_1 0 ++#define APB0_DIV_2 1 ++#define APB0_DIV_4 2 ++#define APB0_DIV_8 3 ++#define CPU_CLK_SRC_SHIFT (16) ++#define CPU_CLK_SRC_OSC24M 1 ++#define CPU_CLK_SRC_PLL1 2 ++ ++#define CCM_PLL1_CFG_ENABLE_SHIFT 31 ++#define CCM_PLL1_CFG_VCO_RST_SHIFT 30 ++#define CCM_PLL1_CFG_VCO_BIAS_SHIFT 26 ++#define CCM_PLL1_CFG_PLL4_EXCH_SHIFT 25 ++#define CCM_PLL1_CFG_BIAS_CUR_SHIFT 20 ++#define CCM_PLL1_CFG_DIVP_SHIFT 16 ++#define CCM_PLL1_CFG_LCK_TMR_SHIFT 13 ++#define CCM_PLL1_CFG_FACTOR_N_SHIFT 8 ++#define CCM_PLL1_CFG_FACTOR_K_SHIFT 4 ++#define CCM_PLL1_CFG_SIG_DELT_PAT_IN_SHIFT 3 ++#define CCM_PLL1_CFG_SIG_DELT_PAT_EN_SHIFT 2 ++#define CCM_PLL1_CFG_FACTOR_M_SHIFT 0 ++ ++#define PLL1_CFG_DEFAULT 0xa1005000 ++ ++#define PLL6_CFG_DEFAULT 0xa1009911 ++ ++/* nand clock */ ++#define NAND_CLK_SRC_OSC24 0 ++#define NAND_CLK_DIV_N 0 ++#define NAND_CLK_DIV_M 0 ++ ++/* gps clock */ ++#define GPS_SCLK_GATING_OFF 0 ++#define GPS_RESET 0 ++ ++/* ahb clock gate bit offset */ ++#define AHB_GATE_OFFSET_GPS 26 ++#define AHB_GATE_OFFSET_SATA 25 ++#define AHB_GATE_OFFSET_PATA 24 ++#define AHB_GATE_OFFSET_SPI3 23 ++#define AHB_GATE_OFFSET_SPI2 22 ++#define AHB_GATE_OFFSET_SPI1 21 ++#define AHB_GATE_OFFSET_SPI0 20 ++#define AHB_GATE_OFFSET_TS0 18 ++#define AHB_GATE_OFFSET_EMAC 17 ++#define AHB_GATE_OFFSET_ACE 16 ++#define AHB_GATE_OFFSET_DLL 15 ++#define AHB_GATE_OFFSET_SDRAM 14 ++#define AHB_GATE_OFFSET_NAND 13 ++#define AHB_GATE_OFFSET_MS 12 ++#define AHB_GATE_OFFSET_MMC3 11 ++#define AHB_GATE_OFFSET_MMC2 10 ++#define AHB_GATE_OFFSET_MMC1 9 ++#define AHB_GATE_OFFSET_MMC0 8 ++#define AHB_GATE_OFFSET_MMC(n) (AHB_GATE_OFFSET_MMC0 + (n)) ++#define AHB_GATE_OFFSET_BIST 7 ++#define AHB_GATE_OFFSET_DMA 6 ++#define AHB_GATE_OFFSET_SS 5 ++#define AHB_GATE_OFFSET_USB_OHCI1 4 ++#define AHB_GATE_OFFSET_USB_EHCI1 3 ++#define AHB_GATE_OFFSET_USB_OHCI0 2 ++#define AHB_GATE_OFFSET_USB_EHCI0 1 ++#define AHB_GATE_OFFSET_USB 0 ++ ++/* ahb clock gate bit offset (second register) */ ++#define AHB_GATE_OFFSET_GMAC 17 ++ ++#define CCM_AHB_GATE_GPS (0x1 << 26) ++#define CCM_AHB_GATE_SDRAM (0x1 << 14) ++#define CCM_AHB_GATE_DLL (0x1 << 15) ++#define CCM_AHB_GATE_ACE (0x1 << 16) ++ ++#define CCM_PLL5_CTRL_M(n) (((n) & 0x3) << 0) ++#define CCM_PLL5_CTRL_M_MASK CCM_PLL5_CTRL_M(0x3) ++#define CCM_PLL5_CTRL_M_X(n) ((n) - 1) ++#define CCM_PLL5_CTRL_M1(n) (((n) & 0x3) << 2) ++#define CCM_PLL5_CTRL_M1_MASK CCM_PLL5_CTRL_M1(0x3) ++#define CCM_PLL5_CTRL_M1_X(n) ((n) - 1) ++#define CCM_PLL5_CTRL_K(n) (((n) & 0x3) << 4) ++#define CCM_PLL5_CTRL_K_MASK CCM_PLL5_CTRL_K(0x3) ++#define CCM_PLL5_CTRL_K_X(n) ((n) - 1) ++#define CCM_PLL5_CTRL_LDO (0x1 << 7) ++#define CCM_PLL5_CTRL_N(n) (((n) & 0x1f) << 8) ++#define CCM_PLL5_CTRL_N_MASK CCM_PLL5_CTRL_N(0x1f) ++#define CCM_PLL5_CTRL_N_X(n) (n) ++#define CCM_PLL5_CTRL_P(n) (((n) & 0x3) << 16) ++#define CCM_PLL5_CTRL_P_MASK CCM_PLL5_CTRL_P(0x3) ++#define CCM_PLL5_CTRL_P_X(n) ((n) - 1) ++#define CCM_PLL5_CTRL_BW (0x1 << 18) ++#define CCM_PLL5_CTRL_VCO_GAIN (0x1 << 19) ++#define CCM_PLL5_CTRL_BIAS(n) (((n) & 0x1f) << 20) ++#define CCM_PLL5_CTRL_BIAS_MASK CCM_PLL5_CTRL_BIAS(0x1f) ++#define CCM_PLL5_CTRL_BIAS_X(n) ((n) - 1) ++#define CCM_PLL5_CTRL_VCO_BIAS (0x1 << 25) ++#define CCM_PLL5_CTRL_DDR_CLK (0x1 << 29) ++#define CCM_PLL5_CTRL_BYPASS (0x1 << 30) ++#define CCM_PLL5_CTRL_EN (0x1 << 31) ++ ++#define CCM_PLL6_CTRL_N_SHIFT 8 ++#define CCM_PLL6_CTRL_N_MASK (0x1f << CCM_PLL6_CTRL_N_SHIFT) ++#define CCM_PLL6_CTRL_K_SHIFT 4 ++#define CCM_PLL6_CTRL_K_MASK (0x3 << CCM_PLL6_CTRL_K_SHIFT) ++ ++#define CCM_GPS_CTRL_RESET (0x1 << 0) ++#define CCM_GPS_CTRL_GATE (0x1 << 1) ++ ++#define CCM_DRAM_CTRL_DCLK_OUT (0x1 << 15) ++ ++#define CCM_MBUS_CTRL_M(n) (((n) & 0xf) << 0) ++#define CCM_MBUS_CTRL_M_MASK CCM_MBUS_CTRL_M(0xf) ++#define CCM_MBUS_CTRL_M_X(n) ((n) - 1) ++#define CCM_MBUS_CTRL_N(n) (((n) & 0xf) << 16) ++#define CCM_MBUS_CTRL_N_MASK CCM_MBUS_CTRL_N(0xf) ++#define CCM_MBUS_CTRL_N_X(n) (((n) >> 3) ? 3 : (((n) >> 2) ? 2 : (((n) >> 1) ? 1 : 0))) ++#define CCM_MBUS_CTRL_CLK_SRC(n) (((n) & 0x3) << 24) ++#define CCM_MBUS_CTRL_CLK_SRC_MASK CCM_MBUS_CTRL_CLK_SRC(0x3) ++#define CCM_MBUS_CTRL_CLK_SRC_HOSC 0x0 ++#define CCM_MBUS_CTRL_CLK_SRC_PLL6 0x1 ++#define CCM_MBUS_CTRL_CLK_SRC_PLL5 0x2 ++#define CCM_MBUS_CTRL_GATE (0x1 << 31) ++ ++#define CCM_MMC_CTRL_OSCM24 (0x0 << 24) ++#define CCM_MMC_CTRL_PLL6 (0x1 << 24) ++#define CCM_MMC_CTRL_PLL5 (0x2 << 24) ++ ++#define CCM_MMC_CTRL_ENABLE (0x1 << 31) ++ ++#define CCM_GMAC_CTRL_TX_CLK_SRC_MII 0x0 ++#define CCM_GMAC_CTRL_TX_CLK_SRC_EXT_RGMII 0x1 ++#define CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII 0x2 ++#define CCM_GMAC_CTRL_GPIT_MII (0x0 << 2) ++#define CCM_GMAC_CTRL_GPIT_RGMII (0x1 << 2) ++ ++#endif /* _SUNXI_CLOCK_SUN4I_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock_sun6i.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/clock_sun6i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/clock_sun6i.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,205 @@ ++/* ++ * sun6i clock register definitions ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_CLOCK_SUN6I_H ++#define _SUNXI_CLOCK_SUN6I_H ++ ++struct sunxi_ccm_reg { ++ u32 pll1_cfg; /* 0x00 pll1 control */ ++ u32 reserved0; ++ u32 pll2_cfg; /* 0x08 pll2 control */ ++ u32 reserved1; ++ u32 pll3_cfg; /* 0x10 pll3 control */ ++ u32 reserved2; ++ u32 pll4_cfg; /* 0x18 pll4 control */ ++ u32 reserved3; ++ u32 pll5_cfg; /* 0x20 pll5 control */ ++ u32 reserved4; ++ u32 pll6_cfg; /* 0x28 pll6 control */ ++ u32 reserved5; ++ u32 pll7_cfg; /* 0x30 pll7 control */ ++ u32 reserved6; ++ u32 pll8_cfg; /* 0x38 pll8 control */ ++ u32 reserved7; ++ u32 mipi_pll_cfg; /* 0x40 MIPI pll control */ ++ u32 pll9_cfg; /* 0x44 pll9 control */ ++ u32 pll10_cfg; /* 0x48 pll10 control */ ++ u32 reserved8; ++ u32 cpu_axi_cfg; /* 0x50 CPU/AXI divide ratio */ ++ u32 ahb1_apb1_div; /* 0x54 AHB1/APB1 divide ratio */ ++ u32 apb2_div; /* 0x58 APB2 divide ratio */ ++ u32 axi_gate; /* 0x5c axi module clock gating */ ++ u32 ahb_gate0; /* 0x60 ahb module clock gating 0 */ ++ u32 ahb_gate1; /* 0x64 ahb module clock gating 1 */ ++ u32 apb1_gate; /* 0x68 apb1 module clock gating */ ++ u32 apb2_gate; /* 0x6c apb2 module clock gating */ ++ u32 reserved9[4]; ++ u32 nand0_clk_cfg; /* 0x80 nand0 clock control */ ++ u32 nand1_clk_cfg; /* 0x84 nand1 clock control */ ++ u32 sd0_clk_cfg; /* 0x88 sd0 clock control */ ++ u32 sd1_clk_cfg; /* 0x8c sd1 clock control */ ++ u32 sd2_clk_cfg; /* 0x90 sd2 clock control */ ++ u32 sd3_clk_cfg; /* 0x94 sd3 clock control */ ++ u32 ts_clk_cfg; /* 0x98 transport stream clock control */ ++ u32 ss_clk_cfg; /* 0x9c security system clock control */ ++ u32 spi0_clk_cfg; /* 0xa0 spi0 clock control */ ++ u32 spi1_clk_cfg; /* 0xa4 spi1 clock control */ ++ u32 spi2_clk_cfg; /* 0xa8 spi2 clock control */ ++ u32 spi3_clk_cfg; /* 0xac spi3 clock control */ ++ u32 i2s0_clk_cfg; /* 0xb0 I2S0 clock control*/ ++ u32 i2s1_clk_cfg; /* 0xb4 I2S1 clock control */ ++ u32 reserved10[2]; ++ u32 spdif_clk_cfg; /* 0xc0 SPDIF clock control */ ++ u32 reserved11[2]; ++ u32 usb_clk_cfg; /* 0xcc USB clock control */ ++ u32 gmac_clk_cfg; /* 0xd0 GMAC clock control */ ++ u32 reserved12[7]; ++ u32 mdfs_clk_cfg; /* 0xf0 MDFS clock control */ ++ u32 dram_clk_cfg; /* 0xf4 DRAM configuration clock control */ ++ u32 reserved13[2]; ++ u32 dram_clk_gate; /* 0x100 DRAM module gating */ ++ u32 be0_clk_cfg; /* 0x104 BE0 module clock */ ++ u32 be1_clk_cfg; /* 0x108 BE1 module clock */ ++ u32 fe0_clk_cfg; /* 0x10c FE0 module clock */ ++ u32 fe1_clk_cfg; /* 0x110 FE1 module clock */ ++ u32 mp_clk_cfg; /* 0x114 MP module clock */ ++ u32 lcd0_ch0_clk_cfg; /* 0x118 LCD0 CH0 module clock */ ++ u32 lcd1_ch0_clk_cfg; /* 0x11c LCD1 CH0 module clock */ ++ u32 reserved14[3]; ++ u32 lcd0_ch1_clk_cfg; /* 0x12c LCD0 CH1 module clock */ ++ u32 lcd1_ch1_clk_cfg; /* 0x130 LCD1 CH1 module clock */ ++ u32 csi0_clk_cfg; /* 0x134 CSI0 module clock */ ++ u32 csi1_clk_cfg; /* 0x138 CSI1 module clock */ ++ u32 ve_clk_cfg; /* 0x13c VE module clock */ ++ u32 adda_clk_cfg; /* 0x140 ADDA module clock */ ++ u32 avs_clk_cfg; /* 0x144 AVS module clock */ ++ u32 dmic_clk_cfg; /* 0x148 Digital Mic module clock*/ ++ u32 reserved15; ++ u32 hdmi_clk_cfg; /* 0x150 HDMI module clock */ ++ u32 ps_clk_cfg; /* 0x154 PS module clock */ ++ u32 mtc_clk_cfg; /* 0x158 MTC module clock */ ++ u32 mbus0_clk_cfg; /* 0x15c MBUS0 module clock */ ++ u32 mbus1_clk_cfg; /* 0x160 MBUS1 module clock */ ++ u32 reserved16; ++ u32 mipi_dsi_clk_cfg; /* 0x168 MIPI DSI clock control */ ++ u32 mipi_csi_clk_cfg; /* 0x16c MIPI CSI clock control */ ++ u32 reserved17[4]; ++ u32 iep_drc0_clk_cfg; /* 0x180 IEP DRC0 module clock */ ++ u32 iep_drc1_clk_cfg; /* 0x184 IEP DRC1 module clock */ ++ u32 iep_deu0_clk_cfg; /* 0x188 IEP DEU0 module clock */ ++ u32 iep_deu1_clk_cfg; /* 0x18c IEP DEU1 module clock */ ++ u32 reserved18[4]; ++ u32 gpu_core_clk_cfg; /* 0x1a0 GPU core clock config */ ++ u32 gpu_mem_clk_cfg; /* 0x1a4 GPU memory clock config */ ++ u32 gpu_hyd_clk_cfg; /* 0x1a0 GPU HYD clock config */ ++ u32 reserved19[21]; ++ u32 pll_lock; /* 0x200 PLL Lock Time */ ++ u32 pll1_lock; /* 0x204 PLL1 Lock Time */ ++ u32 reserved20[6]; ++ u32 pll1_bias_cfg; /* 0x220 PLL1 Bias config */ ++ u32 pll2_bias_cfg; /* 0x224 PLL2 Bias config */ ++ u32 pll3_bias_cfg; /* 0x228 PLL3 Bias config */ ++ u32 pll4_bias_cfg; /* 0x22c PLL4 Bias config */ ++ u32 pll5_bias_cfg; /* 0x230 PLL5 Bias config */ ++ u32 pll6_bias_cfg; /* 0x234 PLL6 Bias config */ ++ u32 pll7_bias_cfg; /* 0x238 PLL7 Bias config */ ++ u32 pll8_bias_cfg; /* 0x23c PLL8 Bias config */ ++ u32 mipi_bias_cfg; /* 0x240 MIPI Bias config */ ++ u32 pll9_bias_cfg; /* 0x244 PLL9 Bias config */ ++ u32 pll10_bias_cfg; /* 0x248 PLL10 Bias config */ ++ u32 reserved21[13]; ++ u32 pll1_pattern_cfg; /* 0x280 PLL1 Pattern config */ ++ u32 pll2_pattern_cfg; /* 0x284 PLL2 Pattern config */ ++ u32 pll3_pattern_cfg; /* 0x288 PLL3 Pattern config */ ++ u32 pll4_pattern_cfg; /* 0x28c PLL4 Pattern config */ ++ u32 pll5_pattern_cfg; /* 0x290 PLL5 Pattern config */ ++ u32 pll6_pattern_cfg; /* 0x294 PLL6 Pattern config */ ++ u32 pll7_pattern_cfg; /* 0x298 PLL7 Pattern config */ ++ u32 pll8_pattern_cfg; /* 0x29c PLL8 Pattern config */ ++ u32 mipi_pattern_cfg; /* 0x2a0 MIPI Pattern config */ ++ u32 pll9_pattern_cfg; /* 0x2a4 PLL9 Pattern config */ ++ u32 pll10_pattern_cfg; /* 0x2a8 PLL10 Pattern config */ ++ u32 reserved22[5]; ++ u32 ahb_reset0_cfg; /* 0x2c0 AHB1 Reset 0 config */ ++ u32 ahb_reset1_cfg; /* 0x2c4 AHB1 Reset 1 config */ ++ u32 ahb_reset2_cfg; /* 0x2c8 AHB1 Reset 2 config */ ++ u32 reserved23; ++ u32 apb1_reset_cfg; /* 0x2d0 APB1 Reset config */ ++ u32 reserved24; ++ u32 apb2_reset_cfg; /* 0x2d8 APB2 Reset config */ ++}; ++ ++/* apb2 bit field */ ++#define APB2_CLK_SRC_LOSC (0x0 << 24) ++#define APB2_CLK_SRC_OSC24M (0x1 << 24) ++#define APB2_CLK_SRC_PLL6 (0x2 << 24) ++#define APB2_CLK_SRC_MASK (0x3 << 24) ++#define APB2_CLK_RATE_N_1 (0x0 << 16) ++#define APB2_CLK_RATE_N_2 (0x1 << 16) ++#define APB2_CLK_RATE_N_4 (0x2 << 16) ++#define APB2_CLK_RATE_N_8 (0x3 << 16) ++#define APB2_CLK_RATE_N_MASK (3 << 16) ++#define APB2_CLK_RATE_M(m) (((m)-1) << 0) ++#define APB2_CLK_RATE_M_MASK (0x1f << 0) ++ ++/* apb2 gate field */ ++#define APB2_GATE_UART_SHIFT (16) ++#define APB2_GATE_UART_MASK (0xff << APB2_GATE_UART_SHIFT) ++#define APB2_GATE_TWI_SHIFT (0) ++#define APB2_GATE_TWI_MASK (0xf << APB2_GATE_TWI_SHIFT) ++ ++/* cpu_axi_cfg bits */ ++#define AXI_DIV_SHIFT 0 ++#define ATB_DIV_SHIFT 8 ++#define CPU_CLK_SRC_SHIFT 16 ++ ++#define AXI_DIV_1 0 ++#define AXI_DIV_2 1 ++#define AXI_DIV_3 2 ++#define AXI_DIV_4 3 ++#define ATB_DIV_1 0 ++#define ATB_DIV_2 1 ++#define ATB_DIV_4 2 ++#define CPU_CLK_SRC_OSC24M 1 ++#define CPU_CLK_SRC_PLL1 2 ++ ++#define PLL1_CFG_DEFAULT 0x90011b21 ++ ++#define PLL6_CFG_DEFAULT 0x90041811 ++ ++#define CCM_PLL6_CTRL_N_SHIFT 8 ++#define CCM_PLL6_CTRL_N_MASK (0x1f << CCM_PLL6_CTRL_N_SHIFT) ++#define CCM_PLL6_CTRL_K_SHIFT 4 ++#define CCM_PLL6_CTRL_K_MASK (0x3 << CCM_PLL6_CTRL_K_SHIFT) ++ ++#define AHB_GATE_OFFSET_MMC3 11 ++#define AHB_GATE_OFFSET_MMC2 10 ++#define AHB_GATE_OFFSET_MMC1 9 ++#define AHB_GATE_OFFSET_MMC0 8 ++#define AHB_GATE_OFFSET_MMC(n) (AHB_GATE_OFFSET_MMC0 + (n)) ++ ++#define CCM_MMC_CTRL_OSCM24 (0x0 << 24) ++#define CCM_MMC_CTRL_PLL6 (0x1 << 24) ++ ++#define CCM_MMC_CTRL_ENABLE (0x1 << 31) ++ ++#define AHB_RESET_OFFSET_MMC3 11 ++#define AHB_RESET_OFFSET_MMC2 10 ++#define AHB_RESET_OFFSET_MMC1 9 ++#define AHB_RESET_OFFSET_MMC0 8 ++#define AHB_RESET_OFFSET_MMC(n) (AHB_RESET_OFFSET_MMC0 + (n)) ++ ++/* apb2 reset */ ++#define APB2_RESET_UART_SHIFT (16) ++#define APB2_RESET_UART_MASK (0xff << APB2_RESET_UART_SHIFT) ++#define APB2_RESET_TWI_SHIFT (0) ++#define APB2_RESET_TWI_MASK (0xf << APB2_RESET_TWI_SHIFT) ++ ++#endif /* _SUNXI_CLOCK_SUN6I_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/cpucfg.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpucfg.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/cpucfg.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpucfg.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,55 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik carl@ok-labs.com ++ * ++ * CPU configuration registers for the sun7i (A20). ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_CPUCFG_H_ ++#define _SUNXI_CPUCFG_H_ ++ ++#ifndef __ASSEMBLY__ ++ ++struct sunxi_cpu_ctrl { ++ u32 reset_ctrl; ++ u32 cpu_ctrl; ++ u32 status; ++ u32 _res[13]; ++}; ++ ++#define CPU_RESET_SET 0 ++#define CPU_RESET_CLEAR 3 ++ ++#define CPU_STATUS_SMP (1 << 0) ++#define CPU_STATUS_WFE (1 << 1) ++#define CPU_STATUS_WFI (1 << 2) ++ ++struct sunxi_cpucfg { ++ u32 _res1[16]; /* 0x000 */ ++ struct sunxi_cpu_ctrl cpu[2]; /* 0x040 */ ++ u32 _res2[48]; /* 0x0c0 */ ++ u32 _res3; /* 0x180 */ ++ u32 general_ctrl; /* 0x184 */ ++ u32 _res4[2]; /* 0x188 */ ++ u32 event_input; /* 0x190 */ ++ u32 _res5[4]; /* 0x194 */ ++ u32 boot_addr; /* 0x1a4 - also known as PRIVATE_REG */ ++ u32 _res6[2]; /* 0x1a8 */ ++ u32 cpu1_power_clamp; /* 0x1b0 */ ++ u32 cpu1_power_off; /* 0x1b4 */ ++ u32 _res7[10]; /* 0x1b8 */ ++ u32 debug0_ctrl; /* 0x1e0 */ ++ u32 debug1_ctrl; /* 0x1e4 */ ++}; ++ ++#define GENERAL_CTRL_NO_L1_RESET_CPU(x) (1UL << (x)) ++#define GENERAL_CTRL_NO_L2_AUTO_RESET (1UL << 4) ++#define GENERAL_CTRL_L2_RESET_SET (0UL << 5) ++#define GENERAL_CTRL_L2_RESET_CLEAR (1UL << 5) ++#define GENERAL_CTRL_CFGSDISABLE (1UL << 8) ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _SUNXI_CPUCFG_H_ */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/cpu.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpu.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/cpu.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/cpu.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,141 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_CPU_H ++#define _SUNXI_CPU_H ++ ++#define SUNXI_SRAM_A1_BASE 0x00000000 ++#define SUNXI_SRAM_A1_SIZE (16 * 1024) /* 16 kiB */ ++ ++#define SUNXI_SRAM_A2_BASE 0x00004000 /* 16 kiB */ ++#define SUNXI_SRAM_A3_BASE 0x00008000 /* 13 kiB */ ++#define SUNXI_SRAM_A4_BASE 0x0000b400 /* 3 kiB */ ++#define SUNXI_SRAM_D_BASE 0x00010000 /* 4 kiB */ ++#define SUNXI_SRAM_B_BASE 0x00020000 /* 64 kiB (secure) */ ++ ++#define SUNXI_SRAMC_BASE 0x01c00000 ++#define SUNXI_DRAMC_BASE 0x01c01000 ++#define SUNXI_DMA_BASE 0x01c02000 ++#define SUNXI_NFC_BASE 0x01c03000 ++#define SUNXI_TS_BASE 0x01c04000 ++#define SUNXI_SPI0_BASE 0x01c05000 ++#define SUNXI_SPI1_BASE 0x01c06000 ++#define SUNXI_MS_BASE 0x01c07000 ++#define SUNXI_TVD_BASE 0x01c08000 ++#define SUNXI_CSI0_BASE 0x01c09000 ++#define SUNXI_TVE0_BASE 0x01c0a000 ++#define SUNXI_EMAC_BASE 0x01c0b000 ++#define SUNXI_LCD0_BASE 0x01c0C000 ++#define SUNXI_LCD1_BASE 0x01c0d000 ++#define SUNXI_VE_BASE 0x01c0e000 ++#define SUNXI_MMC0_BASE 0x01c0f000 ++#define SUNXI_MMC1_BASE 0x01c10000 ++#define SUNXI_MMC2_BASE 0x01c11000 ++#define SUNXI_MMC3_BASE 0x01c12000 ++#define SUNXI_USB0_BASE 0x01c13000 ++#define SUNXI_USB1_BASE 0x01c14000 ++#define SUNXI_SS_BASE 0x01c15000 ++#define SUNXI_HDMI_BASE 0x01c16000 ++#define SUNXI_SPI2_BASE 0x01c17000 ++#define SUNXI_SATA_BASE 0x01c18000 ++#define SUNXI_PATA_BASE 0x01c19000 ++#define SUNXI_ACE_BASE 0x01c1a000 ++#define SUNXI_TVE1_BASE 0x01c1b000 ++#define SUNXI_USB2_BASE 0x01c1c000 ++#define SUNXI_CSI1_BASE 0x01c1d000 ++#define SUNXI_TZASC_BASE 0x01c1e000 ++#define SUNXI_SPI3_BASE 0x01c1f000 ++ ++#define SUNXI_CCM_BASE 0x01c20000 ++#define SUNXI_INTC_BASE 0x01c20400 ++#define SUNXI_PIO_BASE 0x01c20800 ++#define SUNXI_TIMER_BASE 0x01c20c00 ++#define SUNXI_SPDIF_BASE 0x01c21000 ++#define SUNXI_AC97_BASE 0x01c21400 ++#define SUNXI_IR0_BASE 0x01c21800 ++#define SUNXI_IR1_BASE 0x01c21c00 ++ ++#define SUNXI_IIS_BASE 0x01c22400 ++#define SUNXI_LRADC_BASE 0x01c22800 ++#define SUNXI_AD_DA_BASE 0x01c22c00 ++#define SUNXI_KEYPAD_BASE 0x01c23000 ++#define SUNXI_TZPC_BASE 0x01c23400 ++#define SUNXI_SID_BASE 0x01c23800 ++#define SUNXI_SJTAG_BASE 0x01c23c00 ++ ++#define SUNXI_TP_BASE 0x01c25000 ++#define SUNXI_PMU_BASE 0x01c25400 ++#define SUNXI_CPUCFG_BASE 0x01c25c00 /* sun7i only ? */ ++ ++#define SUNXI_UART0_BASE 0x01c28000 ++#define SUNXI_UART1_BASE 0x01c28400 ++#define SUNXI_UART2_BASE 0x01c28800 ++#define SUNXI_UART3_BASE 0x01c28c00 ++#define SUNXI_UART4_BASE 0x01c29000 ++#define SUNXI_UART5_BASE 0x01c29400 ++#define SUNXI_UART6_BASE 0x01c29800 ++#define SUNXI_UART7_BASE 0x01c29c00 ++#define SUNXI_PS2_0_BASE 0x01c2a000 ++#define SUNXI_PS2_1_BASE 0x01c2a400 ++ ++#define SUNXI_TWI0_BASE 0x01c2ac00 ++#define SUNXI_TWI1_BASE 0x01c2b000 ++#define SUNXI_TWI2_BASE 0x01c2b400 ++ ++#define SUNXI_CAN_BASE 0x01c2bc00 ++ ++#define SUNXI_SCR_BASE 0x01c2c400 ++ ++#define SUNXI_GPS_BASE 0x01c30000 ++#define SUNXI_MALI400_BASE 0x01c40000 ++#define SUNXI_GMAC_BASE 0x01c50000 ++ ++#define SUNXI_DRAM_COM_BASE 0x01c62000 ++#define SUNXI_DRAM_CTL_BASE 0x01c63000 ++#define SUNXI_DRAM_PHY_CH1_BASE 0x01c65000 ++#define SUNXI_DRAM_PHY_CH2_BASE 0x01c66000 ++ ++/* module sram */ ++#define SUNXI_SRAM_C_BASE 0x01d00000 ++ ++#define SUNXI_DE_FE0_BASE 0x01e00000 ++#define SUNXI_DE_FE1_BASE 0x01e20000 ++#define SUNXI_DE_BE0_BASE 0x01e60000 ++#define SUNXI_DE_BE1_BASE 0x01e40000 ++#define SUNXI_MP_BASE 0x01e80000 ++#define SUNXI_AVG_BASE 0x01ea0000 ++ ++#define SUNXI_PRCM_BASE 0x01f01400 ++#define SUNXI_R_UART_BASE 0x01f02800 ++#define SUNXI_R_PIO_BASE 0x01f02c00 ++#define SUNXI_P2WI_BASE 0x01f03400 ++ ++/* CoreSight Debug Module */ ++#define SUNXI_CSDM_BASE 0x3f500000 ++ ++#define SUNXI_DDRII_DDRIII_BASE 0x40000000 /* 2 GiB */ ++ ++#define SUNXI_BROM_BASE 0xffff0000 /* 32 kiB */ ++ ++#define SUNXI_CPU_CFG (SUNXI_TIMER_BASE + 0x13c) ++ ++#ifndef __ASSEMBLY__ ++/* boot type */ ++enum sunxi_boot_type_t { ++ SUNXI_BOOT_TYPE_NULL, ++ SUNXI_BOOT_TYPE_MMC0, ++ SUNXI_BOOT_TYPE_NAND, ++ SUNXI_BOOT_TYPE_MMC2, ++ SUNXI_BOOT_TYPE_SPI ++}; ++ ++void sunxi_board_init(void); ++void sunxi_reset(void); ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _CPU_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/dram.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/dram.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/dram.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/dram.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,179 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Sunxi platform dram register definition. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_DRAM_H ++#define _SUNXI_DRAM_H ++ ++#include <linux/types.h> ++ ++struct sunxi_dram_reg { ++ u32 ccr; /* 0x00 controller configuration register */ ++ u32 dcr; /* 0x04 dram configuration register */ ++ u32 iocr; /* 0x08 i/o configuration register */ ++ u32 csr; /* 0x0c controller status register */ ++ u32 drr; /* 0x10 dram refresh register */ ++ u32 tpr0; /* 0x14 dram timing parameters register 0 */ ++ u32 tpr1; /* 0x18 dram timing parameters register 1 */ ++ u32 tpr2; /* 0x1c dram timing parameters register 2 */ ++ u32 gdllcr; /* 0x20 global dll control register */ ++ u8 res0[0x28]; ++ u32 rslr0; /* 0x4c rank system latency register */ ++ u32 rslr1; /* 0x50 rank system latency register */ ++ u8 res1[0x8]; ++ u32 rdgr0; /* 0x5c rank dqs gating register */ ++ u32 rdgr1; /* 0x60 rank dqs gating register */ ++ u8 res2[0x34]; ++ u32 odtcr; /* 0x98 odt configuration register */ ++ u32 dtr0; /* 0x9c data training register 0 */ ++ u32 dtr1; /* 0xa0 data training register 1 */ ++ u32 dtar; /* 0xa4 data training address register */ ++ u32 zqcr0; /* 0xa8 zq control register 0 */ ++ u32 zqcr1; /* 0xac zq control register 1 */ ++ u32 zqsr; /* 0xb0 zq status register */ ++ u32 idcr; /* 0xb4 initializaton delay configure reg */ ++ u8 res3[0x138]; ++ u32 mr; /* 0x1f0 mode register */ ++ u32 emr; /* 0x1f4 extended mode register */ ++ u32 emr2; /* 0x1f8 extended mode register */ ++ u32 emr3; /* 0x1fc extended mode register */ ++ u32 dllctr; /* 0x200 dll control register */ ++ u32 dllcr[5]; /* 0x204 dll control register 0(byte 0) */ ++ /* 0x208 dll control register 1(byte 1) */ ++ /* 0x20c dll control register 2(byte 2) */ ++ /* 0x210 dll control register 3(byte 3) */ ++ /* 0x214 dll control register 4(byte 4) */ ++ u32 dqtr0; /* 0x218 dq timing register */ ++ u32 dqtr1; /* 0x21c dq timing register */ ++ u32 dqtr2; /* 0x220 dq timing register */ ++ u32 dqtr3; /* 0x224 dq timing register */ ++ u32 dqstr; /* 0x228 dqs timing register */ ++ u32 dqsbtr; /* 0x22c dqsb timing register */ ++ u32 mcr; /* 0x230 mode configure register */ ++ u8 res[0x8]; ++ u32 ppwrsctl; /* 0x23c pad power save control */ ++ u32 apr; /* 0x240 arbiter period register */ ++ u32 pldtr; /* 0x244 priority level data threshold reg */ ++ u8 res5[0x8]; ++ u32 hpcr[32]; /* 0x250 host port configure register */ ++ u8 res6[0x10]; ++ u32 csel; /* 0x2e0 controller select register */ ++}; ++ ++struct dram_para { ++ u32 clock; ++ u32 type; ++ u32 rank_num; ++ u32 density; ++ u32 io_width; ++ u32 bus_width; ++ u32 cas; ++ u32 zq; ++ u32 odt_en; ++ u32 size; ++ u32 tpr0; ++ u32 tpr1; ++ u32 tpr2; ++ u32 tpr3; ++ u32 tpr4; ++ u32 tpr5; ++ u32 emr1; ++ u32 emr2; ++ u32 emr3; ++}; ++ ++#define DRAM_CCR_COMMAND_RATE_1T (0x1 << 5) ++#define DRAM_CCR_DQS_GATE (0x1 << 14) ++#define DRAM_CCR_DQS_DRIFT_COMP (0x1 << 17) ++#define DRAM_CCR_ITM_OFF (0x1 << 28) ++#define DRAM_CCR_DATA_TRAINING (0x1 << 30) ++#define DRAM_CCR_INIT (0x1 << 31) ++ ++#define DRAM_MEMORY_TYPE_DDR1 1 ++#define DRAM_MEMORY_TYPE_DDR2 2 ++#define DRAM_MEMORY_TYPE_DDR3 3 ++#define DRAM_MEMORY_TYPE_LPDDR2 4 ++#define DRAM_MEMORY_TYPE_LPDDR 5 ++#define DRAM_DCR_TYPE (0x1 << 0) ++#define DRAM_DCR_TYPE_DDR2 0x0 ++#define DRAM_DCR_TYPE_DDR3 0x1 ++#define DRAM_DCR_IO_WIDTH(n) (((n) & 0x3) << 1) ++#define DRAM_DCR_IO_WIDTH_MASK DRAM_DCR_IO_WIDTH(0x3) ++#define DRAM_DCR_IO_WIDTH_8BIT 0x0 ++#define DRAM_DCR_IO_WIDTH_16BIT 0x1 ++#define DRAM_DCR_CHIP_DENSITY(n) (((n) & 0x7) << 3) ++#define DRAM_DCR_CHIP_DENSITY_MASK DRAM_DCR_CHIP_DENSITY(0x7) ++#define DRAM_DCR_CHIP_DENSITY_256M 0x0 ++#define DRAM_DCR_CHIP_DENSITY_512M 0x1 ++#define DRAM_DCR_CHIP_DENSITY_1024M 0x2 ++#define DRAM_DCR_CHIP_DENSITY_2048M 0x3 ++#define DRAM_DCR_CHIP_DENSITY_4096M 0x4 ++#define DRAM_DCR_CHIP_DENSITY_8192M 0x5 ++#define DRAM_DCR_BUS_WIDTH(n) (((n) & 0x7) << 6) ++#define DRAM_DCR_BUS_WIDTH_MASK DRAM_DCR_BUS_WIDTH(0x7) ++#define DRAM_DCR_BUS_WIDTH_32BIT 0x3 ++#define DRAM_DCR_BUS_WIDTH_16BIT 0x1 ++#define DRAM_DCR_BUS_WIDTH_8BIT 0x0 ++#define DRAM_DCR_NR_DLLCR_32BIT 5 ++#define DRAM_DCR_NR_DLLCR_16BIT 3 ++#define DRAM_DCR_NR_DLLCR_8BIT 2 ++#define DRAM_DCR_RANK_SEL(n) (((n) & 0x3) << 10) ++#define DRAM_DCR_RANK_SEL_MASK DRAM_DCR_CMD_RANK(0x3) ++#define DRAM_DCR_CMD_RANK_ALL (0x1 << 12) ++#define DRAM_DCR_MODE(n) (((n) & 0x3) << 13) ++#define DRAM_DCR_MODE_MASK DRAM_DCR_MODE(0x3) ++#define DRAM_DCR_MODE_SEQ 0x0 ++#define DRAM_DCR_MODE_INTERLEAVE 0x1 ++ ++#define DRAM_CSR_FAILED (0x1 << 20) ++ ++#define DRAM_DRR_TRFC(n) ((n) & 0xff) ++#define DRAM_DRR_TREFI(n) (((n) & 0xffff) << 8) ++#define DRAM_DRR_BURST(n) ((((n) - 1) & 0xf) << 24) ++ ++#define DRAM_MCR_MODE_NORM(n) (((n) & 0x3) << 0) ++#define DRAM_MCR_MODE_NORM_MASK DRAM_MCR_MOD_NORM(0x3) ++#define DRAM_MCR_MODE_DQ_OUT(n) (((n) & 0x3) << 2) ++#define DRAM_MCR_MODE_DQ_OUT_MASK DRAM_MCR_MODE_DQ_OUT(0x3) ++#define DRAM_MCR_MODE_ADDR_OUT(n) (((n) & 0x3) << 4) ++#define DRAM_MCR_MODE_ADDR_OUT_MASK DRAM_MCR_MODE_ADDR_OUT(0x3) ++#define DRAM_MCR_MODE_DQ_IN_OUT(n) (((n) & 0x3) << 6) ++#define DRAM_MCR_MODE_DQ_IN_OUT_MASK DRAM_MCR_MODE_DQ_IN_OUT(0x3) ++#define DRAM_MCR_MODE_DQ_TURNON_DELAY(n) (((n) & 0x7) << 8) ++#define DRAM_MCR_MODE_DQ_TURNON_DELAY_MASK DRAM_MCR_MODE_DQ_TURNON_DELAY(0x7) ++#define DRAM_MCR_MODE_ADDR_IN (0x1 << 11) ++#define DRAM_MCR_RESET (0x1 << 12) ++#define DRAM_MCR_MODE_EN(n) (((n) & 0x3) << 13) ++#define DRAM_MCR_MODE_EN_MASK DRAM_MCR_MOD_EN(0x3) ++#define DRAM_MCR_DCLK_OUT (0x1 << 16) ++ ++#define DRAM_DLLCR_NRESET (0x1 << 30) ++#define DRAM_DLLCR_DISABLE (0x1 << 31) ++ ++#define DRAM_ZQCR0_IMP_DIV(n) (((n) & 0xff) << 20) ++#define DRAM_ZQCR0_IMP_DIV_MASK DRAM_ZQCR0_IMP_DIV(0xff) ++ ++#define DRAM_IOCR_ODT_EN(n) ((((n) & 0x3) << 30) | ((n) & 0x3) << 0) ++#define DRAM_IOCR_ODT_EN_MASK DRAM_IOCR_ODT_EN(0x3) ++ ++#define DRAM_MR_BURST_LENGTH(n) (((n) & 0x7) << 0) ++#define DRAM_MR_BURST_LENGTH_MASK DRAM_MR_BURST_LENGTH(0x7) ++#define DRAM_MR_CAS_LAT(n) (((n) & 0x7) << 4) ++#define DRAM_MR_CAS_LAT_MASK DRAM_MR_CAS_LAT(0x7) ++#define DRAM_MR_WRITE_RECOVERY(n) (((n) & 0x7) << 9) ++#define DRAM_MR_WRITE_RECOVERY_MASK DRAM_MR_WRITE_RECOVERY(0x7) ++#define DRAM_MR_POWER_DOWN (0x1 << 12) ++ ++#define DRAM_CSEL_MAGIC 0x16237495 ++ ++unsigned long sunxi_dram_init(void); ++unsigned long dramc_init(struct dram_para *para); ++ ++#endif /* _SUNXI_DRAM_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/early_print.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/early_print.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/early_print.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/early_print.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,58 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Early uart print for debugging. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_EARLY_PRINT_H ++#define _SUNXI_EARLY_PRINT_H ++ ++#include <asm/arch/cpu.h> ++ ++#define SUNXI_UART_BASE SUNXI_UART0_BASE ++ ++#define UART_OFFSET 0x400 ++ ++/* receive buffer register */ ++#define UART_RBR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x0) ++/* transmit holding register */ ++#define UART_THR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x0) ++/* divisor latch low register */ ++#define UART_DLL(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x0) ++ ++/* divisor latch high register */ ++#define UART_DLH(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x4) ++/* interrupt enable reigster */ ++#define UART_IER(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x4) ++ ++/* interrupt identity register */ ++#define UART_IIR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x8) ++/* fifo control register */ ++#define UART_FCR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x8) ++ ++/* line control register */ ++#define UART_LCR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0xc) ++#define UART_LCR_DLAB (0x1 << 7) ++ ++/* line status register */ ++#define UART_LSR(n) (SUNXI_UART_BASE + (n) * UART_OFFSET + 0x14) ++#define UART_LSR_TEMT (0x1 << 6) ++ ++ ++#define BAUD_115200 (0xd) /* 24 * 1000 * 1000 / 16 / 115200 = 13 */ ++#define NO_PARITY (0) ++#define ONE_STOP_BIT (0) ++#define DAT_LEN_8_BITS (3) ++#define LC_8_N_1 (NO_PARITY << 3 | ONE_STOP_BIT << 2 | DAT_LEN_8_BITS) ++ ++#ifndef __ASSEMBLY__ ++void uart_init(void); ++void uart_putc(char c); ++void uart_puts(const char *s); ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _SUNXI_EARLY_PRINT_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/gpio.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/gpio.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/gpio.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/gpio.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,174 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_GPIO_H ++#define _SUNXI_GPIO_H ++ ++#include <linux/types.h> ++#include <asm/arch/cpu.h> ++ ++/* ++ * sunxi has 9 banks of gpio, they are: ++ * PA0 - PA17 | PB0 - PB23 | PC0 - PC24 ++ * PD0 - PD27 | PE0 - PE31 | PF0 - PF5 ++ * PG0 - PG9 | PH0 - PH27 | PI0 - PI12 ++ */ ++ ++#define SUNXI_GPIO_A 0 ++#define SUNXI_GPIO_B 1 ++#define SUNXI_GPIO_C 2 ++#define SUNXI_GPIO_D 3 ++#define SUNXI_GPIO_E 4 ++#define SUNXI_GPIO_F 5 ++#define SUNXI_GPIO_G 6 ++#define SUNXI_GPIO_H 7 ++#define SUNXI_GPIO_I 8 ++#define SUNXI_GPIO_BANKS 9 ++ ++/* ++ * sun6i has atleast 1 additional bank, note banks J K don't exist! ++ * PL0 - PL1 at the very least is known. ++ * ++ * Note this bank is at a different register offset! ++ */ ++#define SUNXI_GPIO_L 9 ++ ++struct sunxi_gpio { ++ u32 cfg[4]; ++ u32 dat; ++ u32 drv[2]; ++ u32 pull[2]; ++}; ++ ++/* gpio interrupt control */ ++struct sunxi_gpio_int { ++ u32 cfg[3]; ++ u32 ctl; ++ u32 sta; ++ u32 deb; /* interrupt debounce */ ++}; ++ ++struct sunxi_gpio_reg { ++ struct sunxi_gpio gpio_bank[SUNXI_GPIO_BANKS]; ++ u8 res[0xbc]; ++ struct sunxi_gpio_int gpio_int; ++}; ++ ++#define BANK_TO_GPIO(bank) (((bank) < SUNXI_GPIO_BANKS) ? \ ++ &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank] : \ ++ (struct sunxi_gpio *)SUNXI_R_PIO_BASE) ++ ++#define GPIO_BANK(pin) ((pin) >> 5) ++#define GPIO_NUM(pin) ((pin) & 0x1f) ++ ++#define GPIO_CFG_INDEX(pin) (((pin) & 0x1f) >> 3) ++#define GPIO_CFG_OFFSET(pin) ((((pin) & 0x1f) & 0x7) << 2) ++ ++#define GPIO_DRV_INDEX(pin) (((pin) & 0x1f) >> 4) ++#define GPIO_DRV_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1) ++ ++#define GPIO_PULL_INDEX(pin) (((pin) & 0x1f) >> 4) ++#define GPIO_PULL_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1) ++ ++/* GPIO bank sizes */ ++#define SUNXI_GPIO_A_NR 32 ++#define SUNXI_GPIO_B_NR 32 ++#define SUNXI_GPIO_C_NR 32 ++#define SUNXI_GPIO_D_NR 32 ++#define SUNXI_GPIO_E_NR 32 ++#define SUNXI_GPIO_F_NR 32 ++#define SUNXI_GPIO_G_NR 32 ++#define SUNXI_GPIO_H_NR 32 ++#define SUNXI_GPIO_I_NR 32 ++#define SUNXI_GPIO_L_NR 32 ++ ++#define SUNXI_GPIO_NEXT(__gpio) \ ++ ((__gpio##_START) + (__gpio##_NR) + 0) ++ ++enum sunxi_gpio_number { ++ SUNXI_GPIO_A_START = 0, ++ SUNXI_GPIO_B_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_A), ++ SUNXI_GPIO_C_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_B), ++ SUNXI_GPIO_D_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_C), ++ SUNXI_GPIO_E_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_D), ++ SUNXI_GPIO_F_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_E), ++ SUNXI_GPIO_G_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_F), ++ SUNXI_GPIO_H_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_G), ++ SUNXI_GPIO_I_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_H), ++ SUNXI_GPIO_L_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_I), ++}; ++ ++/* SUNXI GPIO number definitions */ ++#define SUNXI_GPA(_nr) (SUNXI_GPIO_A_START + (_nr)) ++#define SUNXI_GPB(_nr) (SUNXI_GPIO_B_START + (_nr)) ++#define SUNXI_GPC(_nr) (SUNXI_GPIO_C_START + (_nr)) ++#define SUNXI_GPD(_nr) (SUNXI_GPIO_D_START + (_nr)) ++#define SUNXI_GPE(_nr) (SUNXI_GPIO_E_START + (_nr)) ++#define SUNXI_GPF(_nr) (SUNXI_GPIO_F_START + (_nr)) ++#define SUNXI_GPG(_nr) (SUNXI_GPIO_G_START + (_nr)) ++#define SUNXI_GPH(_nr) (SUNXI_GPIO_H_START + (_nr)) ++#define SUNXI_GPI(_nr) (SUNXI_GPIO_I_START + (_nr)) ++#define SUNXI_GPL(_nr) (SUNXI_GPIO_L_START + (_nr)) ++ ++/* GPIO pin function config */ ++#define SUNXI_GPIO_INPUT 0 ++#define SUNXI_GPIO_OUTPUT 1 ++ ++#define SUNXI_GPA0_EMAC 2 ++#define SUN7I_GPA0_GMAC 5 ++ ++#define SUNXI_GPB0_TWI0 2 ++ ++#define SUN4I_GPB22_UART0_TX 2 ++#define SUN4I_GPB23_UART0_RX 2 ++ ++#define SUN5I_GPB19_UART0_TX 2 ++#define SUN5I_GPB20_UART0_RX 2 ++ ++#define SUN5I_GPG3_UART1_TX 4 ++#define SUN5I_GPG4_UART1_RX 4 ++ ++#define SUNXI_GPC6_SDC2 3 ++ ++#define SUNXI_GPF0_SDC0 2 ++ ++#define SUNXI_GPF2_SDC0 2 ++ ++#ifdef CONFIG_SUN8I ++#define SUNXI_GPF2_UART0_TX 3 ++#define SUNXI_GPF4_UART0_RX 3 ++#else ++#define SUNXI_GPF2_UART0_TX 4 ++#define SUNXI_GPF4_UART0_RX 4 ++#endif ++ ++#define SUN4I_GPG0_SDC1 4 ++ ++#define SUN4I_GPH22_SDC1 5 ++ ++#define SUN4I_GPI4_SDC3 2 ++ ++/* GPIO pin pull-up/down config */ ++#define SUNXI_GPIO_PULL_DISABLE 0 ++#define SUNXI_GPIO_PULL_UP 1 ++#define SUNXI_GPIO_PULL_DOWN 2 ++ ++#define SUNXI_GPL0_R_P2WI_SCK 3 ++#define SUNXI_GPL1_R_P2WI_SDA 3 ++ ++#define SUN8I_GPL2_R_UART_TX 2 ++#define SUN8I_GPL3_R_UART_RX 2 ++ ++int sunxi_gpio_set_cfgpin(u32 pin, u32 val); ++int sunxi_gpio_get_cfgpin(u32 pin); ++int sunxi_gpio_set_drv(u32 pin, u32 val); ++int sunxi_gpio_set_pull(u32 pin, u32 val); ++int sunxi_name_to_gpio(const char *name); ++#define name_to_gpio(name) sunxi_name_to_gpio(name) ++ ++#endif /* _SUNXI_GPIO_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/i2c.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/i2c.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/i2c.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/i2c.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,15 @@ ++/* ++ * Copyright 2014 - Hans de Goede hdegoede@redhat.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#ifndef _SUNXI_I2C_H_ ++#define _SUNXI_I2C_H_ ++ ++#include <asm/arch/cpu.h> ++ ++#define CONFIG_I2C_MVTWSI_BASE SUNXI_TWI0_BASE ++/* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */ ++#define CONFIG_SYS_TCLK 24000000 ++ ++#endif +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/mmc.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/mmc.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/mmc.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/mmc.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,122 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Aaron leafy.myeh@allwinnertech.com ++ * ++ * MMC register definition for allwinner sunxi platform. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_MMC_H ++#define _SUNXI_MMC_H ++ ++#include <linux/types.h> ++ ++struct sunxi_mmc { ++ u32 gctrl; /* 0x00 global control */ ++ u32 clkcr; /* 0x04 clock control */ ++ u32 timeout; /* 0x08 time out */ ++ u32 width; /* 0x0c bus width */ ++ u32 blksz; /* 0x10 block size */ ++ u32 bytecnt; /* 0x14 byte count */ ++ u32 cmd; /* 0x18 command */ ++ u32 arg; /* 0x1c argument */ ++ u32 resp0; /* 0x20 response 0 */ ++ u32 resp1; /* 0x24 response 1 */ ++ u32 resp2; /* 0x28 response 2 */ ++ u32 resp3; /* 0x2c response 3 */ ++ u32 imask; /* 0x30 interrupt mask */ ++ u32 mint; /* 0x34 masked interrupt status */ ++ u32 rint; /* 0x38 raw interrupt status */ ++ u32 status; /* 0x3c status */ ++ u32 ftrglevel; /* 0x40 FIFO threshold watermark*/ ++ u32 funcsel; /* 0x44 function select */ ++ u32 cbcr; /* 0x48 CIU byte count */ ++ u32 bbcr; /* 0x4c BIU byte count */ ++ u32 dbgc; /* 0x50 debug enable */ ++ u32 res0[11]; ++ u32 dmac; /* 0x80 internal DMA control */ ++ u32 dlba; /* 0x84 internal DMA descr list base address */ ++ u32 idst; /* 0x88 internal DMA status */ ++ u32 idie; /* 0x8c internal DMA interrupt enable */ ++ u32 chda; /* 0x90 */ ++ u32 cbda; /* 0x94 */ ++}; ++ ++#define SUNXI_MMC_CLK_POWERSAVE (0x1 << 17) ++#define SUNXI_MMC_CLK_ENABLE (0x1 << 16) ++#define SUNXI_MMC_CLK_DIVIDER_MASK (0xff) ++ ++#define SUNXI_MMC_GCTRL_SOFT_RESET (0x1 << 0) ++#define SUNXI_MMC_GCTRL_FIFO_RESET (0x1 << 1) ++#define SUNXI_MMC_GCTRL_DMA_RESET (0x1 << 2) ++#define SUNXI_MMC_GCTRL_RESET (SUNXI_MMC_GCTRL_SOFT_RESET|\ ++ SUNXI_MMC_GCTRL_FIFO_RESET|\ ++ SUNXI_MMC_GCTRL_DMA_RESET) ++#define SUNXI_MMC_GCTRL_DMA_ENABLE (0x1 << 5) ++#define SUNXI_MMC_GCTRL_ACCESS_BY_AHB (0x1 << 31) ++ ++#define SUNXI_MMC_CMD_RESP_EXPIRE (0x1 << 6) ++#define SUNXI_MMC_CMD_LONG_RESPONSE (0x1 << 7) ++#define SUNXI_MMC_CMD_CHK_RESPONSE_CRC (0x1 << 8) ++#define SUNXI_MMC_CMD_DATA_EXPIRE (0x1 << 9) ++#define SUNXI_MMC_CMD_WRITE (0x1 << 10) ++#define SUNXI_MMC_CMD_AUTO_STOP (0x1 << 12) ++#define SUNXI_MMC_CMD_WAIT_PRE_OVER (0x1 << 13) ++#define SUNXI_MMC_CMD_SEND_INIT_SEQ (0x1 << 15) ++#define SUNXI_MMC_CMD_UPCLK_ONLY (0x1 << 21) ++#define SUNXI_MMC_CMD_START (0x1 << 31) ++ ++#define SUNXI_MMC_RINT_RESP_ERROR (0x1 << 1) ++#define SUNXI_MMC_RINT_COMMAND_DONE (0x1 << 2) ++#define SUNXI_MMC_RINT_DATA_OVER (0x1 << 3) ++#define SUNXI_MMC_RINT_TX_DATA_REQUEST (0x1 << 4) ++#define SUNXI_MMC_RINT_RX_DATA_REQUEST (0x1 << 5) ++#define SUNXI_MMC_RINT_RESP_CRC_ERROR (0x1 << 6) ++#define SUNXI_MMC_RINT_DATA_CRC_ERROR (0x1 << 7) ++#define SUNXI_MMC_RINT_RESP_TIMEOUT (0x1 << 8) ++#define SUNXI_MMC_RINT_DATA_TIMEOUT (0x1 << 9) ++#define SUNXI_MMC_RINT_VOLTAGE_CHANGE_DONE (0x1 << 10) ++#define SUNXI_MMC_RINT_FIFO_RUN_ERROR (0x1 << 11) ++#define SUNXI_MMC_RINT_HARD_WARE_LOCKED (0x1 << 12) ++#define SUNXI_MMC_RINT_START_BIT_ERROR (0x1 << 13) ++#define SUNXI_MMC_RINT_AUTO_COMMAND_DONE (0x1 << 14) ++#define SUNXI_MMC_RINT_END_BIT_ERROR (0x1 << 15) ++#define SUNXI_MMC_RINT_SDIO_INTERRUPT (0x1 << 16) ++#define SUNXI_MMC_RINT_CARD_INSERT (0x1 << 30) ++#define SUNXI_MMC_RINT_CARD_REMOVE (0x1 << 31) ++#define SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT \ ++ (SUNXI_MMC_RINT_RESP_ERROR | \ ++ SUNXI_MMC_RINT_RESP_CRC_ERROR | \ ++ SUNXI_MMC_RINT_DATA_CRC_ERROR | \ ++ SUNXI_MMC_RINT_RESP_TIMEOUT | \ ++ SUNXI_MMC_RINT_DATA_TIMEOUT | \ ++ SUNXI_MMC_RINT_VOLTAGE_CHANGE_DONE | \ ++ SUNXI_MMC_RINT_FIFO_RUN_ERROR | \ ++ SUNXI_MMC_RINT_HARD_WARE_LOCKED | \ ++ SUNXI_MMC_RINT_START_BIT_ERROR | \ ++ SUNXI_MMC_RINT_END_BIT_ERROR) /* 0xbfc2 */ ++#define SUNXI_MMC_RINT_INTERRUPT_DONE_BIT \ ++ (SUNXI_MMC_RINT_AUTO_COMMAND_DONE | \ ++ SUNXI_MMC_RINT_DATA_OVER | \ ++ SUNXI_MMC_RINT_COMMAND_DONE | \ ++ SUNXI_MMC_RINT_VOLTAGE_CHANGE_DONE) ++ ++#define SUNXI_MMC_STATUS_RXWL_FLAG (0x1 << 0) ++#define SUNXI_MMC_STATUS_TXWL_FLAG (0x1 << 1) ++#define SUNXI_MMC_STATUS_FIFO_EMPTY (0x1 << 2) ++#define SUNXI_MMC_STATUS_FIFO_FULL (0x1 << 3) ++#define SUNXI_MMC_STATUS_CARD_PRESENT (0x1 << 8) ++#define SUNXI_MMC_STATUS_CARD_DATA_BUSY (0x1 << 9) ++#define SUNXI_MMC_STATUS_DATA_FSM_BUSY (0x1 << 10) ++ ++#define SUNXI_MMC_IDMAC_RESET (0x1 << 0) ++#define SUNXI_MMC_IDMAC_FIXBURST (0x1 << 1) ++#define SUNXI_MMC_IDMAC_ENABLE (0x1 << 7) ++ ++#define SUNXI_MMC_IDIE_TXIRQ (0x1 << 0) ++#define SUNXI_MMC_IDIE_RXIRQ (0x1 << 1) ++ ++int sunxi_mmc_init(int sdc_no); ++#endif /* _SUNXI_MMC_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/p2wi.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/p2wi.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/p2wi.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/p2wi.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,142 @@ ++/* ++ * Sunxi platform Push-Push i2c register definition. ++ * ++ * (c) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://linux-sunxi.org ++ * ++ * (c)Copyright 2006-2013 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_P2WI_H ++#define _SUNXI_P2WI_H ++ ++#include <linux/types.h> ++ ++#define P2WI_CTRL_RESET (0x1 << 0) ++#define P2WI_CTRL_IRQ_EN (0x1 << 1) ++#define P2WI_CTRL_TRANS_ABORT (0x1 << 6) ++#define P2WI_CTRL_TRANS_START (0x1 << 7) ++ ++#define __P2WI_CC_CLK(n) (((n) & 0xff) << 0) ++#define P2WI_CC_CLK_MASK __P2WI_CC_CLK_DIV(0xff) ++#define __P2WI_CC_CLK_DIV(n) (((n) >> 1) - 1) ++#define P2WI_CC_CLK_DIV(n) \ ++ __P2WI_CC_CLK(__P2WI_CC_CLK_DIV(n)) ++#define P2WI_CC_SDA_OUT_DELAY(n) (((n) & 0x7) << 8) ++#define P2WI_CC_SDA_OUT_DELAY_MASK P2WI_CC_SDA_OUT_DELAY(0x7) ++ ++#define P2WI_IRQ_TRANS_DONE (0x1 << 0) ++#define P2WI_IRQ_TRANS_ERR (0x1 << 1) ++#define P2WI_IRQ_LOAD_BUSY (0x1 << 2) ++ ++#define P2WI_STAT_TRANS_DONE (0x1 << 0) ++#define P2WI_STAT_TRANS_ERR (0x1 << 1) ++#define P2WI_STAT_LOAD_BUSY (0x1 << 2) ++#define __P2WI_STAT_TRANS_ERR(n) (((n) & 0xff) << 8) ++#define P2WI_STAT_TRANS_ERR_MASK __P2WI_STAT_TRANS_ERR_ID(0xff) ++#define __P2WI_STAT_TRANS_ERR_BYTE_1 0x01 ++#define __P2WI_STAT_TRANS_ERR_BYTE_2 0x02 ++#define __P2WI_STAT_TRANS_ERR_BYTE_3 0x04 ++#define __P2WI_STAT_TRANS_ERR_BYTE_4 0x08 ++#define __P2WI_STAT_TRANS_ERR_BYTE_5 0x10 ++#define __P2WI_STAT_TRANS_ERR_BYTE_6 0x20 ++#define __P2WI_STAT_TRANS_ERR_BYTE_7 0x40 ++#define __P2WI_STAT_TRANS_ERR_BYTE_8 0x80 ++#define P2WI_STAT_TRANS_ERR_BYTE_1 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_1) ++#define P2WI_STAT_TRANS_ERR_BYTE_2 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_2) ++#define P2WI_STAT_TRANS_ERR_BYTE_3 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_3) ++#define P2WI_STAT_TRANS_ERR_BYTE_4 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_4) ++#define P2WI_STAT_TRANS_ERR_BYTE_5 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_5) ++#define P2WI_STAT_TRANS_ERR_BYTE_6 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_6) ++#define P2WI_STAT_TRANS_ERR_BYTE_7 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_7) ++#define P2WI_STAT_TRANS_ERR_BYTE_8 \ ++ __P2WI_STAT_TRANS_ERR(__P2WI_STAT_TRANS_ERR_BYTE_8) ++ ++#define P2WI_DATADDR_BYTE_1(n) (((n) & 0xff) << 0) ++#define P2WI_DATADDR_BYTE_1_MASK P2WI_DATADDR_BYTE_1(0xff) ++#define P2WI_DATADDR_BYTE_2(n) (((n) & 0xff) << 8) ++#define P2WI_DATADDR_BYTE_2_MASK P2WI_DATADDR_BYTE_2(0xff) ++#define P2WI_DATADDR_BYTE_3(n) (((n) & 0xff) << 16) ++#define P2WI_DATADDR_BYTE_3_MASK P2WI_DATADDR_BYTE_3(0xff) ++#define P2WI_DATADDR_BYTE_4(n) (((n) & 0xff) << 24) ++#define P2WI_DATADDR_BYTE_4_MASK P2WI_DATADDR_BYTE_4(0xff) ++#define P2WI_DATADDR_BYTE_5(n) (((n) & 0xff) << 0) ++#define P2WI_DATADDR_BYTE_5_MASK P2WI_DATADDR_BYTE_5(0xff) ++#define P2WI_DATADDR_BYTE_6(n) (((n) & 0xff) << 8) ++#define P2WI_DATADDR_BYTE_6_MASK P2WI_DATADDR_BYTE_6(0xff) ++#define P2WI_DATADDR_BYTE_7(n) (((n) & 0xff) << 16) ++#define P2WI_DATADDR_BYTE_7_MASK P2WI_DATADDR_BYTE_7(0xff) ++#define P2WI_DATADDR_BYTE_8(n) (((n) & 0xff) << 24) ++#define P2WI_DATADDR_BYTE_8_MASK P2WI_DATADDR_BYTE_8(0xff) ++ ++#define __P2WI_DATA_NUM_BYTES(n) (((n) & 0x7) << 0) ++#define P2WI_DATA_NUM_BYTES_MASK __P2WI_DATA_NUM_BYTES(0x7) ++#define P2WI_DATA_NUM_BYTES(n) __P2WI_DATA_NUM_BYTES((n) - 1) ++#define P2WI_DATA_NUM_BYTES_READ (0x1 << 4) ++ ++#define P2WI_DATA_BYTE_1(n) (((n) & 0xff) << 0) ++#define P2WI_DATA_BYTE_1_MASK P2WI_DATA_BYTE_1(0xff) ++#define P2WI_DATA_BYTE_2(n) (((n) & 0xff) << 8) ++#define P2WI_DATA_BYTE_2_MASK P2WI_DATA_BYTE_2(0xff) ++#define P2WI_DATA_BYTE_3(n) (((n) & 0xff) << 16) ++#define P2WI_DATA_BYTE_3_MASK P2WI_DATA_BYTE_3(0xff) ++#define P2WI_DATA_BYTE_4(n) (((n) & 0xff) << 24) ++#define P2WI_DATA_BYTE_4_MASK P2WI_DATA_BYTE_4(0xff) ++#define P2WI_DATA_BYTE_5(n) (((n) & 0xff) << 0) ++#define P2WI_DATA_BYTE_5_MASK P2WI_DATA_BYTE_5(0xff) ++#define P2WI_DATA_BYTE_6(n) (((n) & 0xff) << 8) ++#define P2WI_DATA_BYTE_6_MASK P2WI_DATA_BYTE_6(0xff) ++#define P2WI_DATA_BYTE_7(n) (((n) & 0xff) << 16) ++#define P2WI_DATA_BYTE_7_MASK P2WI_DATA_BYTE_7(0xff) ++#define P2WI_DATA_BYTE_8(n) (((n) & 0xff) << 24) ++#define P2WI_DATA_BYTE_8_MASK P2WI_DATA_BYTE_8(0xff) ++ ++#define P2WI_LINECTRL_SDA_CTRL_EN (0x1 << 0) ++#define P2WI_LINECTRL_SDA_OUT_HIGH (0x1 << 1) ++#define P2WI_LINECTRL_SCL_CTRL_EN (0x1 << 2) ++#define P2WI_LINECTRL_SCL_OUT_HIGH (0x1 << 3) ++#define P2WI_LINECTRL_SDA_STATE_HIGH (0x1 << 4) ++#define P2WI_LINECTRL_SCL_STATE_HIGH (0x1 << 5) ++ ++#define P2WI_PM_DEV_ADDR(n) (((n) & 0xff) << 0) ++#define P2WI_PM_DEV_ADDR_MASK P2WI_PM_DEV_ADDR(0xff) ++#define P2WI_PM_CTRL_ADDR(n) (((n) & 0xff) << 8) ++#define P2WI_PM_CTRL_ADDR_MASK P2WI_PM_CTRL_ADDR(0xff) ++#define P2WI_PM_INIT_DATA(n) (((n) & 0xff) << 16) ++#define P2WI_PM_INIT_DATA_MASK P2WI_PM_INIT_DATA(0xff) ++#define P2WI_PM_INIT_SEND (0x1 << 31) ++ ++#ifndef __ASSEMBLY__ ++struct sunxi_p2wi_reg { ++ u32 ctrl; /* 0x00 control */ ++ u32 cc; /* 0x04 clock control */ ++ u32 irq; /* 0x08 interrupt */ ++ u32 status; /* 0x0c status */ ++ u32 dataddr0; /* 0x10 data address 0 */ ++ u32 dataddr1; /* 0x14 data address 1 */ ++ u32 numbytes; /* 0x18 num bytes */ ++ u32 data0; /* 0x1c data buffer 0 */ ++ u32 data1; /* 0x20 data buffer 1 */ ++ u32 linectrl; /* 0x24 line control */ ++ u32 pm; /* 0x28 power management */ ++}; ++ ++void p2wi_init(void); ++int p2wi_set_pmu_address(u8 slave_addr, u8 ctrl_reg, u8 init_data); ++int p2wi_read(const u8 addr, u8 *data); ++int p2wi_write(const u8 addr, u8 data); ++ ++#endif /* __ASSEMBLY__ */ ++#endif /* _SUNXI_P2WI_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/prcm.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/prcm.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/prcm.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/prcm.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,238 @@ ++/* ++ * Sunxi A31 Power Management Unit register definition. ++ * ++ * (C) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://linux-sunxi.org ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Berg Xing bergxing@allwinnertech.com ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_PRCM_H ++#define _SUNXI_PRCM_H ++ ++#define __PRCM_CPUS_CFG_PRE(n) (((n) & 0x3) << 4) ++#define PRCM_CPUS_CFG_PRE_MASK __PRCM_CPUS_CFG_PRE(0x3) ++#define __PRCM_CPUS_CFG_PRE_DIV(n) (((n) >> 1) - 1) ++#define PRCM_CPUS_CFG_PRE_DIV(n) \ ++ __PRCM_CPUS_CFG_PRE(__PRCM_CPUS_CFG_CLK_PRE(n)) ++#define __PRCM_CPUS_CFG_POST(n) (((n) & 0x1f) << 8) ++#define PRCM_CPUS_CFG_POST_MASK __PRCM_CPUS_CFG_POST(0x1f) ++#define __PRCM_CPUS_CFG_POST_DIV(n) ((n) - 1) ++#define PRCM_CPUS_CFG_POST_DIV(n) \ ++ __PRCM_CPUS_CFG_POST_DIV(__PRCM_CPUS_CFG_POST_DIV(n)) ++#define __PRCM_CPUS_CFG_CLK_SRC(n) (((n) & 0x3) << 16) ++#define PRCM_CPUS_CFG_CLK_SRC_MASK __PRCM_CPUS_CFG_CLK_SRC(0x3) ++#define __PRCM_CPUS_CFG_CLK_SRC_LOSC 0x0 ++#define __PRCM_CPUS_CFG_CLK_SRC_HOSC 0x1 ++#define __PRCM_CPUS_CFG_CLK_SRC_PLL6 0x2 ++#define __PRCM_CPUS_CFG_CLK_SRC_PDIV 0x3 ++#define PRCM_CPUS_CFG_CLK_SRC_LOSC \ ++ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_LOSC) ++#define PRCM_CPUS_CFG_CLK_SRC_HOSC \ ++ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_HOSC) ++#define PRCM_CPUS_CFG_CLK_SRC_PLL6 \ ++ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_PLL6) ++#define PRCM_CPUS_CFG_CLK_SRC_PDIV \ ++ __PRCM_CPUS_CFG_CLK_SRC(__PRCM_CPUS_CFG_CLK_SRC_PDIV) ++ ++#define __PRCM_APB0_RATIO(n) (((n) & 0x3) <<0) ++#define PRCM_APB0_RATIO_DIV_MASK __PRCM_APB0_RATIO_DIV(0x3) ++#define __PRCM_APB0_RATIO_DIV(n) (((n) >> 1) - 1) ++#define PRCM_APB0_RATIO_DIV(n) \ ++ __PRCM_APB0_RATIO(__PRCM_APB0_RATIO_DIV(n)) ++ ++#define PRCM_CPU_CFG_NEON_CLK_EN (0x1 << 0) ++#define PRCM_CPU_CFG_CPU_CLK_EN (0x1 << 1) ++ ++#define PRCM_APB0_GATE_PIO (0x1 << 0) ++#define PRCM_APB0_GATE_IR (0x1 << 1) ++#define PRCM_APB0_GATE_TIMER01 (0x1 << 2) ++#define PRCM_APB0_GATE_P2WI (0x1 << 3) ++#define PRCM_APB0_GATE_UART (0x1 << 4) ++#define PRCM_APB0_GATE_1WIRE (0x1 << 5) ++#define PRCM_APB0_GATE_I2C (0x1 << 6) ++ ++#define PRCM_APB0_RESET_PIO (0x1 << 0) ++#define PRCM_APB0_RESET_IR (0x1 << 1) ++#define PRCM_APB0_RESET_TIMER01 (0x1 << 2) ++#define PRCM_APB0_RESET_P2WI (0x1 << 3) ++#define PRCM_APB0_RESET_UART (0x1 << 4) ++#define PRCM_APB0_RESET_1WIRE (0x1 << 5) ++#define PRCM_APB0_RESET_I2C (0x1 << 6) ++ ++#define PRCM_PLL_CTRL_PLL_BIAS (0x1 << 0) ++#define PRCM_PLL_CTRL_HOSC_GAIN_ENH (0x1 << 1) ++#define __PRCM_PLL_CTRL_USB_CLK_SRC(n) (((n) & 0x3) << 4) ++#define PRCM_PLL_CTRL_USB_CLK_SRC_MASK \ ++ __PRCM_PLL_CTRL_USB_CLK_SRC(0x3) ++#define __PRCM_PLL_CTRL_USB_CLK_0 0x0 ++#define __PRCM_PLL_CTRL_USB_CLK_1 0x1 ++#define __PRCM_PLL_CTRL_USB_CLK_2 0x2 ++#define __PRCM_PLL_CTRL_USB_CLK_3 0x3 ++#define PRCM_PLL_CTRL_USB_CLK_0 \ ++ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_0) ++#define PRCM_PLL_CTRL_USB_CLK_1 \ ++ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_1) ++#define PRCM_PLL_CTRL_USB_CLK_2 \ ++ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_2) ++#define PRCM_PLL_CTRL_USB_CLK_3 \ ++ __PRCM_PLL_CTRL_USB_CLK_SRC(__PRCM_PLL_CTRL_USB_CLK_3) ++#define __PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) (((n) & 0x3) << 12) ++#define PRCM_PLL_CTRL_INT_PLL_IN_SEL_MASK \ ++ __PRCM_PLL_CTRL_INT_PLL_IN_SEL(0x3) ++#define PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) \ ++ __PRCM_PLL_CTRL_INT_PLL_IN_SEL(n) ++#define __PRCM_PLL_CTRL_HOSC_CLK_SEL(n) (((n) & 0x3) << 20) ++#define PRCM_PLL_CTRL_HOSC_CLK_SEL_MASK \ ++ __PRCM_PLL_CTRL_HOSC_CLK_SEL(0x3) ++#define __PRCM_PLL_CTRL_HOSC_CLK_0 0x0 ++#define __PRCM_PLL_CTRL_HOSC_CLK_1 0x1 ++#define __PRCM_PLL_CTRL_HOSC_CLK_2 0x2 ++#define __PRCM_PLL_CTRL_HOSC_CLK_3 0x3 ++#define PRCM_PLL_CTRL_HOSC_CLK_0 \ ++ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_0) ++#define PRCM_PLL_CTRL_HOSC_CLK_1 \ ++ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_1) ++#define PRCM_PLL_CTRL_HOSC_CLK_2 \ ++ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_2) ++#define PRCM_PLL_CTRL_HOSC_CLK_3 \ ++ __PRCM_PLL_CTRL_HOSC_CLK_SEL(__PRCM_PLL_CTRL_HOSC_CLK_3) ++#define PRCM_PLL_CTRL_PLL_TST_SRC_EXT (0x1 << 24) ++#define PRCM_PLL_CTRL_LDO_DIGITAL_EN (0x1 << 0) ++#define PRCM_PLL_CTRL_LDO_ANALOG_EN (0x1 << 1) ++#define PRCM_PLL_CTRL_EXT_OSC_EN (0x1 << 2) ++#define PRCM_PLL_CTRL_CLK_TST_EN (0x1 << 3) ++#define PRCM_PLL_CTRL_IN_PWR_HIGH (0x1 << 15) /* 3.3 for hi 2.5 for lo */ ++#define __PRCM_PLL_CTRL_VDD_LDO_OUT(n) (((n) & 0x7) << 16) ++#define PRCM_PLL_CTRL_LDO_OUT_MASK \ ++ __PRCM_PLL_CTRL_LDO_OUT(0x7) ++/* When using the low voltage 20 mV steps, and high voltage 30 mV steps */ ++#define PRCM_PLL_CTRL_LDO_OUT_L(n) \ ++ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) - 1000) / 20) & 0x7) ++#define PRCM_PLL_CTRL_LDO_OUT_H(n) \ ++ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) - 1160) / 30) & 0x7) ++#define PRCM_PLL_CTRL_LDO_OUT_LV(n) \ ++ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) & 0x7) * 20) + 1000) ++#define PRCM_PLL_CTRL_LDO_OUT_HV(n) \ ++ __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) & 0x7) * 30) + 1160) ++#define PRCM_PLL_CTRL_LDO_KEY (0xa7 << 24) ++ ++#define PRCM_CLK_1WIRE_GATE (0x1 << 31) ++ ++#define __PRCM_CLK_MOD0_M(n) (((n) & 0xf) << 0) ++#define PRCM_CLK_MOD0_M_MASK __PRCM_CLK_MOD0_M(0xf) ++#define __PRCM_CLK_MOD0_M_X(n) (n - 1) ++#define PRCM_CLK_MOD0_M(n) __PRCM_CLK_MOD0_M(__PRCM_CLK_MOD0_M_X(n)) ++#define PRCM_CLK_MOD0_OUT_PHASE(n) (((n) & 0x7) << 8) ++#define PRCM_CLK_MOD0_OUT_PHASE_MASK(n) PRCM_CLK_MOD0_OUT_PHASE(0x7) ++#define _PRCM_CLK_MOD0_N(n) (((n) & 0x3) << 16) ++#define PRCM_CLK_MOD0_N_MASK __PRCM_CLK_MOD_N(0x3) ++#define __PRCM_CLK_MOD0_N_X(n) (((n) >> 1) -1) ++#define PRCM_CLK_MOD0_N(n) __PRCM_CLK_MOD0_N(__PRCM_CLK_MOD0_N_X(n)) ++#define PRCM_CLK_MOD0_SMPL_PHASE(n) (((n) & 0x7) << 20) ++#define PRCM_CLK_MOD0_SMPL_PHASE_MASK PRCM_CLK_MOD0_SMPL_PHASE(0x7) ++#define PRCM_CLK_MOD0_SRC_SEL(n) (((n) & 0x7) << 24) ++#define PRCM_CLK_MOD0_SRC_SEL_MASK PRCM_CLK_MOD0_SRC_SEL(0x7) ++#define PRCM_CLK_MOD0_GATE_EN (0x1 << 31) ++ ++#define PRCM_APB0_RESET_PIO (0x1 << 0) ++#define PRCM_APB0_RESET_IR (0x1 << 1) ++#define PRCM_APB0_RESET_TIMER01 (0x1 << 2) ++#define PRCM_APB0_RESET_P2WI (0x1 << 3) ++#define PRCM_APB0_RESET_UART (0x1 << 4) ++#define PRCM_APB0_RESET_1WIRE (0x1 << 5) ++#define PRCM_APB0_RESET_I2C (0x1 << 6) ++ ++#define __PRCM_CLK_OUTD_M(n) (((n) & 0x7) << 8) ++#define PRCM_CLK_OUTD_M_MASK __PRCM_CLK_OUTD_M(0x7) ++#define __PRCM_CLK_OUTD_M_X() ((n) - 1) ++#define PRCM_CLK_OUTD_M(n) __PRCM_CLK_OUTD_M(__PRCM_CLK_OUTD_M_X(n)) ++#define __PRCM_CLK_OUTD_N(n) (((n) & 0x7) << 20) ++#define PRCM_CLK_OUTD_N_MASK __PRCM_CLK_OUTD_N(0x7) ++#define __PRCM_CLK_OUTD_N_X(n) (((n) >> 1) - 1) ++#define PRCM_CLK_OUTD_N(n) __PRCM_CLK_OUTD_N(__PRCM_CLK_OUTD_N_X(n) ++#define __PRCM_CLK_OUTD_SRC_SEL(n) (((n) & 0x3) << 24) ++#define PRCM_CLK_OUTD_SRC_SEL_MASK __PRCM_CLK_OUTD_SRC_SEL(0x3) ++#define __PRCM_CLK_OUTD_SRC_LOSC2 0x0 ++#define __PRCM_CLK_OUTD_SRC_LOSC 0x1 ++#define __PRCM_CLK_OUTD_SRC_HOSC 0x2 ++#define __PRCM_CLK_OUTD_SRC_ERR 0x3 ++#define PRCM_CLK_OUTD_SRC_LOSC2 \ ++#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_LOSC2) ++#define PRCM_CLK_OUTD_SRC_LOSC \ ++#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_LOSC) ++#define PRCM_CLK_OUTD_SRC_HOSC \ ++#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_HOSC) ++#define PRCM_CLK_OUTD_SRC_ERR \ ++#deifne __PRCM_CLK_OUTD_SRC_SEL(__PRCM_CLK_OUTD_SRC_ERR) ++#define PRCM_CLK_OUTD_EN (0x1 << 31) ++ ++#define PRCM_CPU0_PWROFF (0x1 << 0) ++#define PRCM_CPU1_PWROFF (0x1 << 1) ++#define PRCM_CPU2_PWROFF (0x1 << 2) ++#define PRCM_CPU3_PWROFF (0x1 << 3) ++#define PRCM_CPU_ALL_PWROFF (0xf << 0) ++ ++#define PRCM_VDD_SYS_DRAM_CH0_PAD_HOLD_PWROFF (0x1 << 0) ++#define PRCM_VDD_SYS_DRAM_CH1_PAD_HOLD_PWROFF (0x1 << 1) ++#define PRCM_VDD_SYS_AVCC_A_PWROFF (0x1 << 2) ++#define PRCM_VDD_SYS_CPU0_VDD_PWROFF (0x1 << 3) ++ ++#define PRCM_VDD_GPU_PWROFF (0x1 << 0) ++ ++#define PRCM_VDD_SYS_RESET (0x1 << 0) ++ ++#define PRCM_CPU1_PWR_CLAMP(n) (((n) & 0xff) << 0) ++#define PRCM_CPU1_PWR_CLAMP_MASK PRCM_CPU1_PWR_CLAMP(0xff) ++ ++#define PRCM_CPU2_PWR_CLAMP(n) (((n) & 0xff) << 0) ++#define PRCM_CPU2_PWR_CLAMP_MASK PRCM_CPU2_PWR_CLAMP(0xff) ++ ++#define PRCM_CPU3_PWR_CLAMP(n) (((n) & 0xff) << 0) ++#define PRCM_CPU3_PWR_CLAMP_MASK PRCM_CPU3_PWR_CLAMP(0xff) ++ ++#ifndef __ASSEMBLY__ ++struct sunxi_prcm_reg { ++ u32 cpus_cfg; /* 0x000 */ ++ u8 res0[0x8]; /* 0x004 */ ++ u32 apb0_ratio; /* 0x00c */ ++ u32 cpu0_cfg; /* 0x010 */ ++ u32 cpu1_cfg; /* 0x014 */ ++ u32 cpu2_cfg; /* 0x018 */ ++ u32 cpu3_cfg; /* 0x01c */ ++ u8 res1[0x8]; /* 0x020 */ ++ u32 apb0_gate; /* 0x028 */ ++ u8 res2[0x14]; /* 0x02c */ ++ u32 pll_ctrl0; /* 0x040 */ ++ u32 pll_ctrl1; /* 0x044 */ ++ u8 res3[0x8]; /* 0x048 */ ++ u32 clk_1wire; /* 0x050 */ ++ u32 clk_ir; /* 0x054 */ ++ u8 res4[0x58]; /* 0x058 */ ++ u32 apb0_reset; /* 0x0b0 */ ++ u8 res5[0x3c]; /* 0x0b4 */ ++ u32 clk_outd; /* 0x0f0 */ ++ u8 res6[0xc]; /* 0x0f4 */ ++ u32 cpu_pwroff; /* 0x100 */ ++ u8 res7[0xc]; /* 0x104 */ ++ u32 vdd_sys_pwroff; /* 0x110 */ ++ u8 res8[0x4]; /* 0x114 */ ++ u32 gpu_pwroff; /* 0x118 */ ++ u8 res9[0x4]; /* 0x11c */ ++ u32 vdd_pwr_reset; /* 0x120 */ ++ u8 res10[0x20]; /* 0x124 */ ++ u32 cpu1_pwr_clamp; /* 0x144 */ ++ u32 cpu2_pwr_clamp; /* 0x148 */ ++ u32 cpu3_pwr_clamp; /* 0x14c */ ++ u8 res11[0x30]; /* 0x150 */ ++ u32 dram_pwr; /* 0x180 */ ++ u8 res12[0xc]; /* 0x184 */ ++ u32 dram_tst; /* 0x190 */ ++}; ++ ++void prcm_apb0_enable(u32 flags); ++#endif /* __ASSEMBLY__ */ ++#endif /* _PRCM_H */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/smp.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/smp.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/smp.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/smp.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,22 @@ ++/* ++ * (C) Copyright 2013 ++ * Carl van Schaik carl@ok-labs.com ++ * ++ * CPU configuration registers for the sun7i (A20). ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_SMP_H_ ++#define _SUNXI_SMP_H_ ++ ++#ifndef __ASSEMBLY__ ++ ++void startup_secondaries(void); ++ ++/* Assembly entry point */ ++extern void secondary_init(void); ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _SUNXI_SMP_H_ */ +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/spl.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/spl.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/spl.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/spl.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * This is a copy of omap3/spl.h: ++ * ++ * (C) Copyright 2012 ++ * Texas Instruments, <www.ti.com> ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#ifndef _ASM_ARCH_SPL_H_ ++#define _ASM_SPL_H_ ++ ++#define BOOT_DEVICE_NONE 0 ++#define BOOT_DEVICE_XIP 1 ++#define BOOT_DEVICE_NAND 2 ++#define BOOT_DEVICE_ONE_NAND 3 ++#define BOOT_DEVICE_MMC2 5 /*emmc*/ ++#define BOOT_DEVICE_MMC1 6 ++#define BOOT_DEVICE_XIPWAIT 7 ++#define BOOT_DEVICE_MMC2_2 0xff ++#endif +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/sys_proto.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/sys_proto.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/sys_proto.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/sys_proto.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,16 @@ ++/* ++ * (C) Copyright 2007-2012 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SYS_PROTO_H_ ++#define _SYS_PROTO_H_ ++ ++#include <linux/types.h> ++ ++void sdelay(unsigned long); ++ ++#endif +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/timer.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/timer.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/timer.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/timer.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,88 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Configuration settings for the Allwinner A10-evb board. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_TIMER_H_ ++#define _SUNXI_TIMER_H_ ++ ++#ifndef __ASSEMBLY__ ++ ++#include <linux/types.h> ++ ++/* General purpose timer */ ++struct sunxi_timer { ++ u32 ctl; ++ u32 inter; ++ u32 val; ++ u8 res[4]; ++}; ++ ++/* Audio video sync*/ ++struct sunxi_avs { ++ u32 ctl; /* 0x80 */ ++ u32 cnt0; /* 0x84 */ ++ u32 cnt1; /* 0x88 */ ++ u32 div; /* 0x8c */ ++}; ++ ++/* 64 bit counter */ ++struct sunxi_64cnt { ++ u32 ctl; /* 0xa0 */ ++ u32 lo; /* 0xa4 */ ++ u32 hi; /* 0xa8 */ ++}; ++ ++/* Watchdog */ ++struct sunxi_wdog { ++ u32 ctl; /* 0x90 */ ++ u32 mode; /* 0x94 */ ++}; ++ ++/* Rtc */ ++struct sunxi_rtc { ++ u32 ctl; /* 0x100 */ ++ u32 yymmdd; /* 0x104 */ ++ u32 hhmmss; /* 0x108 */ ++}; ++ ++/* Alarm */ ++struct sunxi_alarm { ++ u32 ddhhmmss; /* 0x10c */ ++ u32 hhmmss; /* 0x110 */ ++ u32 en; /* 0x114 */ ++ u32 irqen; /* 0x118 */ ++ u32 irqsta; /* 0x11c */ ++}; ++ ++/* Timer general purpose register */ ++struct sunxi_tgp { ++ u32 tgpd; ++}; ++ ++struct sunxi_timer_reg { ++ u32 tirqen; /* 0x00 */ ++ u32 tirqsta; /* 0x04 */ ++ u8 res1[8]; ++ struct sunxi_timer timer[6]; /* We have 6 timers */ ++ u8 res2[16]; ++ struct sunxi_avs avs; ++ struct sunxi_wdog wdog; ++ u8 res3[8]; ++ struct sunxi_64cnt cnt64; ++ u8 res4[0x58]; ++ struct sunxi_rtc rtc; ++ struct sunxi_alarm alarm; ++ struct sunxi_tgp tgp[4]; ++ u8 res5[8]; ++ u32 cpu_cfg; ++}; ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif +diff -ruN u-boot-2014.04/arch/arm/include/asm/arch-sunxi/watchdog.h u-boot-sunxi/arch/arm/include/asm/arch-sunxi/watchdog.h +--- u-boot-2014.04/arch/arm/include/asm/arch-sunxi/watchdog.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/arch/arm/include/asm/arch-sunxi/watchdog.h 2014-09-06 16:58:35.381953139 +0200 +@@ -0,0 +1,22 @@ ++/* ++ * Watchdog driver for the Allwinner sunxi platform. ++ * Copyright (C) 2013 Oliver Schinagl oliver@schinagl.nl ++ * http://www.linux-sunxi.org/ ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_WATCHDOG_H_ ++#define _SUNXI_WATCHDOG_H_ ++ ++/* Timeout limits */ ++#define WDT_MAX_TIMEOUT 16 ++#define WDT_OFF -1 ++ ++#ifndef __ASSEMBLY__ ++void watchdog_reset(void); ++void watchdog_set(int timeout); ++void watchdog_init(void); ++#endif /* __ASSEMBLY__ */ ++ ++#endif +diff -ruN u-boot-2014.04/board/sunxi/board.c u-boot-sunxi/board/sunxi/board.c +--- u-boot-2014.04/board/sunxi/board.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/board.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,239 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Some board init for the Allwinner A10-evb board. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#ifdef CONFIG_AXP152_POWER ++#include <axp152.h> ++#endif ++#ifdef CONFIG_AXP209_POWER ++#include <axp209.h> ++#endif ++#ifdef CONFIG_AXP221_POWER ++#include <axp221.h> ++#endif ++#include <asm/arch/clock.h> ++#include <asm/arch/cpu.h> ++#include <asm/arch/dram.h> ++#include <asm/arch/gpio.h> ++#include <asm/arch/mmc.h> ++#include <asm/io.h> ++#include <net.h> ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/* add board specific code here */ ++int board_init(void) ++{ ++ int id_pfr1; ++ ++ gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100); ++ ++ asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1)); ++ debug("id_pfr1: 0x%08x\n", id_pfr1); ++ /* Generic Timer Extension available? */ ++ if ((id_pfr1 >> 16) & 0xf) { ++ debug("Setting CNTFRQ\n"); ++ /* CNTFRQ == 24 MHz */ ++ asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(24000000)); ++ } ++ ++#ifdef CONFIG_STATUS_LED ++ status_led_set(STATUS_LED_BOOT, STATUS_LED_ON); ++#endif ++ return 0; ++} ++ ++#ifdef CONFIG_DISPLAY_BOARDINFO ++int checkboard(void) ++{ ++ printf("Board: %s\n", CONFIG_SYS_BOARD_NAME); ++ ++ return 0; ++} ++#endif ++ ++int dram_init(void) ++{ ++ gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0, PHYS_SDRAM_0_SIZE); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_GENERIC_MMC ++static void mmc_pinmux_setup(int sdc) ++{ ++ unsigned int pin; ++ ++ switch (sdc) { ++ case 0: ++ /* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */ ++ for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) { ++ sunxi_gpio_set_cfgpin(pin, SUNXI_GPF0_SDC0); ++ sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); ++ sunxi_gpio_set_drv(pin, 2); ++ } ++ break; ++ ++ case 1: ++ /* CMD-PH22, CLK-PH23, D0~D3-PH24~27 : 5 */ ++ for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) { ++ sunxi_gpio_set_cfgpin(pin, SUN4I_GPH22_SDC1); ++ sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); ++ sunxi_gpio_set_drv(pin, 2); ++ } ++ break; ++ ++ case 2: ++ /* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */ ++ for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) { ++ sunxi_gpio_set_cfgpin(pin, SUNXI_GPC6_SDC2); ++ sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); ++ sunxi_gpio_set_drv(pin, 2); ++ } ++ break; ++ ++ case 3: ++ /* CMD-PI4, CLK-PI5, D0~D3-PI6~9 : 2 */ ++ for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) { ++ sunxi_gpio_set_cfgpin(pin, SUN4I_GPI4_SDC3); ++ sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); ++ sunxi_gpio_set_drv(pin, 2); ++ } ++ break; ++ ++ default: ++ printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc); ++ break; ++ } ++} ++ ++int board_mmc_init(bd_t *bis) ++{ ++ mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT); ++ sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT); ++#if !defined (CONFIG_SPL_BUILD) && defined (CONFIG_MMC_SUNXI_SLOT_EXTRA) ++ mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA); ++ sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA); ++#endif ++ ++ return 0; ++} ++#endif ++ ++void i2c_init_board(void) ++{ ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUNXI_GPB0_TWI0); ++ sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUNXI_GPB0_TWI0); ++ clock_twi_onoff(0, 1); ++} ++ ++#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I) ++void sunxi_board_init(void) ++{ ++ int power_failed = 0; ++#if !defined(CONFIG_SUN6I) && !defined(CONFIG_SUN8I) ++ unsigned long ramsize; ++#endif ++ ++#ifdef CONFIG_AXP152_POWER ++ power_failed = axp152_init(); ++ power_failed |= axp152_set_dcdc2(1400); ++ power_failed |= axp152_set_dcdc3(1500); ++ power_failed |= axp152_set_dcdc4(1250); ++ power_failed |= axp152_set_ldo2(3000); ++#endif ++#ifdef CONFIG_AXP209_POWER ++ power_failed |= axp209_init(); ++ power_failed |= axp209_set_dcdc2(1400); ++#ifdef CONFIG_FAST_MBUS ++ power_failed |= axp209_set_dcdc3(1300); ++#else ++ power_failed |= axp209_set_dcdc3(1250); ++#endif ++ power_failed |= axp209_set_ldo2(3000); ++ power_failed |= axp209_set_ldo3(2800); ++ power_failed |= axp209_set_ldo4(2800); ++#endif ++#ifdef CONFIG_AXP221_POWER ++ power_failed = axp221_init(); ++ power_failed |= axp221_set_dcdc1(3300); ++ power_failed |= axp221_set_dcdc2(1200); ++ power_failed |= axp221_set_dcdc3(1260); ++ power_failed |= axp221_set_dcdc4(1200); ++ power_failed |= axp221_set_dcdc5(1500); ++#ifdef CONFIG_ENABLE_DLDO1_POWER ++ power_failed |= axp221_set_dldo1(3300); ++#endif ++#endif ++ ++#if !defined(CONFIG_SUN6I) && !defined(CONFIG_SUN8I) ++ printf("DRAM:"); ++ ramsize = sunxi_dram_init(); ++ printf(" %lu MiB\n", ramsize >> 20); ++ if (!ramsize) ++ hang(); ++ ++ /* ++ * Only clock up the CPU to full speed if we are reasonably ++ * assured it's being powered with suitable core voltage ++ */ ++ if (!power_failed) ++ clock_set_pll1(CONFIG_CLK_FULL_SPEED); ++ else ++ printf("Failed to set core voltage! Can't set CPU frequency\n"); ++#endif ++} ++#endif ++ ++#if defined(CONFIG_SPL_OS_BOOT) && defined(CONFIG_AXP209_POWER) ++int spl_start_uboot(void) ++{ ++ if (axp209_poweron_by_dc()) ++ return 0; ++ axp209_power_button(); /* Clear any pending button event */ ++ mdelay(100); ++ return axp209_power_button(); ++} ++#endif ++ ++#ifdef CONFIG_SPL_DISPLAY_PRINT ++void spl_display_print(void) ++{ ++ printf("Board: %s\n", CONFIG_SYS_BOARD_NAME); ++} ++#endif ++ ++#ifdef CONFIG_MISC_INIT_R ++int misc_init_r(void) ++{ ++ if (!getenv("ethaddr")) { ++ uint32_t reg_val = readl(SUNXI_SID_BASE); ++ ++ if (reg_val) { ++ uint8_t mac_addr[6]; ++ ++ mac_addr[0] = 0x02; /* Non OUI / registered MAC address */ ++ mac_addr[1] = (reg_val >> 0) & 0xff; ++ reg_val = readl(SUNXI_SID_BASE + 0x0c); ++ mac_addr[2] = (reg_val >> 24) & 0xff; ++ mac_addr[3] = (reg_val >> 16) & 0xff; ++ mac_addr[4] = (reg_val >> 8) & 0xff; ++ mac_addr[5] = (reg_val >> 0) & 0xff; ++ ++ eth_setenv_enetaddr("ethaddr", mac_addr); ++ } ++ } ++ ++ return 0; ++} ++#endif +diff -ruN u-boot-2014.04/board/sunxi/dram_a10_olinuxino_l.c u-boot-sunxi/board/sunxi/dram_a10_olinuxino_l.c +--- u-boot-2014.04/board/sunxi/dram_a10_olinuxino_l.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a10_olinuxino_l.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_a13_oli_micro.c u-boot-sunxi/board/sunxi/dram_a13_oli_micro.c +--- u-boot-2014.04/board/sunxi/dram_a13_oli_micro.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a13_oli_micro.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,32 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 256, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++ ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_a13_olinuxino.c u-boot-sunxi/board/sunxi/dram_a13_olinuxino.c +--- u-boot-2014.04/board/sunxi/dram_a13_olinuxino.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a13_olinuxino.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_a20_olinuxino_l2.c u-boot-sunxi/board/sunxi/dram_a20_olinuxino_l2.c +--- u-boot-2014.04/board/sunxi/dram_a20_olinuxino_l2.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a20_olinuxino_l2.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_a20_olinuxino_l.c u-boot-sunxi/board/sunxi/dram_a20_olinuxino_l.c +--- u-boot-2014.04/board/sunxi/dram_a20_olinuxino_l.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_a20_olinuxino_l.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_ainol_aw1.c u-boot-sunxi/board/sunxi/dram_ainol_aw1.c +--- u-boot-2014.04/board/sunxi/dram_ainol_aw1.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_ainol_aw1.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_auxtek_t003.c u-boot-sunxi/board/sunxi/dram_auxtek_t003.c +--- u-boot-2014.04/board/sunxi/dram_auxtek_t003.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_auxtek_t003.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_cubieboard.c u-boot-sunxi/board/sunxi/dram_cubieboard.c +--- u-boot-2014.04/board/sunxi/dram_cubieboard.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_cubieboard.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_cubietruck.c u-boot-sunxi/board/sunxi/dram_cubietruck.c +--- u-boot-2014.04/board/sunxi/dram_cubietruck.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_cubietruck.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 2048, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0x0, ++ .tpr4 = 0x1, ++ .tpr5 = 0x0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0x0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_eu3000.c u-boot-sunxi/board/sunxi/dram_eu3000.c +--- u-boot-2014.04/board/sunxi/dram_eu3000.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_eu3000.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_forfun_q88db.c u-boot-sunxi/board/sunxi/dram_forfun_q88db.c +--- u-boot-2014.04/board/sunxi/dram_forfun_q88db.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_forfun_q88db.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_gooseberry_a721.c u-boot-sunxi/board/sunxi/dram_gooseberry_a721.c +--- u-boot-2014.04/board/sunxi/dram_gooseberry_a721.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_gooseberry_a721.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 1024, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_h6.c u-boot-sunxi/board/sunxi/dram_h6.c +--- u-boot-2014.04/board/sunxi/dram_h6.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_h6.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_hackberry.c u-boot-sunxi/board/sunxi/dram_hackberry.c +--- u-boot-2014.04/board/sunxi/dram_hackberry.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_hackberry.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 1, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_icou_fatty_i.c u-boot-sunxi/board/sunxi/dram_icou_fatty_i.c +--- u-boot-2014.04/board/sunxi/dram_icou_fatty_i.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_icou_fatty_i.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_inet_k70hc.c u-boot-sunxi/board/sunxi/dram_inet_k70hc.c +--- u-boot-2014.04/board/sunxi/dram_inet_k70hc.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_inet_k70hc.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x12331a7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_linksprite_pcduino3.c u-boot-sunxi/board/sunxi/dram_linksprite_pcduino3.c +--- u-boot-2014.04/board/sunxi/dram_linksprite_pcduino3.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_linksprite_pcduino3.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7a, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0x0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_megafeis_a08.c u-boot-sunxi/board/sunxi/dram_megafeis_a08.c +--- u-boot-2014.04/board/sunxi/dram_megafeis_a08.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_megafeis_a08.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_merrii_m2.c u-boot-sunxi/board/sunxi/dram_merrii_m2.c +--- u-boot-2014.04/board/sunxi/dram_merrii_m2.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_merrii_m2.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 127, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0x0, ++ .tpr4 = 0x0, ++ .tpr5 = 0x0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0x0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_mini_x_a10s.c u-boot-sunxi/board/sunxi/dram_mini_x_a10s.c +--- u-boot-2014.04/board/sunxi/dram_mini_x_a10s.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_mini_x_a10s.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_mk802_a10s.c u-boot-sunxi/board/sunxi/dram_mk802_a10s.c +--- u-boot-2014.04/board/sunxi/dram_mk802_a10s.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_mk802_a10s.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_mk802ii_a20.c u-boot-sunxi/board/sunxi/dram_mk802ii_a20.c +--- u-boot-2014.04/board/sunxi/dram_mk802ii_a20.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_mk802ii_a20.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_olimex_a13_som.c u-boot-sunxi/board/sunxi/dram_olimex_a13_som.c +--- u-boot-2014.04/board/sunxi/dram_olimex_a13_som.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_olimex_a13_som.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,32 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0x10, ++ .emr3 = 0, ++ ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_pov_protab2.c u-boot-sunxi/board/sunxi/dram_pov_protab2.c +--- u-boot-2014.04/board/sunxi/dram_pov_protab2.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_pov_protab2.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_pov_protab2_xxl.c u-boot-sunxi/board/sunxi/dram_pov_protab2_xxl.c +--- u-boot-2014.04/board/sunxi/dram_pov_protab2_xxl.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_pov_protab2_xxl.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_pov_tab_p703.c u-boot-sunxi/board/sunxi/dram_pov_tab_p703.c +--- u-boot-2014.04/board/sunxi/dram_pov_tab_p703.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_pov_tab_p703.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x56b9697b, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_r7dongle.c u-boot-sunxi/board/sunxi/dram_r7dongle.c +--- u-boot-2014.04/board/sunxi/dram_r7dongle.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_r7dongle.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x04, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sanei_n90.c u-boot-sunxi/board/sunxi/dram_sanei_n90.c +--- u-boot-2014.04/board/sunxi/dram_sanei_n90.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sanei_n90.c 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,30 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 456, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 1, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_semitime_g2.c u-boot-sunxi/board/sunxi/dram_semitime_g2.c +--- u-boot-2014.04/board/sunxi/dram_semitime_g2.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_semitime_g2.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 1024, /* in MiB */ ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0x00, ++ .tpr4 = 0x00, ++ .tpr5 = 0x00, ++ .emr1 = 0x00, ++ .emr2 = 0x10, ++ .emr3 = 0x00, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_312_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_312_1024_iow8.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_312_1024_iow8.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_312_1024_iow8.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 312, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_360_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_360_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_360_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow8.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_360_1024_iow8.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_360_1024_iow8.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_360_512.c u-boot-sunxi/board/sunxi/dram_sun4i_360_512.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_360_512.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_360_512.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_384_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun4i_384_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_384_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_384_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_384_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_384_1024_iow8.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_384_1024_iow8.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_384_1024_iow8.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_408_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_408_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_408_1024_iow8.c u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow8.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_408_1024_iow8.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_408_1024_iow8.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun4i_408_512.c u-boot-sunxi/board/sunxi/dram_sun4i_408_512.c +--- u-boot-2014.04/board/sunxi/dram_sun4i_408_512.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun4i_408_512.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun5i_408_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun5i_408_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun5i_408_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun5i_408_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7b, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun5i_408_512_busw16_iow8.c u-boot-sunxi/board/sunxi/dram_sun5i_408_512_busw16_iow8.c +--- u-boot-2014.04/board/sunxi/dram_sun5i_408_512_busw16_iow8.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun5i_408_512_busw16_iow8.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 1, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun5i_432_512_busw16_iow16.c u-boot-sunxi/board/sunxi/dram_sun5i_432_512_busw16_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun5i_432_512_busw16_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun5i_432_512_busw16_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun7i_360_512_busw16_iow16.c u-boot-sunxi/board/sunxi/dram_sun7i_360_512_busw16_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun7i_360_512_busw16_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun7i_360_512_busw16_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 360, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun7i_384_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun7i_384_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun7i_384_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun7i_384_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun7i_384_512_busw16_iow16.c u-boot-sunxi/board/sunxi/dram_sun7i_384_512_busw16_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun7i_384_512_busw16_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun7i_384_512_busw16_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun7i_432_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun7i_432_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun7i_432_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun7i_432_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_sun7i_460_1024_iow16.c u-boot-sunxi/board/sunxi/dram_sun7i_460_1024_iow16.c +--- u-boot-2014.04/board/sunxi/dram_sun7i_460_1024_iow16.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_sun7i_460_1024_iow16.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 480, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0x0, ++ .tpr4 = 0x1, ++ .tpr5 = 0x0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0x0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_wexler_tab_7200.c u-boot-sunxi/board/sunxi/dram_wexler_tab_7200.c +--- u-boot-2014.04/board/sunxi/dram_wexler_tab_7200.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_wexler_tab_7200.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include "common.h" ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 384, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 0x7f, ++ .odt_en = 1, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 1, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_wobo_i5.c u-boot-sunxi/board/sunxi/dram_wobo_i5.c +--- u-boot-2014.04/board/sunxi/dram_wobo_i5.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_wobo_i5.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 9, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x04, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_xzpad700.c u-boot-sunxi/board/sunxi/dram_xzpad700.c +--- u-boot-2014.04/board/sunxi/dram_xzpad700.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_xzpad700.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 408, ++ .type = 3, ++ .rank_num = 1, ++ .density = 4096, ++ .io_width = 16, ++ .bus_width = 16, ++ .cas = 9, ++ .zq = 0x56b9487b, ++ .odt_en = 0, ++ .size = 512, ++ .tpr0 = 0x42d899b7, ++ .tpr1 = 0xa090, ++ .tpr2 = 0x22a00, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0x10, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/dram_zatab.c u-boot-sunxi/board/sunxi/dram_zatab.c +--- u-boot-2014.04/board/sunxi/dram_zatab.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/dram_zatab.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,31 @@ ++/* this file is generated, don't edit it yourself */ ++ ++#include <common.h> ++#include <asm/arch/dram.h> ++ ++static struct dram_para dram_para = { ++ .clock = 432, ++ .type = 3, ++ .rank_num = 1, ++ .density = 2048, ++ .io_width = 8, ++ .bus_width = 32, ++ .cas = 6, ++ .zq = 123, ++ .odt_en = 0, ++ .size = 1024, ++ .tpr0 = 0x30926692, ++ .tpr1 = 0x1090, ++ .tpr2 = 0x1a0c8, ++ .tpr3 = 0, ++ .tpr4 = 0, ++ .tpr5 = 0, ++ .emr1 = 0x4, ++ .emr2 = 0, ++ .emr3 = 0, ++}; ++ ++unsigned long sunxi_dram_init(void) ++{ ++ return dramc_init(&dram_para); ++} +diff -ruN u-boot-2014.04/board/sunxi/gmac.c u-boot-sunxi/board/sunxi/gmac.c +--- u-boot-2014.04/board/sunxi/gmac.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/gmac.c 2014-09-06 16:58:36.165953115 +0200 +@@ -0,0 +1,43 @@ ++#include <common.h> ++#include <netdev.h> ++#include <miiphy.h> ++#include <asm/gpio.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++ ++int sunxi_gmac_initialize(bd_t *bis) ++{ ++ int pin; ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ /* Set up clock gating */ ++ setbits_le32(&ccm->ahb_gate1, 0x1 << AHB_GATE_OFFSET_GMAC); ++ ++ /* Set MII clock */ ++#ifdef CONFIG_RGMII ++ setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII | ++ CCM_GMAC_CTRL_GPIT_RGMII); ++#else ++ setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_MII | ++ CCM_GMAC_CTRL_GPIT_MII); ++#endif ++ ++ /* Configure pin mux settings for GMAC */ ++ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(16); pin++) { ++#ifdef CONFIG_RGMII ++ /* skip unused pins in RGMII mode */ ++ if (pin == SUNXI_GPA(9) || pin == SUNXI_GPA(14)) ++ continue; ++#endif ++ sunxi_gpio_set_cfgpin(pin, SUN7I_GPA0_GMAC); ++ sunxi_gpio_set_drv(pin, 3); ++ } ++ ++#ifdef CONFIG_RGMII ++ return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_RGMII); ++#else ++ return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_MII); ++#endif ++} +diff -ruN u-boot-2014.04/board/sunxi/Makefile u-boot-sunxi/board/sunxi/Makefile +--- u-boot-2014.04/board/sunxi/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/board/sunxi/Makefile 2014-09-06 16:58:36.161953116 +0200 +@@ -0,0 +1,95 @@ ++# ++# (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++# ++# Based on some other board Makefile ++# ++# (C) Copyright 2000-2003 ++# Wolfgang Denk, DENX Software Engineering, wd@denx.de. ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++obj-y += board.o ++obj-$(CONFIG_SUNXI_GMAC) += gmac.o ++obj-$(CONFIG_A10_MID_1GB) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_A10_OLINUXINO_L) += dram_a10_olinuxino_l.o ++obj-$(CONFIG_A10S_OLINUXINO_M) += dram_sun5i_432_512_busw16_iow16.o ++obj-$(CONFIG_A13_OLINUXINO) += dram_a13_olinuxino.o ++obj-$(CONFIG_A13_OLINUXINOM) += dram_a13_oli_micro.o ++obj-$(CONFIG_A13_MID) += dram_sun5i_408_512_busw16_iow8.o ++obj-$(CONFIG_A20_OLINUXINO_L) += dram_a20_olinuxino_l.o ++obj-$(CONFIG_A20_OLINUXINO_L2) += dram_a20_olinuxino_l2.o ++obj-$(CONFIG_A20_OLINUXINO_M) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_A20_SOM) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_AINOL_AW1) += dram_ainol_aw1.o ++obj-$(CONFIG_AMPE_A76) += dram_sun5i_432_512_busw16_iow16.o ++obj-$(CONFIG_AUXTEK_T003) += dram_auxtek_t003.o ++obj-$(CONFIG_AUXTEK_T004) += dram_sun5i_432_512_busw16_iow16.o ++obj-$(CONFIG_BA10_TV_BOX) += dram_sun4i_384_1024_iow8.o ++obj-$(CONFIG_COBY_MID7042) += dram_sun4i_408_1024_iow16.o ++obj-$(CONFIG_COBY_MID8042) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_COBY_MID9742) += dram_sun4i_408_1024_iow16.o ++obj-$(CONFIG_MARSBOARD_A10) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_MARSBOARD_A20) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_CUBIEBOARD) += dram_cubieboard.o ++obj-$(CONFIG_CUBIEBOARD2) += dram_sun7i_460_1024_iow16.o ++obj-$(CONFIG_BANANAPI) += dram_sun7i_432_1024_iow16.o ++obj-$(CONFIG_CUBIETRUCK) += dram_cubietruck.o ++obj-$(CONFIG_DNS_M82) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_EOMA68_A10) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_EOMA68_A20) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_EU3000) += dram_eu3000.o ++obj-$(CONFIG_FORFUN_Q88DB) += dram_forfun_q88db.o ++obj-$(CONFIG_GOOSEBERRY_A721) += dram_gooseberry_a721.o ++obj-$(CONFIG_H6) += dram_h6.o ++obj-$(CONFIG_HACKBERRY) += dram_hackberry.o ++obj-$(CONFIG_HBD_MID_S906) += dram_sun7i_432_1024_iow16.o ++obj-$(CONFIG_HCORE_HC860) += dram_sun4i_384_1024_iow16.o ++obj-$(CONFIG_HYUNDAI_A7) += dram_sun4i_360_512.o ++obj-$(CONFIG_A7HD) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_I12_TVBOX) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_ICOU_FATTY_I) += dram_icou_fatty_i.o ++obj-$(CONFIG_INTERRA3) += dram_mk802ii_a20.o ++obj-$(CONFIG_INET_86VZ) += dram_sun5i_432_512_busw16_iow16.o ++obj-$(CONFIG_INET97F_II) += dram_sun4i_408_512.o ++obj-$(CONFIG_INET_K70HC) += dram_inet_k70hc.o ++obj-$(CONFIG_ITEADA10) += dram_cubieboard.o ++obj-$(CONFIG_ITEADA20) += dram_sun7i_460_1024_iow16.o ++obj-$(CONFIG_JESURUN_Q5) += dram_sun4i_312_1024_iow8.o ++obj-$(CONFIG_K1001L1C) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_KURIO_7S) += dram_sun7i_432_1024_iow16.o ++obj-$(CONFIG_LANGCENT_H6S) += dram_sun7i_360_512_busw16_iow16.o ++obj-$(CONFIG_LINKSPRITE_PCDUINO3) += dram_linksprite_pcduino3.o ++obj-$(CONFIG_MEFAFEIS_A08) += dram_megafeis_a08.o ++obj-$(CONFIG_MELE_A1000) += dram_sun4i_360_512.o ++obj-$(CONFIG_MELE_A1000G) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_MELE_A3700) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_MERRII_HUMMINGBIRD_A20) += dram_sun7i_460_1024_iow16.o ++obj-$(CONFIG_MINI_X) += dram_sun4i_360_512.o ++obj-$(CONFIG_MINI_X_1GB) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_MINI_X_A10S) += dram_mini_x_a10s.o ++obj-$(CONFIG_MK802) += dram_sun4i_360_512.o ++obj-$(CONFIG_MK802_1GB) += dram_sun4i_360_1024_iow16.o ++obj-$(CONFIG_MK802_A10S) += dram_mk802_a10s.o ++obj-$(CONFIG_MK802II) += dram_sun4i_408_1024_iow8.o ++obj-$(CONFIG_MK802II_A20) += dram_mk802ii_a20.o ++obj-$(CONFIG_MK808C_A20) += dram_sun7i_384_1024_iow16.o ++obj-$(CONFIG_OLIMEX_A13_SOM) += dram_olimex_a13_som.o ++obj-$(CONFIG_PCDUINO) += dram_sun4i_408_1024_iow8.o ++obj-$(CONFIG_PENGPOD700) += dram_sun4i_384_1024_iow8.o ++obj-$(CONFIG_PENGPOD1000) += dram_sun4i_408_1024_iow16.o ++obj-$(CONFIG_PINERIVER-H25) += dram_sun5i_408_1024_iow16.o ++obj-$(CONFIG_POV_TAB_P703) += dram_pov_tab_p703.o ++obj-$(CONFIG_POV_PROTAB2) += dram_pov_protab2.o ++obj-$(CONFIG_POV_PROTAB2_XXL) += dram_pov_protab2_xxl.o ++obj-$(CONFIG_QT840A) += dram_sun7i_384_512_busw16_iow16.o ++obj-$(CONFIG_R7DONGLE) += dram_r7dongle.o ++obj-$(CONFIG_SANEI_N90) += dram_sanei_n90.o ++obj-$(CONFIG_SEMITIME_G2) += dram_semitime_g2.o ++obj-$(CONFIG_TZX_Q8_713B6) += dram_sun5i_408_512_busw16_iow8.o ++obj-$(CONFIG_TZX_Q8_713B7) += dram_sun5i_408_512_busw16_iow8.o ++obj-$(CONFIG_UHOST_U1A) += dram_sun4i_360_1024_iow8.o ++obj-$(CONFIG_WEXLER_TAB_7200) += dram_wexler_tab_7200.o ++obj-$(CONFIG_WOBO_I5) += dram_wobo_i5.o ++obj-$(CONFIG_XZPAD700) += dram_xzpad700.o ++obj-$(CONFIG_ZATAB) += dram_zatab.o ++obj-$(CONFIG_MERRII_M2) += dram_merrii_m2.o +diff -ruN u-boot-2014.04/boards.cfg u-boot-sunxi/boards.cfg +--- u-boot-2014.04/boards.cfg 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/boards.cfg 2014-09-06 16:58:36.185953115 +0200 +@@ -371,6 +371,111 @@ + Active arm armv7 s5pc1xx samsung goni s5p_goni - Mateusz Zalega m.zalega@samsung.com + Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang mk7.kang@samsung.com + Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - - ++Active arm armv7 sunxi - sunxi A10_MID_1GB sun4i:A10_MID_1GB,SPL - ++Active arm armv7 sunxi - sunxi A10-OLinuXino-Lime sun4i:A10_OLINUXINO_L,STATUSLED=226,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A10s-OLinuXino-M sun5i:A10S_OLINUXINO_M,STATUSLED=131,AXP152_POWER,CONS_INDEX=1,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A10s-OLinuXino-M_FEL sun5i:A10S_OLINUXINO_M,STATUSLED=131,AXP152_POWER,CONS_INDEX=1,SPL_FEL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A13-OLinuXino sun5i:A13_OLINUXINO,SPL,STATUSLED=201,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi A13-OLinuXino_FEL sun5i:A13_OLINUXINO,SPL_FEL,STATUSLED=201,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi A13-OLinuXino_FEL_sdcon sun5i:A13_OLINUXINO,SPL_FEL,STATUSLED=201,UART0_PORT_F - ++Active arm armv7 sunxi - sunxi A13-OLinuXinoM sun5i:A13_OLINUXINOM,SPL,NO_AXP,STATUSLED=201,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi A13-OLinuXinoM_FEL sun5i:A13_OLINUXINOM,SPL_FEL,NO_AXP,STATUSLED=201,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi A13_MID sun5i:A13_MID,SPL,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi A20-OLinuXino_Lime sun7i:A20_OLINUXINO_L,CONS_INDEX=1,STATUSLED=226,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A20-OLinuXino_Lime2 sun7i:A20_OLINUXINO_L2,CONS_INDEX=1,STATUSLED=226,SPL,SUNXI_GMAC - ++Active arm armv7 sunxi - sunxi A20-OLinuXino_MICRO sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A20-OLinuXino_MICRO_FEL sun7i:A20_OLINUXINO_M,CONS_INDEX=1,STATUSLED=226,SPL_FEL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi A20-SOM sun7i:A20_SOM,SPL,SUNXI_GMAC,RGMII,STATUSLED1=245,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Ainol_AW1 sun7i:AINOL_AW1,SPL - ++Active arm armv7 sunxi - sunxi Ampe_A76 sun5i:AMPE_A76,SPL,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi Auxtek-T003 sun5i:AUXTEK_T003,SPL,AXP152_POWER,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi Auxtek-T004 sun5i:AUXTEK_T004,SPL,AXP152_POWER,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi ba10_tv_box sun4i:BA10_TV_BOX,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi Bananapi sun7i:BANANAPI,SPL,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),STATUSLED=244,STATUSLED1=245,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Bananapi_FEL sun7i:BANANAPI,SPL_FEL,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),STATUSLED=244,STATUSLED1=245,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Coby_MID7042 sun4i:COBY_MID7042,SPL - ++Active arm armv7 sunxi - sunxi Coby_MID8042 sun4i:COBY_MID8042,SPL - ++Active arm armv7 sunxi - sunxi Coby_MID9742 sun4i:COBY_MID9742,SPL - ++Active arm armv7 sunxi - sunxi Iteaduino_Plus_A10 sun4i:ITEADA10,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245 - ++Active arm armv7 sunxi - sunxi Iteaduino_Plus_A20 sun7i:ITEADA20,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245 - ++Active arm armv7 sunxi - sunxi Colombus sun6i:COLOMBUS,AXP221_POWER,ENABLE_DLDO1_POWER - ++Active arm armv7 sunxi - sunxi Ippo_q8h sun8i:IPPO_Q8H,NO_AXP,CONS_INDEX=5 - ++Active arm armv7 sunxi - sunxi Cubieboard sun4i:CUBIEBOARD,SPL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245 - ++Active arm armv7 sunxi - sunxi Cubieboard2 sun7i:CUBIEBOARD2,SPL,SUNXI_GMAC,STATUSLED=244,STATUSLED1=245,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Cubieboard2_FEL sun7i:CUBIEBOARD2,SPL_FEL,SUNXI_GMAC,STATUSLED=244,STATUSLED1=245,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII,STATUSLED=245,STATUSLED1=244,STATUSLED2=235,STATUSLED3=231,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII,STATUSLED=245,STATUSLED1=244,STATUSLED2=235,STATUSLED3=231,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Cubieboard_FEL sun4i:CUBIEBOARD,SPL_FEL,SUNXI_EMAC,STATUSLED=244,STATUSLED1=245 - ++Active arm armv7 sunxi - sunxi DNS_M82 sun4i:DNS_M82,SPL - ++Active arm armv7 sunxi - sunxi EOMA68_A10 sun4i:EOMA68_A10,SPL,MMC_SUNXI_SLOT=3,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi EOMA68_A10_FEL sun4i:EOMA68_A10,SPL_FEL,MMC_SUNXI_SLOT=3,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi EOMA68_A20 sun7i:EOMA68_A20,SPL,MMC_SUNXI_SLOT=3,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi EOMA68_A20_FEL sun7i:EOMA68_A20,SPL_FEL,MMC_SUNXI_SLOT=3,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi EU3000 sun7i:EU3000,SPL - ++Active arm armv7 sunxi - sunxi Forfun_Q88DB sun7i:FORFUN_Q88DB,SPL - ++Active arm armv7 sunxi - sunxi Gooseberry_A721 sun4i:GOOSEBERRY_A721,SPL - ++Active arm armv7 sunxi - sunxi H6 sun4i:H6,SPL - ++Active arm armv7 sunxi - sunxi Hackberry sun4i:HACKBERRY,SPL,SUNXI_EMAC,MACPWR=SUNXI_GPH(19) - ++Active arm armv7 sunxi - sunxi HBD_MID_S906 sun7i:HBD_MID_S906,SPL - ++Active arm armv7 sunxi - sunxi HCore_HC860 sun4i:HCORE_HC860,SPL - ++Active arm armv7 sunxi - sunxi Hyundai_A7 sun4i:HYUNDAI_A7,SPL - ++Active arm armv7 sunxi - sunxi Hyundai_A7HD sun4i:A7HD,SPL - ++Active arm armv7 sunxi - sunxi i12-tvbox sun7i:I12_TVBOX,SPL,FAST_MBUS,STATUSLED=244 - ++Active arm armv7 sunxi - sunxi ICOU_Fatty_I sun7i:ICOU_FATTY_I,SPL - ++Active arm armv7 sunxi - sunxi Interra-3 sun7i:INTERRA3,SPL,SUNXI_GMAC,FAST_MBUS,MMC_SUNXI_SLOT=2 - ++Active arm armv7 sunxi - sunxi INet_86VZ sun5i:INET_86VZ,SPL - ++Active arm armv7 sunxi - sunxi INet_86VZ_FEL sun5i:INET_86VZ,SPL_FEL,UART0_PORT_F - ++Active arm armv7 sunxi - sunxi INet97F-II sun4i:INET97F_II,SPL - ++Active arm armv7 sunxi - sunxi INet_K70HC sun7i:INET_K70HC,SPL - ++Active arm armv7 sunxi - sunxi Jesurun-Q5 sun4i:JESURUN_Q5,SPL,SUNXI_EMAC,STATUSLED=244 - ++Active arm armv7 sunxi - sunxi K1001L1C sun7i:K1001L1C,SPL - ++Active arm armv7 sunxi - sunxi Kurio_7S sun7i:KURIO_7S,SPL - ++Active arm armv7 sunxi - sunxi Langcent_H6S sun7i:LANGCENT_H6S,SPL - ++Active arm armv7 sunxi - sunxi Linksprite_pcDuino3 sun7i:LINKSPRITE_PCDUINO3,SPL,SUNXI_GMAC,FAST_MBUS - ++Active arm armv7 sunxi - sunxi Marsboard_A10 sun4i:MARSBOARD_A10,SPL,SUNXI_EMAC,NO_AXP - ++Active arm armv7 sunxi - sunxi Marsboard_A20 sun7i:MARSBOARD_A20,SPL,SUNXI_EMAC,NO_AXP - ++Active arm armv7 sunxi - sunxi Marsboard_A20_debug sun7i:MARSBOARD_A20,SPL,SUNXI_EMAC,NO_AXP,SYS_SECONDARY_ON - ++Active arm armv7 sunxi - sunxi Megafeis_A08 sun5i:MEFAFEIS_A08,SPL - ++Active arm armv7 sunxi - sunxi Mele_A1000 sun4i:MELE_A1000,SPL,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),STATUSLED=234 - ++Active arm armv7 sunxi - sunxi Mele_A1000_FEL sun4i:MELE_A1000,SPL_FEL,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),STATUSLED=234 - ++Active arm armv7 sunxi - sunxi Mele_A1000G sun4i:MELE_A1000G,SPL,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),STATUSLED=234 - ++Active arm armv7 sunxi - sunxi Mele_A3700 sun4i:MELE_A3700,SPL,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),STATUSLED=234 - ++Active arm armv7 sunxi - sunxi Merrii_Hummingbird_A20 sun7i:MERRII_HUMMINGBIRD_A20,SPL - ++Active arm armv7 sunxi - sunxi merrii_m2 sun7i:MERRII_M2,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi Mini-X sun4i:MINI_X,SPL - ++Active arm armv7 sunxi - sunxi Mini-X-1Gb sun4i:MINI_X_1GB,SPL - ++Active arm armv7 sunxi - sunxi Mini-X_A10s sun5i:MINI_X_A10S,SPL - ++Active arm armv7 sunxi - sunxi mk802 sun4i:MK802,SPL,NO_AXP - ++Active arm armv7 sunxi - sunxi mk802-1gb sun4i:MK802_1GB,SPL,NO_AXP - ++Active arm armv7 sunxi - sunxi mk802_a10s sun5i:MK802_A10S,SPL,AXP152_POWER,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi mk802ii_A20 sun7i:MK802II_A20,SPL - ++Active arm armv7 sunxi - sunxi mk802ii sun4i:MK802II,SPL - ++Active arm armv7 sunxi - sunxi mk808c_A20 sun7i:MK808C_A20,SPL - ++Active arm armv7 sunxi - sunxi OLIMEX-A13-SOM sun5i:OLIMEX_A13_SOM,SPL,NO_AXP,STATUSLED=201,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi pcDuino sun4i:PCDUINO,SPL,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi pengpod1000 sun4i:PENGPOD1000,SPL - ++Active arm armv7 sunxi - sunxi pengpod700 sun4i:PENGPOD700,SPL - ++Active arm armv7 suxni - sunxi pineriver-h25 sun5i:PINERIVER-H25,SPL ++Active arm armv7 sunxi - sunxi POV_TAB_P703 sun5i:POV_TAB_P703,SPL - ++Active arm armv7 sunxi - sunxi PoV_ProTab2_IPS9 sun4i:POV_PROTAB2,SPL - ++Active arm armv7 sunxi - sunxi PoV_ProTab2_IPS_3g sun4i:POV_PROTAB2,SPL - ++Active arm armv7 sunxi - sunxi PoV_ProTab2_XXL sun4i:POV_PROTAB2_XXL,SPL - ++Active arm armv7 sunxi - sunxi qt840a sun7i:QT840A,SPL,FAST_MBUS,STATUSLED=244 - ++Active arm armv7 sunxi - sunxi r7-tv-dongle sun5i:R7DONGLE,SPL,AXP152_POWER,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi Sanei_N90 sun4i:SANEI_N90,SPL - ++Active arm armv7 sunxi - sunxi Semitime_G2 sun5i:SEMITIME_G2,SPL,AXP152_POWER,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi sun4i sun4i:SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi sun4i_sdcon sun4i:UART0_PORT_F,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi sun5i sun5i:SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi sun5i_sdcon sun5i:UART0_PORT_F,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi sun5i_uart1 sun5i:CONS_INDEX=2,SUNXI_EMAC - ++Active arm armv7 sunxi - sunxi TZX-Q8-713B6 sun5i:TZX_Q8_713B6,SPL,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi TZX-Q8-713B7 sun5i:TZX_Q8_713B7,SPL,CONS_INDEX=2 - ++Active arm armv7 sunxi - sunxi uhost_u1a sun4i:UHOST_U1A,SPL,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi Wexler_TAB_7200 sun7i:WEXLER_TAB_7200,SPL - ++Active arm armv7 sunxi - sunxi wobo-i5 sun5i:WOBO_I5,SPL,STATUSLED=34 - ++Active arm armv7 sunxi - sunxi xzpad700 sun5i:XZPAD700,SPL - ++Active arm armv7 sunxi - sunxi zatab sun4i:ZATAB,SPL - + Active arm armv7 u8500 st-ericsson snowball snowball - Mathieu Poirier mathieu.poirier@linaro.org + Active arm armv7 u8500 st-ericsson u8500 u8500_href - - + Active arm armv7 vf610 freescale vf610twr vf610twr vf610twr:IMX_CONFIG=board/freescale/vf610twr/imximage.cfg Alison Wang b18965@freescale.com +diff -ruN u-boot-2014.04/common/spl/spl_mmc.c u-boot-sunxi/common/spl/spl_mmc.c +--- u-boot-2014.04/common/spl/spl_mmc.c 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/common/spl/spl_mmc.c 2014-09-06 16:58:36.205953114 +0200 +@@ -29,8 +29,10 @@ + if (err == 0) + goto end; + +- if (image_get_magic(header) != IH_MAGIC) ++ if (image_get_magic(header) != IH_MAGIC) { ++ printf("spl: not an uImage at %lu\n", sector); + return -1; ++ } + + spl_parse_image_header(header); + +diff -ruN u-boot-2014.04/drivers/gpio/Makefile u-boot-sunxi/drivers/gpio/Makefile +--- u-boot-2014.04/drivers/gpio/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/gpio/Makefile 2014-09-06 16:58:36.253953113 +0200 +@@ -34,3 +34,4 @@ + obj-$(CONFIG_ADI_GPIO2) += adi_gpio2.o + obj-$(CONFIG_TCA642X) += tca642x.o + oby-$(CONFIG_SX151X) += sx151x.o ++obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o +diff -ruN u-boot-2014.04/drivers/gpio/sunxi_gpio.c u-boot-sunxi/drivers/gpio/sunxi_gpio.c +--- u-boot-2014.04/drivers/gpio/sunxi_gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/gpio/sunxi_gpio.c 2014-09-06 16:58:36.253953113 +0200 +@@ -0,0 +1,102 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * Based on earlier arch/arm/cpu/armv7/sunxi/gpio.c: ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/gpio.h> ++ ++static int sunxi_gpio_output(u32 pin, u32 val) ++{ ++ u32 dat; ++ u32 bank = GPIO_BANK(pin); ++ u32 num = GPIO_NUM(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ dat = readl(&pio->dat); ++ if (val) ++ dat |= 0x1 << num; ++ else ++ dat &= ~(0x1 << num); ++ ++ writel(dat, &pio->dat); ++ ++ return 0; ++} ++ ++static int sunxi_gpio_input(u32 pin) ++{ ++ u32 dat; ++ u32 bank = GPIO_BANK(pin); ++ u32 num = GPIO_NUM(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ dat = readl(&pio->dat); ++ dat >>= num; ++ ++ return dat & 0x1; ++} ++ ++int gpio_request(unsigned gpio, const char *label) ++{ ++ return 0; ++} ++ ++int gpio_free(unsigned gpio) ++{ ++ return 0; ++} ++ ++int gpio_direction_input(unsigned gpio) ++{ ++ sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT); ++ ++ return sunxi_gpio_input(gpio); ++} ++ ++int gpio_direction_output(unsigned gpio, int value) ++{ ++ sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT); ++ ++ return sunxi_gpio_output(gpio, value); ++} ++ ++int gpio_get_value(unsigned gpio) ++{ ++ return sunxi_gpio_input(gpio); ++} ++ ++int gpio_set_value(unsigned gpio, int value) ++{ ++ return sunxi_gpio_output(gpio, value); ++} ++ ++int sunxi_name_to_gpio(const char *name) ++{ ++ int group = 0; ++ int groupsize = 9 * 32; ++ long pin; ++ char *eptr; ++ if (*name == 'P' || *name == 'p') ++ name++; ++ if (*name >= 'A') { ++ group = *name - (*name > 'a' ? 'a' : 'A'); ++ groupsize = 32; ++ name++; ++ } ++ ++ pin = simple_strtol(name, &eptr, 10); ++ if (!*name || *eptr) ++ return -1; ++ if (pin < 0 || pin > groupsize || group >= 9) ++ return -1; ++ return group * 32 + pin; ++} +diff -ruN u-boot-2014.04/drivers/i2c/Makefile u-boot-sunxi/drivers/i2c/Makefile +--- u-boot-2014.04/drivers/i2c/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/i2c/Makefile 2014-09-06 16:58:36.265953112 +0200 +@@ -27,5 +27,6 @@ + obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o + obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o + obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o ++obj-$(CONFIG_SYS_I2C_SUNXI) += mvtwsi.o + obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o + obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o +diff -ruN u-boot-2014.04/drivers/i2c/mvtwsi.c u-boot-sunxi/drivers/i2c/mvtwsi.c +--- u-boot-2014.04/drivers/i2c/mvtwsi.c 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/i2c/mvtwsi.c 2014-09-06 16:58:36.265953112 +0200 +@@ -22,6 +22,8 @@ + #include <asm/arch/orion5x.h> + #elif defined(CONFIG_KIRKWOOD) + #include <asm/arch/kirkwood.h> ++#elif defined(CONFIG_SUNXI) ++#include <asm/arch/i2c.h> + #else + #error Driver mvtwsi not supported by SoC or board + #endif +@@ -30,6 +32,20 @@ + * TWSI register structure + */ + ++#ifdef CONFIG_SUNXI ++ ++struct mvtwsi_registers { ++ u32 slave_address; ++ u32 xtnd_slave_addr; ++ u32 data; ++ u32 control; ++ u32 status; ++ u32 baudrate; ++ u32 soft_reset; ++}; ++ ++#else ++ + struct mvtwsi_registers { + u32 slave_address; + u32 data; +@@ -43,6 +59,8 @@ + u32 soft_reset; + }; + ++#endif ++ + /* + * Control register fields + */ +@@ -216,21 +234,7 @@ + */ + + #define TWSI_FREQUENCY(m, n) \ +- ((u8) (CONFIG_SYS_TCLK / (10 * (m + 1) * 2 * (1 << n)))) +- +-/* +- * These are required to be reprogrammed before enabling the controller +- * because a reset loses them. +- * Default values come from the spec, but a twsi_reset will change them. +- * twsi_slave_address left uninitialized lest checkpatch.pl complains. +- */ +- +-/* Baudrate generator: m (bits 7..4) =4, n (bits 3..0) =4 */ +-static u8 twsi_baud_rate = 0x44; /* baudrate at controller reset */ +-/* Default frequency corresponding to default m=4, n=4 */ +-static u8 twsi_actual_speed = TWSI_FREQUENCY(4, 4); +-/* Default slave address is 0 (so is an uninitialized static) */ +-static u8 twsi_slave_address; ++ (CONFIG_SYS_TCLK / (10 * (m + 1) * (1 << n))) + + /* + * Reset controller. +@@ -238,7 +242,7 @@ + * Controller reset also resets the baud rate and slave address, so + * re-establish them. + */ +-static void twsi_reset(void) ++static void twsi_reset(u8 baud_rate, u8 slave_address) + { + /* ensure controller will be enabled by any twsi*() function */ + twsi_control_flags = MVTWSI_CONTROL_TWSIEN; +@@ -247,9 +251,9 @@ + /* wait 2 ms -- this is what the Marvell LSP does */ + udelay(20000); + /* set baud rate */ +- writel(twsi_baud_rate, &twsi->baudrate); ++ writel(baud_rate, &twsi->baudrate); + /* set slave address even though we don't use it */ +- writel(twsi_slave_address, &twsi->slave_address); ++ writel(slave_address, &twsi->slave_address); + writel(0, &twsi->xtnd_slave_addr); + /* assert STOP but don't care for the result */ + (void) twsi_stop(0); +@@ -277,12 +281,8 @@ + } + } + } +- /* save baud rate and slave for later calls to twsi_reset */ +- twsi_baud_rate = baud; +- twsi_actual_speed = highest_speed; +- twsi_slave_address = slaveadd; + /* reset controller */ +- twsi_reset(); ++ twsi_reset(baud, slaveadd); + } + + /* +diff -ruN u-boot-2014.04/drivers/mmc/Makefile u-boot-sunxi/drivers/mmc/Makefile +--- u-boot-2014.04/drivers/mmc/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/mmc/Makefile 2014-09-06 16:58:36.281953112 +0200 +@@ -28,6 +28,7 @@ + obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o + obj-$(CONFIG_DWMMC) += dw_mmc.o + obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o ++obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o + obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o + obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o + ifdef CONFIG_SPL_BUILD +diff -ruN u-boot-2014.04/drivers/mmc/sunxi_mmc.c u-boot-sunxi/drivers/mmc/sunxi_mmc.c +--- u-boot-2014.04/drivers/mmc/sunxi_mmc.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/mmc/sunxi_mmc.c 2014-09-06 16:58:36.281953112 +0200 +@@ -0,0 +1,385 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Aaron leafy.myeh@allwinnertech.com ++ * ++ * MMC driver for allwinner sunxi platform. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <malloc.h> ++#include <mmc.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/cpu.h> ++#include <asm/arch/mmc.h> ++ ++struct sunxi_mmc_host { ++ unsigned mmc_no; ++ uint32_t *mclkreg; ++ unsigned database; ++ unsigned fatal_err; ++ unsigned mod_clk; ++ struct sunxi_mmc *reg; ++ struct mmc_config cfg; ++}; ++ ++/* support 4 mmc hosts */ ++struct sunxi_mmc_host mmc_host[4]; ++ ++static int mmc_resource_init(int sdc_no) ++{ ++ struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; ++ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ debug("init mmc %d resource\n", sdc_no); ++ ++ switch (sdc_no) { ++ case 0: ++ mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE; ++ mmchost->mclkreg = &ccm->sd0_clk_cfg; ++ break; ++ case 1: ++ mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE; ++ mmchost->mclkreg = &ccm->sd1_clk_cfg; ++ break; ++ case 2: ++ mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE; ++ mmchost->mclkreg = &ccm->sd2_clk_cfg; ++ break; ++ case 3: ++ mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE; ++ mmchost->mclkreg = &ccm->sd3_clk_cfg; ++ break; ++ default: ++ printf("Wrong mmc number %d\n", sdc_no); ++ return -1; ++ } ++#ifdef CONFIG_SUN6I ++ mmchost->database = (unsigned int)mmchost->reg + 0x200; ++#else ++ mmchost->database = (unsigned int)mmchost->reg + 0x100; ++#endif ++ mmchost->mmc_no = sdc_no; ++ ++ return 0; ++} ++ ++static int mmc_clk_io_on(int sdc_no) ++{ ++ unsigned int pll_clk; ++ unsigned int divider; ++ struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; ++ struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ debug("init mmc %d clock and io\n", sdc_no); ++ ++ /* config ahb clock */ ++ setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); ++ ++#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN8I) ++ /* unassert reset */ ++ setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no)); ++#endif ++ ++ /* config mod clock */ ++ pll_clk = clock_get_pll6(); ++ /* should be close to 100 MHz but no more, so round up */ ++ divider = ((pll_clk + 99999999) / 100000000) - 1; ++ writel(CCM_MMC_CTRL_ENABLE | CCM_MMC_CTRL_PLL6 | divider, ++ mmchost->mclkreg); ++ mmchost->mod_clk = pll_clk / (divider + 1); ++ ++ return 0; ++} ++ ++static int mmc_update_clk(struct mmc *mmc) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ unsigned int cmd; ++ unsigned timeout_msecs = 2000; ++ ++ cmd = SUNXI_MMC_CMD_START | ++ SUNXI_MMC_CMD_UPCLK_ONLY | ++ SUNXI_MMC_CMD_WAIT_PRE_OVER; ++ writel(cmd, &mmchost->reg->cmd); ++ while (readl(&mmchost->reg->cmd) & SUNXI_MMC_CMD_START) { ++ if (!timeout_msecs--) ++ return -1; ++ udelay(1000); ++ } ++ ++ /* clock update sets various irq status bits, clear these */ ++ writel(readl(&mmchost->reg->rint), &mmchost->reg->rint); ++ ++ return 0; ++} ++ ++static int mmc_config_clock(struct mmc *mmc, unsigned div) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ unsigned rval = readl(&mmchost->reg->clkcr); ++ ++ /* Disable Clock */ ++ rval &= ~SUNXI_MMC_CLK_ENABLE; ++ writel(rval, &mmchost->reg->clkcr); ++ if (mmc_update_clk(mmc)) ++ return -1; ++ ++ /* Change Divider Factor */ ++ rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK; ++ rval |= div; ++ writel(rval, &mmchost->reg->clkcr); ++ if (mmc_update_clk(mmc)) ++ return -1; ++ /* Re-enable Clock */ ++ rval |= SUNXI_MMC_CLK_ENABLE; ++ writel(rval, &mmchost->reg->clkcr); ++ ++ if (mmc_update_clk(mmc)) ++ return -1; ++ ++ return 0; ++} ++ ++static void mmc_set_ios(struct mmc *mmc) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ unsigned int clkdiv = 0; ++ ++ debug("set ios: bus_width: %x, clock: %d, mod_clk: %d\n", ++ mmc->bus_width, mmc->clock, mmchost->mod_clk); ++ ++ /* Change clock first */ ++ clkdiv = (mmchost->mod_clk + (mmc->clock >> 1)) / mmc->clock / 2; ++ if (mmc->clock) { ++ if (mmc_config_clock(mmc, clkdiv)) { ++ mmchost->fatal_err = 1; ++ return; ++ } ++ } ++ ++ /* Change bus width */ ++ if (mmc->bus_width == 8) ++ writel(0x2, &mmchost->reg->width); ++ else if (mmc->bus_width == 4) ++ writel(0x1, &mmchost->reg->width); ++ else ++ writel(0x0, &mmchost->reg->width); ++} ++ ++static int mmc_core_init(struct mmc *mmc) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ ++ /* Reset controller */ ++ writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); ++ udelay(1000); ++ ++ return 0; ++} ++ ++static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ const int reading = !!(data->flags & MMC_DATA_READ); ++ const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY : ++ SUNXI_MMC_STATUS_FIFO_FULL; ++ unsigned i; ++ unsigned byte_cnt = data->blocksize * data->blocks; ++ unsigned timeout_msecs = 2000; ++ unsigned *buff = (unsigned int *)(reading ? data->dest : data->src); ++ ++ /* Always read / write data through the CPU */ ++ setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB); ++ ++ for (i = 0; i < (byte_cnt >> 2); i++) { ++ while (readl(&mmchost->reg->status) & status_bit) { ++ if (!timeout_msecs--) ++ return -1; ++ udelay(1000); ++ } ++ ++ if (reading) ++ buff[i] = readl(mmchost->database); ++ else ++ writel(buff[i], mmchost->database); ++ } ++ ++ return 0; ++} ++ ++static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, ++ unsigned int done_bit, const char *what) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ unsigned int status; ++ ++ do { ++ status = readl(&mmchost->reg->rint); ++ if (!timeout_msecs-- || ++ (status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) { ++ debug("%s timeout %x\n", what, ++ status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT); ++ return TIMEOUT; ++ } ++ udelay(1000); ++ } while (!(status & done_bit)); ++ ++ return 0; ++} ++ ++static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, ++ struct mmc_data *data) ++{ ++ struct sunxi_mmc_host *mmchost = mmc->priv; ++ unsigned int cmdval = SUNXI_MMC_CMD_START; ++ unsigned int timeout_msecs; ++ int error = 0; ++ unsigned int status = 0; ++ unsigned int bytecnt = 0; ++ ++ if (mmchost->fatal_err) ++ return -1; ++ if (cmd->resp_type & MMC_RSP_BUSY) ++ debug("mmc cmd %d check rsp busy\n", cmd->cmdidx); ++ if (cmd->cmdidx == 12) ++ return 0; ++ ++ if (!cmd->cmdidx) ++ cmdval |= SUNXI_MMC_CMD_SEND_INIT_SEQ; ++ if (cmd->resp_type & MMC_RSP_PRESENT) ++ cmdval |= SUNXI_MMC_CMD_RESP_EXPIRE; ++ if (cmd->resp_type & MMC_RSP_136) ++ cmdval |= SUNXI_MMC_CMD_LONG_RESPONSE; ++ if (cmd->resp_type & MMC_RSP_CRC) ++ cmdval |= SUNXI_MMC_CMD_CHK_RESPONSE_CRC; ++ ++ if (data) { ++ if ((u32) data->dest & 0x3) { ++ error = -1; ++ goto out; ++ } ++ ++ cmdval |= SUNXI_MMC_CMD_DATA_EXPIRE|SUNXI_MMC_CMD_WAIT_PRE_OVER; ++ if (data->flags & MMC_DATA_WRITE) ++ cmdval |= SUNXI_MMC_CMD_WRITE; ++ if (data->blocks > 1) ++ cmdval |= SUNXI_MMC_CMD_AUTO_STOP; ++ writel(data->blocksize, &mmchost->reg->blksz); ++ writel(data->blocks * data->blocksize, &mmchost->reg->bytecnt); ++ } ++ ++ debug("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", mmchost->mmc_no, ++ cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg); ++ writel(cmd->cmdarg, &mmchost->reg->arg); ++ ++ if (!data) ++ writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); ++ ++ /* ++ * transfer data and check status ++ * STATREG[2] : FIFO empty ++ * STATREG[3] : FIFO full ++ */ ++ if (data) { ++ int ret = 0; ++ ++ bytecnt = data->blocksize * data->blocks; ++ debug("trans data %d bytes\n", bytecnt); ++ writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); ++ ret = mmc_trans_data_by_cpu(mmc, data); ++ if (ret) { ++ error = readl(&mmchost->reg->rint) & \ ++ SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT; ++ error = TIMEOUT; ++ goto out; ++ } ++ } ++ ++ error = mmc_rint_wait(mmc, 0xfffff, SUNXI_MMC_RINT_COMMAND_DONE, "cmd"); ++ if (error) ++ goto out; ++ ++ if (data) { ++ timeout_msecs = 120; ++ debug("cacl timeout %x msec\n", timeout_msecs); ++ error = mmc_rint_wait(mmc, timeout_msecs, ++ data->blocks > 1 ? ++ SUNXI_MMC_RINT_AUTO_COMMAND_DONE : ++ SUNXI_MMC_RINT_DATA_OVER, ++ "data"); ++ if (error) ++ goto out; ++ } ++ ++ if (cmd->resp_type & MMC_RSP_BUSY) { ++ timeout_msecs = 2000; ++ do { ++ status = readl(&mmchost->reg->status); ++ if (!timeout_msecs--) { ++ debug("busy timeout\n"); ++ error = TIMEOUT; ++ goto out; ++ } ++ udelay(1000); ++ } while (status & SUNXI_MMC_STATUS_CARD_DATA_BUSY); ++ } ++ ++ if (cmd->resp_type & MMC_RSP_136) { ++ cmd->response[0] = readl(&mmchost->reg->resp3); ++ cmd->response[1] = readl(&mmchost->reg->resp2); ++ cmd->response[2] = readl(&mmchost->reg->resp1); ++ cmd->response[3] = readl(&mmchost->reg->resp0); ++ debug("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n", ++ cmd->response[3], cmd->response[2], ++ cmd->response[1], cmd->response[0]); ++ } else { ++ cmd->response[0] = readl(&mmchost->reg->resp0); ++ debug("mmc resp 0x%08x\n", cmd->response[0]); ++ } ++out: ++ if (error < 0) { ++ writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); ++ mmc_update_clk(mmc); ++ } ++ writel(0xffffffff, &mmchost->reg->rint); ++ writel(readl(&mmchost->reg->gctrl) | SUNXI_MMC_GCTRL_FIFO_RESET, ++ &mmchost->reg->gctrl); ++ ++ return error; ++} ++ ++static const struct mmc_ops sunxi_mmc_ops = { ++ .send_cmd = mmc_send_cmd, ++ .set_ios = mmc_set_ios, ++ .init = mmc_core_init, ++}; ++ ++int sunxi_mmc_init(int sdc_no) ++{ ++ struct mmc_config *cfg = &mmc_host[sdc_no].cfg; ++ ++ memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host)); ++ ++ cfg->name = "SUNXI SD/MMC"; ++ cfg->ops = &sunxi_mmc_ops; ++ ++ cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; ++ cfg->host_caps = MMC_MODE_4BIT; ++ cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; ++ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; ++ ++ cfg->f_min = 400000; ++ cfg->f_max = 52000000; ++ ++ mmc_resource_init(sdc_no); ++ mmc_clk_io_on(sdc_no); ++ ++ if (mmc_create(cfg, &mmc_host[sdc_no]) == NULL) ++ return -1; ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/drivers/net/designware.c u-boot-sunxi/drivers/net/designware.c +--- u-boot-2014.04/drivers/net/designware.c 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/net/designware.c 2014-09-06 16:58:36.301953111 +0200 +@@ -249,7 +249,7 @@ + rx_descs_init(dev); + tx_descs_init(dev); + +- writel(FIXEDBURST | PRIORXTX_41 | BURST_16, &dma_p->busmode); ++ writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode); + + writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD, + &dma_p->opmode); +@@ -280,10 +280,18 @@ + u32 desc_num = priv->tx_currdescnum; + struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num]; + +- /* Invalidate only "status" field for the following check */ +- invalidate_dcache_range((unsigned long)&desc_p->txrx_status, +- (unsigned long)&desc_p->txrx_status + +- sizeof(desc_p->txrx_status)); ++ /* ++ * Strictly we only need to invalidate the "txrx_status" field ++ * for the following check, but on some platforms we cannot ++ * invalidate only 4 bytes, so roundup to ++ * ARCH_DMA_MINALIGN. This is safe because the individual ++ * descriptors in the array are each aligned to ++ * ARCH_DMA_MINALIGN. ++ */ ++ invalidate_dcache_range( ++ (unsigned long)desc_p, ++ (unsigned long)desc_p + ++ roundup(sizeof(desc_p->txrx_status), ARCH_DMA_MINALIGN)); + + /* Check if the descriptor is owned by CPU */ + if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) { +@@ -351,7 +359,7 @@ + /* Invalidate received data */ + invalidate_dcache_range((unsigned long)desc_p->dmamac_addr, + (unsigned long)desc_p->dmamac_addr + +- length); ++ roundup(length, ARCH_DMA_MINALIGN)); + + NetReceive(desc_p->dmamac_addr, length); + +@@ -390,6 +398,8 @@ + if (!phydev) + return -1; + ++ phy_connect_dev(phydev, dev); ++ + phydev->supported &= PHY_GBIT_FEATURES; + phydev->advertising = phydev->supported; + +@@ -412,7 +422,8 @@ + * Since the priv structure contains the descriptors which need a strict + * buswidth alignment, memalign is used to allocate memory + */ +- priv = (struct dw_eth_dev *) memalign(16, sizeof(struct dw_eth_dev)); ++ priv = (struct dw_eth_dev *) memalign(ARCH_DMA_MINALIGN, ++ sizeof(struct dw_eth_dev)); + if (!priv) { + free(dev); + return -ENOMEM; +diff -ruN u-boot-2014.04/drivers/net/designware.h u-boot-sunxi/drivers/net/designware.h +--- u-boot-2014.04/drivers/net/designware.h 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/net/designware.h 2014-09-06 16:58:36.301953111 +0200 +@@ -77,18 +77,18 @@ + + #define DW_DMA_BASE_OFFSET (0x1000) + ++/* Default DMA Burst length */ ++#ifndef CONFIG_DW_GMAC_DEFAULT_DMA_PBL ++#define CONFIG_DW_GMAC_DEFAULT_DMA_PBL 8 ++#endif ++ + /* Bus mode register definitions */ + #define FIXEDBURST (1 << 16) + #define PRIORXTX_41 (3 << 14) + #define PRIORXTX_31 (2 << 14) + #define PRIORXTX_21 (1 << 14) + #define PRIORXTX_11 (0 << 14) +-#define BURST_1 (1 << 8) +-#define BURST_2 (2 << 8) +-#define BURST_4 (4 << 8) +-#define BURST_8 (8 << 8) +-#define BURST_16 (16 << 8) +-#define BURST_32 (32 << 8) ++#define DMA_PBL (CONFIG_DW_GMAC_DEFAULT_DMA_PBL<<8) + #define RXHIGHPRIO (1 << 1) + #define DMAMAC_SRST (1 << 0) + +@@ -215,15 +215,14 @@ + #endif + + struct dw_eth_dev { +- u32 interface; +- u32 tx_currdescnum; +- u32 rx_currdescnum; +- + struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM]; + struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM]; ++ char txbuffs[TX_TOTAL_BUFSIZE] __aligned(ARCH_DMA_MINALIGN); ++ char rxbuffs[RX_TOTAL_BUFSIZE] __aligned(ARCH_DMA_MINALIGN); + +- char txbuffs[TX_TOTAL_BUFSIZE]; +- char rxbuffs[RX_TOTAL_BUFSIZE]; ++ u32 interface; ++ u32 tx_currdescnum; ++ u32 rx_currdescnum; + + struct eth_mac_regs *mac_regs_p; + struct eth_dma_regs *dma_regs_p; +diff -ruN u-boot-2014.04/drivers/net/Makefile u-boot-sunxi/drivers/net/Makefile +--- u-boot-2014.04/drivers/net/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/net/Makefile 2014-09-06 16:58:36.297953112 +0200 +@@ -50,7 +50,7 @@ + obj-$(CONFIG_SH_ETHER) += sh_eth.o + obj-$(CONFIG_SMC91111) += smc91111.o + obj-$(CONFIG_SMC911X) += smc911x.o +-obj-$(CONFIG_SUNXI_WEMAC) += sunxi_wemac.o ++obj-$(CONFIG_SUNXI_EMAC) += sunxi_emac.o + obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o + obj-$(CONFIG_TSEC_ENET) += tsec.o fsl_mdio.o + obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o +diff -ruN u-boot-2014.04/drivers/net/sunxi_emac.c u-boot-sunxi/drivers/net/sunxi_emac.c +--- u-boot-2014.04/drivers/net/sunxi_emac.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/net/sunxi_emac.c 2014-09-06 16:58:36.317953111 +0200 +@@ -0,0 +1,521 @@ ++/* ++ * sunxi_emac.c -- Allwinner A10 ethernet driver ++ * ++ * (C) Copyright 2012, Stefan Roese sr@denx.de ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <linux/err.h> ++#include <malloc.h> ++#include <miiphy.h> ++#include <net.h> ++#include <asm/io.h> ++#include <asm/arch/clock.h> ++#include <asm/arch/gpio.h> ++ ++/* EMAC register */ ++struct emac_regs { ++ u32 ctl; /* 0x00 */ ++ u32 tx_mode; /* 0x04 */ ++ u32 tx_flow; /* 0x08 */ ++ u32 tx_ctl0; /* 0x0c */ ++ u32 tx_ctl1; /* 0x10 */ ++ u32 tx_ins; /* 0x14 */ ++ u32 tx_pl0; /* 0x18 */ ++ u32 tx_pl1; /* 0x1c */ ++ u32 tx_sta; /* 0x20 */ ++ u32 tx_io_data; /* 0x24 */ ++ u32 tx_io_data1;/* 0x28 */ ++ u32 tx_tsvl0; /* 0x2c */ ++ u32 tx_tsvh0; /* 0x30 */ ++ u32 tx_tsvl1; /* 0x34 */ ++ u32 tx_tsvh1; /* 0x38 */ ++ u32 rx_ctl; /* 0x3c */ ++ u32 rx_hash0; /* 0x40 */ ++ u32 rx_hash1; /* 0x44 */ ++ u32 rx_sta; /* 0x48 */ ++ u32 rx_io_data; /* 0x4c */ ++ u32 rx_fbc; /* 0x50 */ ++ u32 int_ctl; /* 0x54 */ ++ u32 int_sta; /* 0x58 */ ++ u32 mac_ctl0; /* 0x5c */ ++ u32 mac_ctl1; /* 0x60 */ ++ u32 mac_ipgt; /* 0x64 */ ++ u32 mac_ipgr; /* 0x68 */ ++ u32 mac_clrt; /* 0x6c */ ++ u32 mac_maxf; /* 0x70 */ ++ u32 mac_supp; /* 0x74 */ ++ u32 mac_test; /* 0x78 */ ++ u32 mac_mcfg; /* 0x7c */ ++ u32 mac_mcmd; /* 0x80 */ ++ u32 mac_madr; /* 0x84 */ ++ u32 mac_mwtd; /* 0x88 */ ++ u32 mac_mrdd; /* 0x8c */ ++ u32 mac_mind; /* 0x90 */ ++ u32 mac_ssrr; /* 0x94 */ ++ u32 mac_a0; /* 0x98 */ ++ u32 mac_a1; /* 0x9c */ ++}; ++ ++/* SRAMC register */ ++struct sunxi_sramc_regs { ++ u32 ctrl0; ++ u32 ctrl1; ++}; ++ ++/* 0: Disable 1: Aborted frame enable(default) */ ++#define EMAC_TX_AB_M (0x1 << 0) ++/* 0: CPU 1: DMA(default) */ ++#define EMAC_TX_TM (0x1 << 1) ++ ++#define EMAC_TX_SETUP (0) ++ ++/* 0: DRQ asserted 1: DRQ automatically(default) */ ++#define EMAC_RX_DRQ_MODE (0x1 << 1) ++/* 0: CPU 1: DMA(default) */ ++#define EMAC_RX_TM (0x1 << 2) ++/* 0: Normal(default) 1: Pass all Frames */ ++#define EMAC_RX_PA (0x1 << 4) ++/* 0: Normal(default) 1: Pass Control Frames */ ++#define EMAC_RX_PCF (0x1 << 5) ++/* 0: Normal(default) 1: Pass Frames with CRC Error */ ++#define EMAC_RX_PCRCE (0x1 << 6) ++/* 0: Normal(default) 1: Pass Frames with Length Error */ ++#define EMAC_RX_PLE (0x1 << 7) ++/* 0: Normal 1: Pass Frames length out of range(default) */ ++#define EMAC_RX_POR (0x1 << 8) ++/* 0: Not accept 1: Accept unicast Packets(default) */ ++#define EMAC_RX_UCAD (0x1 << 16) ++/* 0: Normal(default) 1: DA Filtering */ ++#define EMAC_RX_DAF (0x1 << 17) ++/* 0: Not accept 1: Accept multicast Packets(default) */ ++#define EMAC_RX_MCO (0x1 << 20) ++/* 0: Disable(default) 1: Enable Hash filter */ ++#define EMAC_RX_MHF (0x1 << 21) ++/* 0: Not accept 1: Accept Broadcast Packets(default) */ ++#define EMAC_RX_BCO (0x1 << 22) ++/* 0: Disable(default) 1: Enable SA Filtering */ ++#define EMAC_RX_SAF (0x1 << 24) ++/* 0: Normal(default) 1: Inverse Filtering */ ++#define EMAC_RX_SAIF (0x1 << 25) ++ ++#define EMAC_RX_SETUP (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \ ++ EMAC_RX_MCO | EMAC_RX_BCO) ++ ++/* 0: Disable 1: Enable Receive Flow Control(default) */ ++#define EMAC_MAC_CTL0_RFC (0x1 << 2) ++/* 0: Disable 1: Enable Transmit Flow Control(default) */ ++#define EMAC_MAC_CTL0_TFC (0x1 << 3) ++ ++#define EMAC_MAC_CTL0_SETUP (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC) ++ ++/* 0: Disable 1: Enable MAC Frame Length Checking(default) */ ++#define EMAC_MAC_CTL1_FLC (0x1 << 1) ++/* 0: Disable(default) 1: Enable Huge Frame */ ++#define EMAC_MAC_CTL1_HF (0x1 << 2) ++/* 0: Disable(default) 1: Enable MAC Delayed CRC */ ++#define EMAC_MAC_CTL1_DCRC (0x1 << 3) ++/* 0: Disable 1: Enable MAC CRC(default) */ ++#define EMAC_MAC_CTL1_CRC (0x1 << 4) ++/* 0: Disable 1: Enable MAC PAD Short frames(default) */ ++#define EMAC_MAC_CTL1_PC (0x1 << 5) ++/* 0: Disable(default) 1: Enable MAC PAD Short frames and append CRC */ ++#define EMAC_MAC_CTL1_VC (0x1 << 6) ++/* 0: Disable(default) 1: Enable MAC auto detect Short frames */ ++#define EMAC_MAC_CTL1_ADP (0x1 << 7) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_PRE (0x1 << 8) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_LPE (0x1 << 9) ++/* 0: Disable(default) 1: Enable no back off */ ++#define EMAC_MAC_CTL1_NB (0x1 << 12) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_BNB (0x1 << 13) ++/* 0: Disable(default) 1: Enable */ ++#define EMAC_MAC_CTL1_ED (0x1 << 14) ++ ++#define EMAC_MAC_CTL1_SETUP (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \ ++ EMAC_MAC_CTL1_PC) ++ ++#define EMAC_MAC_IPGT 0x15 ++ ++#define EMAC_MAC_NBTB_IPG1 0xc ++#define EMAC_MAC_NBTB_IPG2 0x12 ++ ++#define EMAC_MAC_CW 0x37 ++#define EMAC_MAC_RM 0xf ++ ++#define EMAC_MAC_MFL 0x0600 ++ ++/* Receive status */ ++#define EMAC_CRCERR (0x1 << 4) ++#define EMAC_LENERR (0x3 << 5) ++ ++#define DMA_CPU_TRRESHOLD 2000 ++ ++struct emac_eth_dev { ++ u32 speed; ++ u32 duplex; ++ u32 phy_configured; ++ int link_printed; ++}; ++ ++struct emac_rxhdr { ++ s16 rx_len; ++ u16 rx_status; ++}; ++ ++static void emac_inblk_32bit(void *reg, void *data, int count) ++{ ++ int cnt = (count + 3) >> 2; ++ ++ if (cnt) { ++ u32 *buf = data; ++ ++ do { ++ u32 x = readl(reg); ++ *buf++ = x; ++ } while (--cnt); ++ } ++} ++ ++static void emac_outblk_32bit(void *reg, void *data, int count) ++{ ++ int cnt = (count + 3) >> 2; ++ ++ if (cnt) { ++ const u32 *buf = data; ++ ++ do { ++ writel(*buf++, reg); ++ } while (--cnt); ++ } ++} ++ ++/* Read a word from phyxcer */ ++static int emac_phy_read(const char *devname, unsigned char addr, ++ unsigned char reg, unsigned short *value) ++{ ++ struct eth_device *dev = eth_get_dev_by_name(devname); ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ /* issue the phy address and reg */ ++ writel(addr << 8 | reg, ®s->mac_madr); ++ ++ /* pull up the phy io line */ ++ writel(0x1, ®s->mac_mcmd); ++ ++ /* Wait read complete */ ++ mdelay(1); ++ ++ /* push down the phy io line */ ++ writel(0x0, ®s->mac_mcmd); ++ ++ /* and write data */ ++ *value = readl(®s->mac_mrdd); ++ ++ return 0; ++} ++ ++/* Write a word to phyxcer */ ++static int emac_phy_write(const char *devname, unsigned char addr, ++ unsigned char reg, unsigned short value) ++{ ++ struct eth_device *dev = eth_get_dev_by_name(devname); ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ /* issue the phy address and reg */ ++ writel(addr << 8 | reg, ®s->mac_madr); ++ ++ /* pull up the phy io line */ ++ writel(0x1, ®s->mac_mcmd); ++ ++ /* Wait write complete */ ++ mdelay(1); ++ ++ /* push down the phy io line */ ++ writel(0x0, ®s->mac_mcmd); ++ ++ /* and write data */ ++ writel(value, ®s->mac_mwtd); ++ ++ return 0; ++} ++ ++static void emac_setup(struct eth_device *dev) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ u32 reg_val; ++ u16 phy_val; ++ u32 duplex_flag; ++ ++ /* Set up TX */ ++ writel(EMAC_TX_SETUP, ®s->tx_mode); ++ ++ /* Set up RX */ ++ writel(EMAC_RX_SETUP, ®s->rx_ctl); ++ ++ /* Set MAC */ ++ /* Set MAC CTL0 */ ++ writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); ++ ++ /* Set MAC CTL1 */ ++ emac_phy_read(dev->name, 1, 0, &phy_val); ++ debug("PHY SETUP, reg 0 value: %x\n", phy_val); ++ duplex_flag = !!(phy_val & (1 << 8)); ++ ++ reg_val = 0; ++ if (duplex_flag) ++ reg_val = (0x1 << 0); ++ writel(EMAC_MAC_CTL1_SETUP | reg_val, ®s->mac_ctl1); ++ ++ /* Set up IPGT */ ++ writel(EMAC_MAC_IPGT, ®s->mac_ipgt); ++ ++ /* Set up IPGR */ ++ writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); ++ ++ /* Set up Collison window */ ++ writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); ++ ++ /* Set up Max Frame Length */ ++ writel(EMAC_MAC_MFL, ®s->mac_maxf); ++} ++ ++static void emac_reset(struct eth_device *dev) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ debug("resetting device\n"); ++ ++ /* RESET device */ ++ writel(0, ®s->ctl); ++ udelay(200); ++ ++ writel(1, ®s->ctl); ++ udelay(200); ++} ++ ++static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ struct emac_eth_dev *priv = dev->priv; ++ u16 phy_reg; ++ ++ /* Init EMAC */ ++ ++ /* Flush RX FIFO */ ++ setbits_le32(®s->rx_ctl, 0x8); ++ udelay(1); ++ ++ /* Init MAC */ ++ ++ /* Soft reset MAC */ ++ clrbits_le32(®s->mac_ctl0, 0x1 << 15); ++ ++ /* Clear RX counter */ ++ writel(0x0, ®s->rx_fbc); ++ udelay(1); ++ ++ /* Set up EMAC */ ++ emac_setup(dev); ++ ++ writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | ++ dev->enetaddr[2], ®s->mac_a1); ++ writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 | ++ dev->enetaddr[5], ®s->mac_a0); ++ ++ mdelay(1); ++ ++ emac_reset(dev); ++ ++ /* PHY POWER UP */ ++ emac_phy_read(dev->name, 1, 0, &phy_reg); ++ emac_phy_write(dev->name, 1, 0, phy_reg & (~(0x1 << 11))); ++ mdelay(1); ++ ++ emac_phy_read(dev->name, 1, 0, &phy_reg); ++ ++ priv->speed = miiphy_speed(dev->name, 0); ++ priv->duplex = miiphy_duplex(dev->name, 0); ++ ++ /* Print link status only once */ ++ if (!priv->link_printed) { ++ printf("ENET Speed is %d Mbps - %s duplex connection\n", ++ priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); ++ priv->link_printed = 1; ++ } ++ ++ /* Set EMAC SPEED depend on PHY */ ++ clrsetbits_le32(®s->mac_supp, 1 << 8, ++ ((phy_reg & (0x1 << 13)) >> 13) << 8); ++ ++ /* Set duplex depend on phy */ ++ clrsetbits_le32(®s->mac_ctl1, 1 << 0, ++ ((phy_reg & (0x1 << 8)) >> 8) << 0); ++ ++ /* Enable RX/TX */ ++ setbits_le32(®s->ctl, 0x7); ++ ++ return 0; ++} ++ ++static void sunxi_emac_eth_halt(struct eth_device *dev) ++{ ++ /* Nothing to do here */ ++} ++ ++static int sunxi_emac_eth_recv(struct eth_device *dev) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ struct emac_rxhdr rxhdr; ++ u32 rxcount; ++ u32 reg_val; ++ int rx_len; ++ int rx_status; ++ int good_packet; ++ ++ /* Check packet ready or not */ ++ ++ /* Race warning: The first packet might arrive with ++ * the interrupts disabled, but the second will fix ++ */ ++ rxcount = readl(®s->rx_fbc); ++ if (!rxcount) { ++ /* Had one stuck? */ ++ rxcount = readl(®s->rx_fbc); ++ if (!rxcount) ++ return 0; ++ } ++ ++ reg_val = readl(®s->rx_io_data); ++ if (reg_val != 0x0143414d) { ++ /* Disable RX */ ++ clrbits_le32(®s->ctl, 0x1 << 2); ++ ++ /* Flush RX FIFO */ ++ setbits_le32(®s->rx_ctl, 0x1 << 3); ++ while (readl(®s->rx_ctl) & (0x1 << 3)) ++ ; ++ ++ /* Enable RX */ ++ setbits_le32(®s->ctl, 0x1 << 2); ++ ++ return 0; ++ } ++ ++ /* A packet ready now ++ * Get status/length ++ */ ++ good_packet = 1; ++ ++ emac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); ++ ++ rx_len = rxhdr.rx_len; ++ rx_status = rxhdr.rx_status; ++ ++ /* Packet Status check */ ++ if (rx_len < 0x40) { ++ good_packet = 0; ++ debug("RX: Bad Packet (runt)\n"); ++ } ++ ++ /* rx_status is identical to RSR register. */ ++ if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) { ++ good_packet = 0; ++ if (rx_status & EMAC_CRCERR) ++ printf("crc error\n"); ++ if (rx_status & EMAC_LENERR) ++ printf("length error\n"); ++ } ++ ++ /* Move data from EMAC */ ++ if (good_packet) { ++ if (rx_len > DMA_CPU_TRRESHOLD) { ++ printf("Received packet is too big (len=%d)\n", rx_len); ++ } else { ++ emac_inblk_32bit((void *)®s->rx_io_data, ++ NetRxPackets[0], rx_len); ++ ++ /* Pass to upper layer */ ++ NetReceive(NetRxPackets[0], rx_len); ++ return rx_len; ++ } ++ } ++ ++ return 0; ++} ++ ++static int sunxi_emac_eth_send(struct eth_device *dev, void *packet, int len) ++{ ++ struct emac_regs *regs = (struct emac_regs *)dev->iobase; ++ ++ /* Select channel 0 */ ++ writel(0, ®s->tx_ins); ++ ++ /* Write packet */ ++ emac_outblk_32bit((void *)®s->tx_io_data, packet, len); ++ ++ /* Set TX len */ ++ writel(len, ®s->tx_pl0); ++ ++ /* Start translate from fifo to phy */ ++ setbits_le32(®s->tx_ctl0, 1); ++ ++ return 0; ++} ++ ++int sunxi_emac_initialize(void) ++{ ++ struct sunxi_ccm_reg *const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ struct sunxi_sramc_regs *sram = ++ (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; ++ struct emac_regs *regs = ++ (struct emac_regs *)SUNXI_EMAC_BASE; ++ struct eth_device *dev; ++ struct emac_eth_dev *priv; ++ int pin; ++ ++ dev = malloc(sizeof(*dev)); ++ if (dev == NULL) ++ return -ENOMEM; ++ ++ priv = (struct emac_eth_dev *)malloc(sizeof(struct emac_eth_dev)); ++ if (!priv) { ++ free(dev); ++ return -ENOMEM; ++ } ++ ++ memset(dev, 0, sizeof(*dev)); ++ memset(priv, 0, sizeof(struct emac_eth_dev)); ++ ++ /* Map SRAM to EMAC */ ++ setbits_le32(&sram->ctrl1, 0x5 << 2); ++ ++ /* Configure pin mux settings for MII Ethernet */ ++ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) ++ sunxi_gpio_set_cfgpin(pin, SUNXI_GPA0_EMAC); ++ ++ /* Set up clock gating */ ++ setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_EMAC); ++ ++ /* Set MII clock */ ++ clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); ++ ++ dev->iobase = (int)regs; ++ dev->priv = priv; ++ dev->init = sunxi_emac_eth_init; ++ dev->halt = sunxi_emac_eth_halt; ++ dev->send = sunxi_emac_eth_send; ++ dev->recv = sunxi_emac_eth_recv; ++ strcpy(dev->name, "emac"); ++ ++ eth_register(dev); ++ ++ miiphy_register(dev->name, emac_phy_read, emac_phy_write); ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/drivers/net/sunxi_wemac.c u-boot-sunxi/drivers/net/sunxi_wemac.c +--- u-boot-2014.04/drivers/net/sunxi_wemac.c 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/net/sunxi_wemac.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,525 +0,0 @@ +-/* +- * sunxi_wemac.c -- Allwinner A10 ethernet driver +- * +- * (C) Copyright 2012, Stefan Roese sr@denx.de +- * +- * SPDX-License-Identifier: GPL-2.0+ +- */ +- +-#include <common.h> +-#include <malloc.h> +-#include <net.h> +-#include <miiphy.h> +-#include <linux/err.h> +-#include <asm/io.h> +-#include <asm/arch/clock.h> +-#include <asm/arch/gpio.h> +- +-/* EMAC register */ +-struct wemac_regs { +- u32 ctl; /* 0x00 */ +- u32 tx_mode; /* 0x04 */ +- u32 tx_flow; /* 0x08 */ +- u32 tx_ctl0; /* 0x0c */ +- u32 tx_ctl1; /* 0x10 */ +- u32 tx_ins; /* 0x14 */ +- u32 tx_pl0; /* 0x18 */ +- u32 tx_pl1; /* 0x1c */ +- u32 tx_sta; /* 0x20 */ +- u32 tx_io_data; /* 0x24 */ +- u32 tx_io_data1; /* 0x28 */ +- u32 tx_tsvl0; /* 0x2c */ +- u32 tx_tsvh0; /* 0x30 */ +- u32 tx_tsvl1; /* 0x34 */ +- u32 tx_tsvh1; /* 0x38 */ +- u32 rx_ctl; /* 0x3c */ +- u32 rx_hash0; /* 0x40 */ +- u32 rx_hash1; /* 0x44 */ +- u32 rx_sta; /* 0x48 */ +- u32 rx_io_data; /* 0x4c */ +- u32 rx_fbc; /* 0x50 */ +- u32 int_ctl; /* 0x54 */ +- u32 int_sta; /* 0x58 */ +- u32 mac_ctl0; /* 0x5c */ +- u32 mac_ctl1; /* 0x60 */ +- u32 mac_ipgt; /* 0x64 */ +- u32 mac_ipgr; /* 0x68 */ +- u32 mac_clrt; /* 0x6c */ +- u32 mac_maxf; /* 0x70 */ +- u32 mac_supp; /* 0x74 */ +- u32 mac_test; /* 0x78 */ +- u32 mac_mcfg; /* 0x7c */ +- u32 mac_mcmd; /* 0x80 */ +- u32 mac_madr; /* 0x84 */ +- u32 mac_mwtd; /* 0x88 */ +- u32 mac_mrdd; /* 0x8c */ +- u32 mac_mind; /* 0x90 */ +- u32 mac_ssrr; /* 0x94 */ +- u32 mac_a0; /* 0x98 */ +- u32 mac_a1; /* 0x9c */ +-}; +- +-/* SRAMC register */ +-struct sunxi_sramc_regs { +- u32 ctrl0; +- u32 ctrl1; +-}; +- +-/* 0: Disable 1: Aborted frame enable(default) */ +-#define EMAC_TX_AB_M (0x1 << 0) +-/* 0: CPU 1: DMA(default) */ +-#define EMAC_TX_TM (0x1 << 1) +- +-#define EMAC_TX_SETUP (0) +- +-/* 0: DRQ asserted 1: DRQ automatically(default) */ +-#define EMAC_RX_DRQ_MODE (0x1 << 1) +-/* 0: CPU 1: DMA(default) */ +-#define EMAC_RX_TM (0x1 << 2) +-/* 0: Normal(default) 1: Pass all Frames */ +-#define EMAC_RX_PA (0x1 << 4) +-/* 0: Normal(default) 1: Pass Control Frames */ +-#define EMAC_RX_PCF (0x1 << 5) +-/* 0: Normal(default) 1: Pass Frames with CRC Error */ +-#define EMAC_RX_PCRCE (0x1 << 6) +-/* 0: Normal(default) 1: Pass Frames with Length Error */ +-#define EMAC_RX_PLE (0x1 << 7) +-/* 0: Normal 1: Pass Frames length out of range(default) */ +-#define EMAC_RX_POR (0x1 << 8) +-/* 0: Not accept 1: Accept unicast Packets(default) */ +-#define EMAC_RX_UCAD (0x1 << 16) +-/* 0: Normal(default) 1: DA Filtering */ +-#define EMAC_RX_DAF (0x1 << 17) +-/* 0: Not accept 1: Accept multicast Packets(default) */ +-#define EMAC_RX_MCO (0x1 << 20) +-/* 0: Disable(default) 1: Enable Hash filter */ +-#define EMAC_RX_MHF (0x1 << 21) +-/* 0: Not accept 1: Accept Broadcast Packets(default) */ +-#define EMAC_RX_BCO (0x1 << 22) +-/* 0: Disable(default) 1: Enable SA Filtering */ +-#define EMAC_RX_SAF (0x1 << 24) +-/* 0: Normal(default) 1: Inverse Filtering */ +-#define EMAC_RX_SAIF (0x1 << 25) +- +-#define EMAC_RX_SETUP (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \ +- EMAC_RX_MCO | EMAC_RX_BCO) +- +-/* 0: Disable 1: Enable Receive Flow Control(default) */ +-#define EMAC_MAC_CTL0_RFC (0x1 << 2) +-/* 0: Disable 1: Enable Transmit Flow Control(default) */ +-#define EMAC_MAC_CTL0_TFC (0x1 << 3) +- +-#define EMAC_MAC_CTL0_SETUP (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC) +- +-/* 0: Disable 1: Enable MAC Frame Length Checking(default) */ +-#define EMAC_MAC_CTL1_FLC (0x1 << 1) +-/* 0: Disable(default) 1: Enable Huge Frame */ +-#define EMAC_MAC_CTL1_HF (0x1 << 2) +-/* 0: Disable(default) 1: Enable MAC Delayed CRC */ +-#define EMAC_MAC_CTL1_DCRC (0x1 << 3) +-/* 0: Disable 1: Enable MAC CRC(default) */ +-#define EMAC_MAC_CTL1_CRC (0x1 << 4) +-/* 0: Disable 1: Enable MAC PAD Short frames(default) */ +-#define EMAC_MAC_CTL1_PC (0x1 << 5) +-/* 0: Disable(default) 1: Enable MAC PAD Short frames and append CRC */ +-#define EMAC_MAC_CTL1_VC (0x1 << 6) +-/* 0: Disable(default) 1: Enable MAC auto detect Short frames */ +-#define EMAC_MAC_CTL1_ADP (0x1 << 7) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_PRE (0x1 << 8) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_LPE (0x1 << 9) +-/* 0: Disable(default) 1: Enable no back off */ +-#define EMAC_MAC_CTL1_NB (0x1 << 12) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_BNB (0x1 << 13) +-/* 0: Disable(default) 1: Enable */ +-#define EMAC_MAC_CTL1_ED (0x1 << 14) +- +-#define EMAC_MAC_CTL1_SETUP (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \ +- EMAC_MAC_CTL1_PC) +- +-#define EMAC_MAC_IPGT 0x15 +- +-#define EMAC_MAC_NBTB_IPG1 0xC +-#define EMAC_MAC_NBTB_IPG2 0x12 +- +-#define EMAC_MAC_CW 0x37 +-#define EMAC_MAC_RM 0xF +- +-#define EMAC_MAC_MFL 0x0600 +- +-/* Receive status */ +-#define EMAC_CRCERR (1 << 4) +-#define EMAC_LENERR (3 << 5) +- +-#define DMA_CPU_TRRESHOLD 2000 +- +-struct wemac_eth_dev { +- u32 speed; +- u32 duplex; +- u32 phy_configured; +- int link_printed; +-}; +- +-struct wemac_rxhdr { +- s16 rx_len; +- u16 rx_status; +-}; +- +-static void wemac_inblk_32bit(void *reg, void *data, int count) +-{ +- int cnt = (count + 3) >> 2; +- +- if (cnt) { +- u32 *buf = data; +- +- do { +- u32 x = readl(reg); +- *buf++ = x; +- } while (--cnt); +- } +-} +- +-static void wemac_outblk_32bit(void *reg, void *data, int count) +-{ +- int cnt = (count + 3) >> 2; +- +- if (cnt) { +- const u32 *buf = data; +- +- do { +- writel(*buf++, reg); +- } while (--cnt); +- } +-} +- +-/* +- * Read a word from phyxcer +- */ +-static int wemac_phy_read(const char *devname, unsigned char addr, +- unsigned char reg, unsigned short *value) +-{ +- struct eth_device *dev = eth_get_dev_by_name(devname); +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- /* issue the phy address and reg */ +- writel(addr << 8 | reg, ®s->mac_madr); +- +- /* pull up the phy io line */ +- writel(0x1, ®s->mac_mcmd); +- +- /* Wait read complete */ +- mdelay(1); +- +- /* push down the phy io line */ +- writel(0x0, ®s->mac_mcmd); +- +- /* and write data */ +- *value = readl(®s->mac_mrdd); +- +- return 0; +-} +- +-/* +- * Write a word to phyxcer +- */ +-static int wemac_phy_write(const char *devname, unsigned char addr, +- unsigned char reg, unsigned short value) +-{ +- struct eth_device *dev = eth_get_dev_by_name(devname); +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- /* issue the phy address and reg */ +- writel(addr << 8 | reg, ®s->mac_madr); +- +- /* pull up the phy io line */ +- writel(0x1, ®s->mac_mcmd); +- +- /* Wait write complete */ +- mdelay(1); +- +- /* push down the phy io line */ +- writel(0x0, ®s->mac_mcmd); +- +- /* and write data */ +- writel(value, ®s->mac_mwtd); +- +- return 0; +-} +- +-static void emac_setup(struct eth_device *dev) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- u32 reg_val; +- u16 phy_val; +- u32 duplex_flag; +- +- /* Set up TX */ +- writel(EMAC_TX_SETUP, ®s->tx_mode); +- +- /* Set up RX */ +- writel(EMAC_RX_SETUP, ®s->rx_ctl); +- +- /* Set MAC */ +- /* Set MAC CTL0 */ +- writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); +- +- /* Set MAC CTL1 */ +- wemac_phy_read(dev->name, 1, 0, &phy_val); +- debug("PHY SETUP, reg 0 value: %x\n", phy_val); +- duplex_flag = !!(phy_val & (1 << 8)); +- +- reg_val = 0; +- if (duplex_flag) +- reg_val = (0x1 << 0); +- writel(EMAC_MAC_CTL1_SETUP | reg_val, ®s->mac_ctl1); +- +- /* Set up IPGT */ +- writel(EMAC_MAC_IPGT, ®s->mac_ipgt); +- +- /* Set up IPGR */ +- writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); +- +- /* Set up Collison window */ +- writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); +- +- /* Set up Max Frame Length */ +- writel(EMAC_MAC_MFL, ®s->mac_maxf); +-} +- +-static void wemac_reset(struct eth_device *dev) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- debug("resetting device\n"); +- +- /* RESET device */ +- writel(0, ®s->ctl); +- udelay(200); +- +- writel(1, ®s->ctl); +- udelay(200); +-} +- +-static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- struct wemac_eth_dev *priv = dev->priv; +- u16 phy_reg; +- +- /* Init EMAC */ +- +- /* Flush RX FIFO */ +- setbits_le32(®s->rx_ctl, 0x8); +- udelay(1); +- +- /* Init MAC */ +- +- /* Soft reset MAC */ +- clrbits_le32(®s->mac_ctl0, 1 << 15); +- +- /* Set MII clock */ +- clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); +- +- /* Clear RX counter */ +- writel(0x0, ®s->rx_fbc); +- udelay(1); +- +- /* Set up EMAC */ +- emac_setup(dev); +- +- writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | +- dev->enetaddr[2], ®s->mac_a1); +- writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 | +- dev->enetaddr[5], ®s->mac_a0); +- +- mdelay(1); +- +- wemac_reset(dev); +- +- /* PHY POWER UP */ +- wemac_phy_read(dev->name, 1, 0, &phy_reg); +- wemac_phy_write(dev->name, 1, 0, phy_reg & (~(1 << 11))); +- mdelay(1); +- +- wemac_phy_read(dev->name, 1, 0, &phy_reg); +- +- priv->speed = miiphy_speed(dev->name, 0); +- priv->duplex = miiphy_duplex(dev->name, 0); +- +- /* Print link status only once */ +- if (!priv->link_printed) { +- printf("ENET Speed is %d Mbps - %s duplex connection\n", +- priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); +- priv->link_printed = 1; +- } +- +- /* Set EMAC SPEED depend on PHY */ +- clrsetbits_le32(®s->mac_supp, 1 << 8, +- ((phy_reg & (1 << 13)) >> 13) << 8); +- +- /* Set duplex depend on phy */ +- clrsetbits_le32(®s->mac_ctl1, 1 << 0, +- ((phy_reg & (1 << 8)) >> 8) << 0); +- +- /* Enable RX/TX */ +- setbits_le32(®s->ctl, 0x7); +- +- return 0; +-} +- +-static void sunxi_wemac_eth_halt(struct eth_device *dev) +-{ +- /* Nothing to do here */ +-} +- +-static int sunxi_wemac_eth_recv(struct eth_device *dev) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- struct wemac_rxhdr rxhdr; +- u32 rxcount; +- u32 reg_val; +- int rx_len; +- int rx_status; +- int good_packet; +- +- /* Check packet ready or not */ +- +- /* +- * Race warning: The first packet might arrive with +- * the interrupts disabled, but the second will fix +- */ +- rxcount = readl(®s->rx_fbc); +- if (!rxcount) { +- /* Had one stuck? */ +- rxcount = readl(®s->rx_fbc); +- if (!rxcount) +- return 0; +- } +- +- reg_val = readl(®s->rx_io_data); +- if (reg_val != 0x0143414d) { +- /* Disable RX */ +- clrbits_le32(®s->ctl, 1 << 2); +- +- /* Flush RX FIFO */ +- setbits_le32(®s->rx_ctl, 1 << 3); +- while (readl(®s->rx_ctl) & (1 << 3)) +- ; +- +- /* Enable RX */ +- setbits_le32(®s->ctl, 1 << 2); +- +- return 0; +- } +- +- /* +- * A packet ready now +- * Get status/length +- */ +- good_packet = 1; +- +- wemac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); +- +- rx_len = rxhdr.rx_len; +- rx_status = rxhdr.rx_status; +- +- /* Packet Status check */ +- if (rx_len < 0x40) { +- good_packet = 0; +- debug("RX: Bad Packet (runt)\n"); +- } +- +- /* rx_status is identical to RSR register. */ +- if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) { +- good_packet = 0; +- if (rx_status & EMAC_CRCERR) +- printf("crc error\n"); +- if (rx_status & EMAC_LENERR) +- printf("length error\n"); +- } +- +- /* Move data from WEMAC */ +- if (good_packet) { +- if (rx_len > DMA_CPU_TRRESHOLD) { +- printf("Received packet is too big (len=%d)\n", rx_len); +- } else { +- wemac_inblk_32bit((void *)®s->rx_io_data, +- NetRxPackets[0], rx_len); +- +- /* Pass to upper layer */ +- NetReceive(NetRxPackets[0], rx_len); +- return rx_len; +- } +- } +- +- return 0; +-} +- +-static int sunxi_wemac_eth_send(struct eth_device *dev, void *packet, int len) +-{ +- struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; +- +- /* Select channel 0 */ +- writel(0, ®s->tx_ins); +- +- /* Write packet */ +- wemac_outblk_32bit((void *)®s->tx_io_data, packet, len); +- +- /* Set TX len */ +- writel(len, ®s->tx_pl0); +- +- /* Start translate from fifo to phy */ +- setbits_le32(®s->tx_ctl0, 1); +- +- return 0; +-} +- +-int sunxi_wemac_initialize(void) +-{ +- struct sunxi_ccm_reg *const ccm = +- (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; +- struct sunxi_sramc_regs *sram = +- (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; +- struct eth_device *dev; +- struct wemac_eth_dev *priv; +- int pin; +- +- dev = malloc(sizeof(*dev)); +- if (dev == NULL) +- return -ENOMEM; +- +- priv = (struct wemac_eth_dev *)malloc(sizeof(struct wemac_eth_dev)); +- if (!priv) { +- free(dev); +- return -ENOMEM; +- } +- +- memset(dev, 0, sizeof(*dev)); +- memset(priv, 0, sizeof(struct wemac_eth_dev)); +- +- /* Map SRAM to EMAC */ +- setbits_le32(&sram->ctrl1, 0x5 << 2); +- +- /* Configure pin mux settings for MII Ethernet */ +- for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) +- sunxi_gpio_set_cfgpin(pin, 2); +- +- /* Set up clock gating */ +- setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_EMAC); +- +- dev->iobase = SUNXI_EMAC_BASE; +- dev->priv = priv; +- dev->init = sunxi_wemac_eth_init; +- dev->halt = sunxi_wemac_eth_halt; +- dev->send = sunxi_wemac_eth_send; +- dev->recv = sunxi_wemac_eth_recv; +- strcpy(dev->name, "wemac"); +- +- eth_register(dev); +- +- miiphy_register(dev->name, wemac_phy_read, wemac_phy_write); +- +- return 0; +-} +diff -ruN u-boot-2014.04/drivers/power/axp152.c u-boot-sunxi/drivers/power/axp152.c +--- u-boot-2014.04/drivers/power/axp152.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/power/axp152.c 2014-09-06 16:58:36.321953111 +0200 +@@ -0,0 +1,112 @@ ++/* ++ * (C) Copyright 2012 ++ * Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#include <common.h> ++#include <i2c.h> ++#include <axp152.h> ++ ++enum axp152_reg { ++ AXP152_CHIP_VERSION = 0x3, ++ AXP152_DCDC2_VOLTAGE = 0x23, ++ AXP152_DCDC3_VOLTAGE = 0x27, ++ AXP152_DCDC4_VOLTAGE = 0x2B, ++ AXP152_LDO2_VOLTAGE = 0x2A, ++ AXP152_SHUTDOWN = 0x32, ++}; ++ ++#define AXP152_POWEROFF (1 << 7) ++ ++static int axp152_write(enum axp152_reg reg, u8 val) ++{ ++ return i2c_write(0x30, reg, 1, &val, 1); ++} ++ ++static int axp152_read(enum axp152_reg reg, u8 *val) ++{ ++ return i2c_read(0x30, reg, 1, val, 1); ++} ++ ++static int axp152_mvolt_to_target(int mvolt, int min, int max, int div) ++{ ++ if (mvolt < min) ++ mvolt = min; ++ else if (mvolt > max) ++ mvolt = max; ++ ++ return (mvolt - min) / div; ++} ++ ++int axp152_set_dcdc2(int mvolt) ++{ ++ int rc, target; ++ u8 current; ++ ++ target = axp152_mvolt_to_target(mvolt, 700, 2275, 25); ++ ++ /* Do we really need to be this gentle? It has built-in voltage slope */ ++ while ((rc = axp152_read(AXP152_DCDC2_VOLTAGE, ¤t)) == 0 && ++ current != target) { ++ if (current < target) ++ current++; ++ else ++ current--; ++ rc = axp152_write(AXP152_DCDC2_VOLTAGE, current); ++ if (rc) ++ break; ++ } ++ return rc; ++} ++ ++int axp152_set_dcdc3(int mvolt) ++{ ++ int target = axp152_mvolt_to_target(mvolt, 700, 3500, 25); ++ ++ return axp152_write(AXP152_DCDC3_VOLTAGE, target); ++} ++ ++int axp152_set_dcdc4(int mvolt) ++{ ++ int target = axp152_mvolt_to_target(mvolt, 700, 3500, 25); ++ ++ return axp152_write(AXP152_DCDC4_VOLTAGE, target); ++} ++ ++int axp152_set_ldo2(int mvolt) ++{ ++ int target = axp152_mvolt_to_target(mvolt, 700, 3500, 100); ++ ++ return axp152_write(AXP152_LDO2_VOLTAGE, target); ++} ++ ++void axp152_poweroff(void) ++{ ++ u8 val; ++ ++ if (axp152_read(AXP152_SHUTDOWN, &val) != 0) ++ return; ++ ++ val |= AXP152_POWEROFF; ++ ++ if (axp152_write(AXP152_SHUTDOWN, val) != 0) ++ return; ++ ++ udelay(10000); /* wait for power to drain */ ++} ++ ++int axp152_init(void) ++{ ++ u8 ver; ++ int rc; ++ ++ rc = axp152_read(AXP152_CHIP_VERSION, &ver); ++ if (rc) ++ return rc; ++ ++ if (ver != 0x05) ++ return -1; ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/drivers/power/axp209.c u-boot-sunxi/drivers/power/axp209.c +--- u-boot-2014.04/drivers/power/axp209.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/power/axp209.c 2014-09-06 16:58:36.321953111 +0200 +@@ -0,0 +1,180 @@ ++/* ++ * (C) Copyright 2012 ++ * Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <i2c.h> ++#include <axp209.h> ++ ++enum axp209_reg { ++ AXP209_POWER_STATUS = 0x00, ++ AXP209_CHIP_VERSION = 0x03, ++ AXP209_DCDC2_VOLTAGE = 0x23, ++ AXP209_DCDC3_VOLTAGE = 0x27, ++ AXP209_LDO24_VOLTAGE = 0x28, ++ AXP209_LDO3_VOLTAGE = 0x29, ++ AXP209_IRQ_STATUS5 = 0x4c, ++ AXP209_SHUTDOWN = 0x32, ++}; ++ ++#define AXP209_POWER_STATUS_ON_BY_DC (1 << 0) ++ ++#define AXP209_IRQ5_PEK_UP (1 << 6) ++#define AXP209_IRQ5_PEK_DOWN (1 << 5) ++ ++#define AXP209_POWEROFF (1 << 7) ++ ++static int axp209_write(enum axp209_reg reg, u8 val) ++{ ++ return i2c_write(0x34, reg, 1, &val, 1); ++} ++ ++static int axp209_read(enum axp209_reg reg, u8 *val) ++{ ++ return i2c_read(0x34, reg, 1, val, 1); ++} ++ ++static int axp209_mvolt_to_cfg(int mvolt, int min, int max, int div) ++{ ++ if (mvolt < min) ++ mvolt = min; ++ else if (mvolt > max) ++ mvolt = max; ++ ++ return (mvolt - min) / div; ++} ++ ++int axp209_set_dcdc2(int mvolt) ++{ ++ int cfg, rc; ++ u8 current; ++ ++ cfg = axp209_mvolt_to_cfg(mvolt, 700, 2275, 25); ++ ++ /* Do we really need to be this gentle? It has built-in voltage slope */ ++ while ((rc = axp209_read(AXP209_DCDC2_VOLTAGE, ¤t)) == 0 && ++ current != cfg) { ++ if (current < cfg) ++ current++; ++ else ++ current--; ++ ++ rc = axp209_write(AXP209_DCDC2_VOLTAGE, current); ++ if (rc) ++ break; ++ } ++ ++ return rc; ++} ++ ++int axp209_set_dcdc3(int mvolt) ++{ ++ int cfg = axp209_mvolt_to_cfg(mvolt, 700, 3500, 25); ++ ++ return axp209_write(AXP209_DCDC3_VOLTAGE, cfg); ++} ++ ++int axp209_set_ldo2(int mvolt) ++{ ++ int rc, cfg; ++ u8 reg; ++ ++ cfg = axp209_mvolt_to_cfg(mvolt, 1800, 3300, 100); ++ ++ rc = axp209_read(AXP209_LDO24_VOLTAGE, ®); ++ if (rc) ++ return rc; ++ ++ /* LDO2 configuration is in upper 4 bits */ ++ reg = (reg & 0x0f) | (cfg << 4); ++ return axp209_write(AXP209_LDO24_VOLTAGE, reg); ++} ++ ++int axp209_set_ldo3(int mvolt) ++{ ++ int cfg = axp209_mvolt_to_cfg(mvolt, 700, 2275, 25); ++ ++ if (mvolt == -1) ++ cfg = 0x80; /* determined by LDO3IN pin */ ++ ++ return axp209_write(AXP209_LDO3_VOLTAGE, cfg); ++} ++ ++int axp209_set_ldo4(int mvolt) ++{ ++ int cfg, rc; ++ static const int vindex[] = { ++ 1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2500, ++ 2700, 2800, 3000, 3100, 3200, 3300 ++ }; ++ u8 reg; ++ ++ /* Translate mvolt to register cfg value, requested <= selected */ ++ for (cfg = 15; vindex[cfg] > mvolt && cfg > 0; cfg--); ++ ++ rc = axp209_read(AXP209_LDO24_VOLTAGE, ®); ++ if (rc) ++ return rc; ++ ++ /* LDO4 configuration is in lower 4 bits */ ++ reg = (reg & 0xf0) | (cfg << 0); ++ return axp209_write(AXP209_LDO24_VOLTAGE, reg); ++} ++ ++void axp209_poweroff(void) ++{ ++ u8 val; ++ ++ if (axp209_read(AXP209_SHUTDOWN, &val) != 0) ++ return; ++ ++ val |= AXP209_POWEROFF; ++ ++ if (axp209_write(AXP209_SHUTDOWN, val) != 0) ++ return; ++ ++ udelay(10000); /* wait for power to drain */ ++} ++ ++int axp209_init(void) ++{ ++ u8 ver; ++ int rc; ++ ++ rc = axp209_read(AXP209_CHIP_VERSION, &ver); ++ if (rc) ++ return rc; ++ ++ /* Low 4 bits is chip version */ ++ ver &= 0x0f; ++ ++ if (ver != 0x1) ++ return -1; ++ ++ return 0; ++} ++ ++int axp209_poweron_by_dc(void) ++{ ++ u8 v; ++ ++ if (axp209_read(AXP209_POWER_STATUS, &v)) ++ return 0; ++ ++ return (v & AXP209_POWER_STATUS_ON_BY_DC); ++} ++ ++int axp209_power_button(void) ++{ ++ u8 v; ++ ++ if (axp209_read(AXP209_IRQ_STATUS5, &v)) ++ return 0; ++ ++ axp209_write(AXP209_IRQ_STATUS5, AXP209_IRQ5_PEK_DOWN); ++ ++ return v & AXP209_IRQ5_PEK_DOWN; ++} +diff -ruN u-boot-2014.04/drivers/power/axp221.c u-boot-sunxi/drivers/power/axp221.c +--- u-boot-2014.04/drivers/power/axp221.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/drivers/power/axp221.c 2014-09-06 16:58:36.321953111 +0200 +@@ -0,0 +1,73 @@ ++/* ++ * (C) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <errno.h> ++#include <asm/arch/p2wi.h> ++#include <axp221.h> ++ ++int axp221_set_dcdc1(unsigned int mvolt) ++{ ++ return p2wi_write(AXP221_DCDC1_CTRL, (mvolt - 1600) / 100); ++} ++ ++int axp221_set_dcdc2(unsigned int mvolt) ++{ ++ return p2wi_write(AXP221_DCDC2_CTRL, (mvolt - 600) / 20); ++} ++ ++int axp221_set_dcdc3(unsigned int mvolt) ++{ ++ return p2wi_write(AXP221_DCDC3_CTRL, (mvolt - 600) / 20); ++} ++ ++int axp221_set_dcdc4(unsigned int mvolt) ++{ ++ return p2wi_write(AXP221_DCDC4_CTRL, (mvolt - 600) / 20); ++} ++ ++int axp221_set_dcdc5(unsigned int mvolt) ++{ ++ return p2wi_write(AXP221_DCDC5_CTRL, (mvolt - 600) / 20); ++} ++ ++int axp221_set_dldo1(unsigned int mvolt) ++{ ++ int ret; ++ u8 val; ++ ++ ret = p2wi_write(AXP221_DLDO1_CTRL, (mvolt - 700) / 100); ++ if (ret) ++ return ret; ++ ++ ret = p2wi_read(AXP221_OUTPUT_CTRL2, &val); ++ if (ret) ++ return ret; ++ ++ val |= 1 << 3; ++ return p2wi_write(AXP221_OUTPUT_CTRL2, val); ++} ++ ++int axp221_init(void) ++{ ++ u8 axp_chip_id; ++ int ret; ++ ++ p2wi_init(); ++ ret = p2wi_set_pmu_address(AXP221_CHIP_ADDR, AXP221_CTRL_ADDR, ++ AXP221_INIT_DATA); ++ if (ret) ++ return ret; ++ ++ ret = p2wi_read(AXP221_CHIP_ID, &axp_chip_id); ++ if (ret) ++ return ret; ++ ++ if (!(axp_chip_id == 0x6 || axp_chip_id == 0x7 || axp_chip_id == 0x17)) ++ return -ENODEV; ++ ++ return 0; ++} +diff -ruN u-boot-2014.04/drivers/power/Makefile u-boot-sunxi/drivers/power/Makefile +--- u-boot-2014.04/drivers/power/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/power/Makefile 2014-09-06 16:58:36.321953111 +0200 +@@ -5,6 +5,9 @@ + # SPDX-License-Identifier: GPL-2.0+ + # + ++obj-$(CONFIG_AXP152_POWER) += axp152.o ++obj-$(CONFIG_AXP209_POWER) += axp209.o ++obj-$(CONFIG_AXP221_POWER) += axp221.o + obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o + obj-$(CONFIG_FTPMU010_POWER) += ftpmu010.o + obj-$(CONFIG_TPS6586X_POWER) += tps6586x.o +diff -ruN u-boot-2014.04/drivers/serial/arm_dcc.c u-boot-sunxi/drivers/serial/arm_dcc.c +--- u-boot-2014.04/drivers/serial/arm_dcc.c 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/drivers/serial/arm_dcc.c 2014-09-06 16:58:36.329953111 +0200 +@@ -29,7 +29,7 @@ + #include <common.h> + #include <serial.h> + +-#if defined(CONFIG_CPU_V6) ++#if defined(CONFIG_CPU_V6) || 1 + /* + * ARMV6 + */ +diff -ruN u-boot-2014.04/.git/config u-boot-sunxi/.git/config +--- u-boot-2014.04/.git/config 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/config 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1,11 @@ ++[core] ++ repositoryformatversion = 0 ++ filemode = true ++ bare = false ++ logallrefupdates = true ++[remote "origin"] ++ fetch = +refs/heads/*:refs/remotes/origin/* ++ url = https://github.com/linux-sunxi/u-boot-sunxi ++[branch "sunxi"] ++ remote = origin ++ merge = refs/heads/sunxi +diff -ruN u-boot-2014.04/.git/description u-boot-sunxi/.git/description +--- u-boot-2014.04/.git/description 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/description 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1 @@ ++Unnamed repository; edit this file 'description' to name the repository. +diff -ruN u-boot-2014.04/.git/HEAD u-boot-sunxi/.git/HEAD +--- u-boot-2014.04/.git/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/HEAD 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++ref: refs/heads/sunxi +diff -ruN u-boot-2014.04/.git/hooks/applypatch-msg.sample u-boot-sunxi/.git/hooks/applypatch-msg.sample +--- u-boot-2014.04/.git/hooks/applypatch-msg.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/applypatch-msg.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,15 @@ ++#!/bin/sh ++# ++# An example hook script to check the commit log message taken by ++# applypatch from an e-mail message. ++# ++# The hook should exit with non-zero status after issuing an ++# appropriate message if it wants to stop the commit. The hook is ++# allowed to edit the commit message file. ++# ++# To enable this hook, rename this file to "applypatch-msg". ++ ++. git-sh-setup ++test -x "$GIT_DIR/hooks/commit-msg" && ++ exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} ++: +diff -ruN u-boot-2014.04/.git/hooks/commit-msg.sample u-boot-sunxi/.git/hooks/commit-msg.sample +--- u-boot-2014.04/.git/hooks/commit-msg.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/commit-msg.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,24 @@ ++#!/bin/sh ++# ++# An example hook script to check the commit log message. ++# Called by "git commit" with one argument, the name of the file ++# that has the commit message. The hook should exit with non-zero ++# status after issuing an appropriate message if it wants to stop the ++# commit. The hook is allowed to edit the commit message file. ++# ++# To enable this hook, rename this file to "commit-msg". ++ ++# Uncomment the below to add a Signed-off-by line to the message. ++# Doing this in a hook is a bad idea in general, but the prepare-commit-msg ++# hook is more suited to it. ++# ++# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^(.*>).*$/Signed-off-by: \1/p') ++# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" ++ ++# This example catches duplicate Signed-off-by lines. ++ ++test "" = "$(grep '^Signed-off-by: ' "$1" | ++ sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { ++ echo >&2 Duplicate Signed-off-by lines. ++ exit 1 ++} +diff -ruN u-boot-2014.04/.git/hooks/post-update.sample u-boot-sunxi/.git/hooks/post-update.sample +--- u-boot-2014.04/.git/hooks/post-update.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/post-update.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,8 @@ ++#!/bin/sh ++# ++# An example hook script to prepare a packed repository for use over ++# dumb transports. ++# ++# To enable this hook, rename this file to "post-update". ++ ++exec git update-server-info +diff -ruN u-boot-2014.04/.git/hooks/pre-applypatch.sample u-boot-sunxi/.git/hooks/pre-applypatch.sample +--- u-boot-2014.04/.git/hooks/pre-applypatch.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/pre-applypatch.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,14 @@ ++#!/bin/sh ++# ++# An example hook script to verify what is about to be committed ++# by applypatch from an e-mail message. ++# ++# The hook should exit with non-zero status after issuing an ++# appropriate message if it wants to stop the commit. ++# ++# To enable this hook, rename this file to "pre-applypatch". ++ ++. git-sh-setup ++test -x "$GIT_DIR/hooks/pre-commit" && ++ exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} ++: +diff -ruN u-boot-2014.04/.git/hooks/pre-commit.sample u-boot-sunxi/.git/hooks/pre-commit.sample +--- u-boot-2014.04/.git/hooks/pre-commit.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/pre-commit.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,50 @@ ++#!/bin/sh ++# ++# An example hook script to verify what is about to be committed. ++# Called by "git commit" with no arguments. The hook should ++# exit with non-zero status after issuing an appropriate message if ++# it wants to stop the commit. ++# ++# To enable this hook, rename this file to "pre-commit". ++ ++if git rev-parse --verify HEAD >/dev/null 2>&1 ++then ++ against=HEAD ++else ++ # Initial commit: diff against an empty tree object ++ against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 ++fi ++ ++# If you want to allow non-ascii filenames set this variable to true. ++allownonascii=$(git config hooks.allownonascii) ++ ++# Redirect output to stderr. ++exec 1>&2 ++ ++# Cross platform projects tend to avoid non-ascii filenames; prevent ++# them from being added to the repository. We exploit the fact that the ++# printable range starts at the space character and ends with tilde. ++if [ "$allownonascii" != "true" ] && ++ # Note that the use of brackets around a tr range is ok here, (it's ++ # even required, for portability to Solaris 10's /usr/bin/tr), since ++ # the square bracket bytes happen to fall in the designated range. ++ test $(git diff --cached --name-only --diff-filter=A -z $against | ++ LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 ++then ++ echo "Error: Attempt to add a non-ascii file name." ++ echo ++ echo "This can cause problems if you want to work" ++ echo "with people on other platforms." ++ echo ++ echo "To be portable it is advisable to rename the file ..." ++ echo ++ echo "If you know what you are doing you can disable this" ++ echo "check using:" ++ echo ++ echo " git config hooks.allownonascii true" ++ echo ++ exit 1 ++fi ++ ++# If there are whitespace errors, print the offending file names and fail. ++exec git diff-index --check --cached $against -- +diff -ruN u-boot-2014.04/.git/hooks/prepare-commit-msg.sample u-boot-sunxi/.git/hooks/prepare-commit-msg.sample +--- u-boot-2014.04/.git/hooks/prepare-commit-msg.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/prepare-commit-msg.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,36 @@ ++#!/bin/sh ++# ++# An example hook script to prepare the commit log message. ++# Called by "git commit" with the name of the file that has the ++# commit message, followed by the description of the commit ++# message's source. The hook's purpose is to edit the commit ++# message file. If the hook fails with a non-zero status, ++# the commit is aborted. ++# ++# To enable this hook, rename this file to "prepare-commit-msg". ++ ++# This hook includes three examples. The first comments out the ++# "Conflicts:" part of a merge commit. ++# ++# The second includes the output of "git diff --name-status -r" ++# into the message, just before the "git status" output. It is ++# commented because it doesn't cope with --amend or with squashed ++# commits. ++# ++# The third example adds a Signed-off-by line to the message, that can ++# still be edited. This is rarely a good idea. ++ ++case "$2,$3" in ++ merge,) ++ /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; ++ ++# ,|template,) ++# /usr/bin/perl -i.bak -pe ' ++# print "\n" . `git diff --cached --name-status -r` ++# if /^#/ && $first++ == 0' "$1" ;; ++ ++ *) ;; ++esac ++ ++# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^(.*>).*$/Signed-off-by: \1/p') ++# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" +diff -ruN u-boot-2014.04/.git/hooks/pre-rebase.sample u-boot-sunxi/.git/hooks/pre-rebase.sample +--- u-boot-2014.04/.git/hooks/pre-rebase.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/pre-rebase.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,169 @@ ++#!/bin/sh ++# ++# Copyright (c) 2006, 2008 Junio C Hamano ++# ++# The "pre-rebase" hook is run just before "git rebase" starts doing ++# its job, and can prevent the command from running by exiting with ++# non-zero status. ++# ++# The hook is called with the following parameters: ++# ++# $1 -- the upstream the series was forked from. ++# $2 -- the branch being rebased (or empty when rebasing the current branch). ++# ++# This sample shows how to prevent topic branches that are already ++# merged to 'next' branch from getting rebased, because allowing it ++# would result in rebasing already published history. ++ ++publish=next ++basebranch="$1" ++if test "$#" = 2 ++then ++ topic="refs/heads/$2" ++else ++ topic=`git symbolic-ref HEAD` || ++ exit 0 ;# we do not interrupt rebasing detached HEAD ++fi ++ ++case "$topic" in ++refs/heads/??/*) ++ ;; ++*) ++ exit 0 ;# we do not interrupt others. ++ ;; ++esac ++ ++# Now we are dealing with a topic branch being rebased ++# on top of master. Is it OK to rebase it? ++ ++# Does the topic really exist? ++git show-ref -q "$topic" || { ++ echo >&2 "No such branch $topic" ++ exit 1 ++} ++ ++# Is topic fully merged to master? ++not_in_master=`git rev-list --pretty=oneline ^master "$topic"` ++if test -z "$not_in_master" ++then ++ echo >&2 "$topic is fully merged to master; better remove it." ++ exit 1 ;# we could allow it, but there is no point. ++fi ++ ++# Is topic ever merged to next? If so you should not be rebasing it. ++only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` ++only_next_2=`git rev-list ^master ${publish} | sort` ++if test "$only_next_1" = "$only_next_2" ++then ++ not_in_topic=`git rev-list "^$topic" master` ++ if test -z "$not_in_topic" ++ then ++ echo >&2 "$topic is already up-to-date with master" ++ exit 1 ;# we could allow it, but there is no point. ++ else ++ exit 0 ++ fi ++else ++ not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` ++ /usr/bin/perl -e ' ++ my $topic = $ARGV[0]; ++ my $msg = "* $topic has commits already merged to public branch:\n"; ++ my (%not_in_next) = map { ++ /^([0-9a-f]+) /; ++ ($1 => 1); ++ } split(/\n/, $ARGV[1]); ++ for my $elem (map { ++ /^([0-9a-f]+) (.*)$/; ++ [$1 => $2]; ++ } split(/\n/, $ARGV[2])) { ++ if (!exists $not_in_next{$elem->[0]}) { ++ if ($msg) { ++ print STDERR $msg; ++ undef $msg; ++ } ++ print STDERR " $elem->[1]\n"; ++ } ++ } ++ ' "$topic" "$not_in_next" "$not_in_master" ++ exit 1 ++fi ++ ++<<\DOC_END ++ ++This sample hook safeguards topic branches that have been ++published from being rewound. ++ ++The workflow assumed here is: ++ ++ * Once a topic branch forks from "master", "master" is never ++ merged into it again (either directly or indirectly). ++ ++ * Once a topic branch is fully cooked and merged into "master", ++ it is deleted. If you need to build on top of it to correct ++ earlier mistakes, a new topic branch is created by forking at ++ the tip of the "master". This is not strictly necessary, but ++ it makes it easier to keep your history simple. ++ ++ * Whenever you need to test or publish your changes to topic ++ branches, merge them into "next" branch. ++ ++The script, being an example, hardcodes the publish branch name ++to be "next", but it is trivial to make it configurable via ++$GIT_DIR/config mechanism. ++ ++With this workflow, you would want to know: ++ ++(1) ... if a topic branch has ever been merged to "next". Young ++ topic branches can have stupid mistakes you would rather ++ clean up before publishing, and things that have not been ++ merged into other branches can be easily rebased without ++ affecting other people. But once it is published, you would ++ not want to rewind it. ++ ++(2) ... if a topic branch has been fully merged to "master". ++ Then you can delete it. More importantly, you should not ++ build on top of it -- other people may already want to ++ change things related to the topic as patches against your ++ "master", so if you need further changes, it is better to ++ fork the topic (perhaps with the same name) afresh from the ++ tip of "master". ++ ++Let's look at this example: ++ ++ o---o---o---o---o---o---o---o---o---o "next" ++ / / / / ++ / a---a---b A / / ++ / / / / ++ / / c---c---c---c B / ++ / / / \ / ++ / / / b---b C \ / ++ / / / / \ / ++ ---o---o---o---o---o---o---o---o---o---o---o "master" ++ ++ ++A, B and C are topic branches. ++ ++ * A has one fix since it was merged up to "next". ++ ++ * B has finished. It has been fully merged up to "master" and "next", ++ and is ready to be deleted. ++ ++ * C has not merged to "next" at all. ++ ++We would want to allow C to be rebased, refuse A, and encourage ++B to be deleted. ++ ++To compute (1): ++ ++ git rev-list ^master ^topic next ++ git rev-list ^master next ++ ++ if these match, topic has not merged in next at all. ++ ++To compute (2): ++ ++ git rev-list master..topic ++ ++ if this is empty, it is fully merged to "master". ++ ++DOC_END +diff -ruN u-boot-2014.04/.git/hooks/update.sample u-boot-sunxi/.git/hooks/update.sample +--- u-boot-2014.04/.git/hooks/update.sample 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/hooks/update.sample 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,128 @@ ++#!/bin/sh ++# ++# An example hook script to blocks unannotated tags from entering. ++# Called by "git receive-pack" with arguments: refname sha1-old sha1-new ++# ++# To enable this hook, rename this file to "update". ++# ++# Config ++# ------ ++# hooks.allowunannotated ++# This boolean sets whether unannotated tags will be allowed into the ++# repository. By default they won't be. ++# hooks.allowdeletetag ++# This boolean sets whether deleting tags will be allowed in the ++# repository. By default they won't be. ++# hooks.allowmodifytag ++# This boolean sets whether a tag may be modified after creation. By default ++# it won't be. ++# hooks.allowdeletebranch ++# This boolean sets whether deleting branches will be allowed in the ++# repository. By default they won't be. ++# hooks.denycreatebranch ++# This boolean sets whether remotely creating branches will be denied ++# in the repository. By default this is allowed. ++# ++ ++# --- Command line ++refname="$1" ++oldrev="$2" ++newrev="$3" ++ ++# --- Safety check ++if [ -z "$GIT_DIR" ]; then ++ echo "Don't run this script from the command line." >&2 ++ echo " (if you want, you could supply GIT_DIR then run" >&2 ++ echo " $0 <ref> <oldrev> <newrev>)" >&2 ++ exit 1 ++fi ++ ++if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then ++ echo "Usage: $0 <ref> <oldrev> <newrev>" >&2 ++ exit 1 ++fi ++ ++# --- Config ++allowunannotated=$(git config --bool hooks.allowunannotated) ++allowdeletebranch=$(git config --bool hooks.allowdeletebranch) ++denycreatebranch=$(git config --bool hooks.denycreatebranch) ++allowdeletetag=$(git config --bool hooks.allowdeletetag) ++allowmodifytag=$(git config --bool hooks.allowmodifytag) ++ ++# check for no description ++projectdesc=$(sed -e '1q' "$GIT_DIR/description") ++case "$projectdesc" in ++"Unnamed repository"* | "") ++ echo "*** Project description file hasn't been set" >&2 ++ exit 1 ++ ;; ++esac ++ ++# --- Check types ++# if $newrev is 0000...0000, it's a commit to delete a ref. ++zero="0000000000000000000000000000000000000000" ++if [ "$newrev" = "$zero" ]; then ++ newrev_type=delete ++else ++ newrev_type=$(git cat-file -t $newrev) ++fi ++ ++case "$refname","$newrev_type" in ++ refs/tags/*,commit) ++ # un-annotated tag ++ short_refname=${refname##refs/tags/} ++ if [ "$allowunannotated" != "true" ]; then ++ echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 ++ echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 ++ exit 1 ++ fi ++ ;; ++ refs/tags/*,delete) ++ # delete tag ++ if [ "$allowdeletetag" != "true" ]; then ++ echo "*** Deleting a tag is not allowed in this repository" >&2 ++ exit 1 ++ fi ++ ;; ++ refs/tags/*,tag) ++ # annotated tag ++ if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 ++ then ++ echo "*** Tag '$refname' already exists." >&2 ++ echo "*** Modifying a tag is not allowed in this repository." >&2 ++ exit 1 ++ fi ++ ;; ++ refs/heads/*,commit) ++ # branch ++ if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then ++ echo "*** Creating a branch is not allowed in this repository" >&2 ++ exit 1 ++ fi ++ ;; ++ refs/heads/*,delete) ++ # delete branch ++ if [ "$allowdeletebranch" != "true" ]; then ++ echo "*** Deleting a branch is not allowed in this repository" >&2 ++ exit 1 ++ fi ++ ;; ++ refs/remotes/*,commit) ++ # tracking branch ++ ;; ++ refs/remotes/*,delete) ++ # delete tracking branch ++ if [ "$allowdeletebranch" != "true" ]; then ++ echo "*** Deleting a tracking branch is not allowed in this repository" >&2 ++ exit 1 ++ fi ++ ;; ++ *) ++ # Anything else (is there anything else?) ++ echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 ++ exit 1 ++ ;; ++esac ++ ++# --- Finished ++exit 0 +Binary files u-boot-2014.04/.git/index and u-boot-sunxi/.git/index differ +diff -ruN u-boot-2014.04/.git/info/exclude u-boot-sunxi/.git/info/exclude +--- u-boot-2014.04/.git/info/exclude 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/info/exclude 2014-09-06 16:58:09.553953909 +0200 +@@ -0,0 +1,6 @@ ++# git ls-files --others --exclude-from=.git/info/exclude ++# Lines that start with '#' are comments. ++# For a project mostly in C, the following would be a good set of ++# exclude patterns (uncomment them if you want to use them): ++# *.[oa] ++# *~ +diff -ruN u-boot-2014.04/.git/logs/HEAD u-boot-sunxi/.git/logs/HEAD +--- u-boot-2014.04/.git/logs/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/logs/HEAD 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++0000000000000000000000000000000000000000 509d96d4f1f602d62d36db660973249e16f9d088 Zoltan HERPAI wigyori@uid0.hu 1410015515 +0200 clone: from https://github.com/linux-sunxi/u-boot-sunxi +diff -ruN u-boot-2014.04/.git/logs/refs/heads/sunxi u-boot-sunxi/.git/logs/refs/heads/sunxi +--- u-boot-2014.04/.git/logs/refs/heads/sunxi 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/logs/refs/heads/sunxi 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++0000000000000000000000000000000000000000 509d96d4f1f602d62d36db660973249e16f9d088 Zoltan HERPAI wigyori@uid0.hu 1410015515 +0200 clone: from https://github.com/linux-sunxi/u-boot-sunxi +diff -ruN u-boot-2014.04/.git/logs/refs/remotes/origin/HEAD u-boot-sunxi/.git/logs/refs/remotes/origin/HEAD +--- u-boot-2014.04/.git/logs/refs/remotes/origin/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/logs/refs/remotes/origin/HEAD 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++0000000000000000000000000000000000000000 509d96d4f1f602d62d36db660973249e16f9d088 Zoltan HERPAI wigyori@uid0.hu 1410015515 +0200 clone: from https://github.com/linux-sunxi/u-boot-sunxi +Binary files u-boot-2014.04/.git/objects/pack/pack-67611423d2b8399a45fe3205d396caff441c8135.idx and u-boot-sunxi/.git/objects/pack/pack-67611423d2b8399a45fe3205d396caff441c8135.idx differ +Binary files u-boot-2014.04/.git/objects/pack/pack-67611423d2b8399a45fe3205d396caff441c8135.pack and u-boot-sunxi/.git/objects/pack/pack-67611423d2b8399a45fe3205d396caff441c8135.pack differ +diff -ruN u-boot-2014.04/.git/packed-refs u-boot-sunxi/.git/packed-refs +--- u-boot-2014.04/.git/packed-refs 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/packed-refs 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1,25 @@ ++# pack-refs with: peeled ++3212c6fd4beaa14a21a57e5241022702c986f82e refs/remotes/origin/lichee-dev ++c0860ba179bc0cf016831ceeeacd0dd4e287a860 refs/remotes/origin/lichee-dev-a20 ++1076d3bdd67db39f34bc91857c636525874441ae refs/remotes/origin/lichee/lichee-dev ++40b4fba701c1824cc60c7ab966f4a5dd674e947d refs/remotes/origin/lichee/lichee-dev-ICS ++cf54463fd782c690cf790ca35b5a15504b57c287 refs/remotes/origin/lichee/lichee-dev-mmc ++218f643881c0dabd7e40cdb21a757416fa80afb2 refs/remotes/origin/old/sunxi-current ++509d96d4f1f602d62d36db660973249e16f9d088 refs/remotes/origin/sunxi ++43fb1236c3330676f49220cc1dfc235eb0558e4c refs/remotes/origin/sunxi-patchqueue ++80fd9a5c5b87ba2f48f4a71b666839870e780be6 refs/remotes/origin/wip/a20 ++27113637710a574d1fb6325817ffa9ced7afe019 refs/tags/v2011.09-sun4i ++^22b38fa5c0348ac4f285f038999f9a617f98e73a ++9ba56441491542cd06b30c514e544d96b29ef801 refs/tags/v2011.09-sun4i-20120808 ++88eacf3372855579760ba6bc8fa3e0d4e53fdef8 refs/tags/v2012.10-sunxi ++1ae18d97d24c5d6dd4cb7949d8e5fb602728601c refs/tags/v2013.01-sunxi ++fc40799c144d035c595c4abe3032a03be8f0e2c4 refs/tags/v2013.01.01-sunxi ++90c8c0c88362d1e39bb1433f04b9a21bb1c74e45 refs/tags/v2013.04-sunxi ++57ff4519ba0f47f1647f7def5864ae4c9ef3e6a0 refs/tags/v2013.07-rc1-sunxi ++c416374795b584f025a80b1f81db215456567155 refs/tags/v2013.07-sunxi ++8969c6f654248ececdfcf05eb51de9a8bc0a8703 refs/tags/v2013.07-sunxi.2 ++88b1df7ee9c15c821a2209791f513b21596f21b4 refs/tags/v2013.07-sunxi.3 ++569c37da7dfd4ed93b6e8b5993df760b9ed18c8d refs/tags/v2013.07-sunxi.4 ++7a63a6882876b76e47746c1254e8cd1120a52b0d refs/tags/v2013.10-rc1-sunxi ++951e509384822e39149c22f44cde6a01f5105c40 refs/tags/v2013.10-rc2-sunxi ++09ef3a640a3eb58e66eedcf239193e2ab548e730 refs/tags/v2013.10-sunxi +diff -ruN u-boot-2014.04/.git/refs/heads/sunxi u-boot-sunxi/.git/refs/heads/sunxi +--- u-boot-2014.04/.git/refs/heads/sunxi 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/refs/heads/sunxi 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++509d96d4f1f602d62d36db660973249e16f9d088 +diff -ruN u-boot-2014.04/.git/refs/remotes/origin/HEAD u-boot-sunxi/.git/refs/remotes/origin/HEAD +--- u-boot-2014.04/.git/refs/remotes/origin/HEAD 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/.git/refs/remotes/origin/HEAD 2014-09-06 16:58:35.001953150 +0200 +@@ -0,0 +1 @@ ++ref: refs/remotes/origin/sunxi +diff -ruN u-boot-2014.04/include/axp152.h u-boot-sunxi/include/axp152.h +--- u-boot-2014.04/include/axp152.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/axp152.h 2014-09-06 16:58:36.397953109 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++int axp152_set_dcdc2(int mvolt); ++int axp152_set_dcdc3(int mvolt); ++int axp152_set_dcdc4(int mvolt); ++int axp152_set_ldo2(int mvolt); ++void axp152_poweroff(void); ++int axp152_init(void); +diff -ruN u-boot-2014.04/include/axp209.h u-boot-sunxi/include/axp209.h +--- u-boot-2014.04/include/axp209.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/axp209.h 2014-09-06 16:58:36.397953109 +0200 +@@ -0,0 +1,15 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++extern int axp209_set_dcdc2(int mvolt); ++extern int axp209_set_dcdc3(int mvolt); ++extern int axp209_set_ldo2(int mvolt); ++extern int axp209_set_ldo3(int mvolt); ++extern int axp209_set_ldo4(int mvolt); ++extern void axp209_poweroff(void); ++extern int axp209_init(void); ++extern int axp209_poweron_by_dc(void); ++extern int axp209_power_button(void); +diff -ruN u-boot-2014.04/include/axp221.h u-boot-sunxi/include/axp221.h +--- u-boot-2014.04/include/axp221.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/axp221.h 2014-09-06 16:58:36.397953109 +0200 +@@ -0,0 +1,30 @@ ++/* ++ * (C) Copyright 2013 Oliver Schinagl oliver@schinagl.nl ++ * ++ * X-Powers AXP221 Power Management IC driver ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#define AXP221_CHIP_ADDR 0x68 ++#define AXP221_CTRL_ADDR 0x3e ++#define AXP221_INIT_DATA 0x3e ++ ++#define AXP221_CHIP_ID 0x03 ++#define AXP221_OUTPUT_CTRL1 0x10 ++#define AXP221_OUTPUT_CTRL2 0x12 ++#define AXP221_OUTPUT_CTRL3 0x13 ++#define AXP221_DLDO1_CTRL 0x15 ++#define AXP221_DCDC1_CTRL 0x21 ++#define AXP221_DCDC2_CTRL 0x22 ++#define AXP221_DCDC3_CTRL 0x23 ++#define AXP221_DCDC4_CTRL 0x24 ++#define AXP221_DCDC5_CTRL 0x25 ++ ++int axp221_set_dcdc1(unsigned int mvolt); ++int axp221_set_dcdc2(unsigned int mvolt); ++int axp221_set_dcdc3(unsigned int mvolt); ++int axp221_set_dcdc4(unsigned int mvolt); ++int axp221_set_dcdc5(unsigned int mvolt); ++int axp221_set_dldo1(unsigned int mvolt); ++int axp221_init(void); +diff -ruN u-boot-2014.04/include/config_fallbacks.h u-boot-sunxi/include/config_fallbacks.h +--- u-boot-2014.04/include/config_fallbacks.h 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/include/config_fallbacks.h 2014-09-06 16:58:36.401953108 +0200 +@@ -55,6 +55,10 @@ + #define HAVE_BLOCK_DEVICE + #endif + ++#ifndef CONFIG_SYS_BOARD_NAME ++#define CONFIG_SYS_BOARD_NAME CONFIG_SYS_TARGET ++#endif ++ + #if (defined(CONFIG_PARTITION_UUIDS) || \ + defined(CONFIG_EFI_PARTITION) || \ + defined(CONFIG_RANDOM_UUID) || \ +diff -ruN u-boot-2014.04/include/configs/sun4i.h u-boot-sunxi/include/configs/sun4i.h +--- u-boot-2014.04/include/configs/sun4i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun4i.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * Configuration settings for the Allwinner A10 (sun4i) CPU ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++/* ++ * A10 specific configuration ++ */ ++#define CONFIG_SUN4I /* sun4i SoC generation */ ++#define CONFIG_CLK_FULL_SPEED 1008000000 ++ ++#define CONFIG_SYS_PROMPT "sun4i# " ++#define CONFIG_MACH_TYPE 4104 ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include <configs/sunxi-common.h> ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.04/include/configs/sun5i.h u-boot-sunxi/include/configs/sun5i.h +--- u-boot-2014.04/include/configs/sun5i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun5i.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * Configuration settings for the Allwinner A13 (sun5i) CPU ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++/* ++ * High Level Configuration Options ++ */ ++#define CONFIG_SUN5I /* sun5i SoC generation */ ++#define CONFIG_CLK_FULL_SPEED 1008000000 ++ ++#define CONFIG_SYS_PROMPT "sun5i# " ++#define CONFIG_MACH_TYPE 4138 ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include <configs/sunxi-common.h> ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.04/include/configs/sun6i.h u-boot-sunxi/include/configs/sun6i.h +--- u-boot-2014.04/include/configs/sun6i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun6i.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,43 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * (C) Copyright 2013 Maxime Ripard maxime.ripard@free-electrons.com ++ * ++ * Configuration settings for the Allwinner A31 (sun6i) CPU ++ * ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, ++ * MA 02111-1307 USA ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++/* ++ * A31 specific configuration ++ */ ++#define CONFIG_SUN6I /* sun6i SoC generation */ ++ ++#define CONFIG_SYS_PROMPT "sun6i# " ++#define CONFIG_MACH_TYPE 3892 ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include <configs/sunxi-common.h> ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.04/include/configs/sun7i.h u-boot-sunxi/include/configs/sun7i.h +--- u-boot-2014.04/include/configs/sun7i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun7i.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,30 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * ++ * Configuration settings for the Allwinner A20 (sun7i) CPU ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++/* ++ * A20 specific configuration ++ */ ++#define CONFIG_SUN7I /* sun7i SoC generation */ ++#define CONFIG_CLK_FULL_SPEED 912000000 ++ ++#define CONFIG_SYS_PROMPT "sun7i# " ++#define CONFIG_MACH_TYPE 4283 ++ ++#if defined(CONFIG_SYS_SECONDARY_ON) ++#define CONFIG_BOARD_POSTCLK_INIT 1 ++#endif ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include <configs/sunxi-common.h> ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.04/include/configs/sun8i.h u-boot-sunxi/include/configs/sun8i.h +--- u-boot-2014.04/include/configs/sun8i.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sun8i.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,28 @@ ++/* ++ * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net ++ * (C) Copyright 2013 Luke Kenneth Casson Leighton lkcl@lkcl.net ++ * (C) Copyright 2013 Maxime Ripard maxime.ripard@free-electrons.com ++ * (C) Copyright 2014 Chen-Yu Tsai wens@csie.org ++ * ++ * Configuration settings for the Allwinner A23 (sun8i) CPU ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef __CONFIG_H ++#define __CONFIG_H ++ ++/* ++ * A23 specific configuration ++ */ ++#define CONFIG_SUN8I /* sun8i SoC generation */ ++ ++#define CONFIG_SYS_PROMPT "sun8i# " ++#define CONFIG_MACH_TYPE 4137 ++ ++/* ++ * Include common sunxi configuration where most the settings are ++ */ ++#include <configs/sunxi-common.h> ++ ++#endif /* __CONFIG_H */ +diff -ruN u-boot-2014.04/include/configs/sunxi-common.h u-boot-sunxi/include/configs/sunxi-common.h +--- u-boot-2014.04/include/configs/sunxi-common.h 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/include/configs/sunxi-common.h 2014-09-06 16:58:36.461953107 +0200 +@@ -0,0 +1,427 @@ ++/* ++ * (C) Copyright 2012-2012 Henrik Nordstrom henrik@henriknordstrom.net ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * Configuration settings for the Allwinner sunxi series of boards. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_COMMON_CONFIG_H ++#define _SUNXI_COMMON_CONFIG_H ++ ++/* ++ * High Level Configuration Options ++ */ ++#define CONFIG_SUNXI /* sunxi family */ ++#ifdef CONFIG_SPL_BUILD ++#ifndef CONFIG_SPL_FEL ++#define CONFIG_SYS_THUMB_BUILD /* Thumbs mode to save space in SPL */ ++#endif ++#endif ++ ++#include <asm/arch/cpu.h> /* get chip and board defs */ ++ ++#define CONFIG_SYS_TEXT_BASE 0x4a000000 ++ ++/* ++ * Display CPU and Board information ++ */ ++#define CONFIG_DISPLAY_CPUINFO ++#define CONFIG_DISPLAY_BOARDINFO ++ ++/* Serial & console */ ++#define CONFIG_SYS_NS16550 ++#define CONFIG_SYS_NS16550_SERIAL ++/* ns16550 reg in the low bits of cpu reg */ ++#define CONFIG_SYS_NS16550_REG_SIZE -4 ++#define CONFIG_SYS_NS16550_CLK 24000000 ++#define CONFIG_SYS_NS16550_COM1 SUNXI_UART0_BASE ++#define CONFIG_SYS_NS16550_COM2 SUNXI_UART1_BASE ++#define CONFIG_SYS_NS16550_COM3 SUNXI_UART2_BASE ++#define CONFIG_SYS_NS16550_COM4 SUNXI_UART3_BASE ++#define CONFIG_SYS_NS16550_COM5 SUNXI_R_UART_BASE ++ ++/* DRAM Base */ ++#define CONFIG_SYS_SDRAM_BASE 0x40000000 ++#define CONFIG_SYS_INIT_RAM_ADDR 0x0 ++#define CONFIG_SYS_INIT_RAM_SIZE 0x8000 /* 32 KiB */ ++ ++#define CONFIG_SYS_INIT_SP_OFFSET \ ++ (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) ++#define CONFIG_SYS_INIT_SP_ADDR \ ++ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) ++ ++/* A10 has 1 banks of DRAM, we use only bank 1 in U-Boot */ ++#define CONFIG_NR_DRAM_BANKS 1 ++#define PHYS_SDRAM_0 CONFIG_SYS_SDRAM_BASE ++#if defined(CONFIG_SUN6I) || defined(CONFIG_SUN7I) ++#define PHYS_SDRAM_0_SIZE 0x80000000 /* 2 GiB */ ++#else ++#define PHYS_SDRAM_0_SIZE 0x40000000 /* 1 GiB */ ++#endif ++#if 0 ++/* Nand config */ ++#define CONFIG_NAND ++#define CONFIG_NAND_SUNXI ++#define CONFIG_CMD_NAND /* NAND support */ ++#define CONFIG_SYS_MAX_NAND_DEVICE 1 ++#define CONFIG_SYS_NAND_BASE 0x00 ++#endif ++ ++#define CONFIG_CMD_MEMORY ++#define CONFIG_CMD_SETEXPR ++ ++#define CONFIG_SETUP_MEMORY_TAGS ++#define CONFIG_CMDLINE_TAG ++#define CONFIG_INITRD_TAG ++ ++/* mmc config */ ++/* Can't use MMC slot 0 if the UART is directed there */ ++#if !defined CONFIG_UART0_PORT_F || CONFIG_MMC_SUNXI_SLOT != 0 ++#define CONFIG_MMC ++#define CONFIG_GENERIC_MMC ++#define CONFIG_CMD_MMC ++#define CONFIG_MMC_SUNXI ++#ifndef CONFIG_MMC_SUNXI_SLOT ++#define CONFIG_MMC_SUNXI_SLOT 0 ++#endif ++#define CONFIG_ENV_IS_IN_MMC ++#define CONFIG_SYS_MMC_ENV_DEV 0 /* first detected MMC controller */ ++#endif ++ ++/* 4MB of malloc() pool */ ++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (4 << 20)) ++ ++/* ++ * Miscellaneous configurable options ++ */ ++#define CONFIG_CMD_ECHO ++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ ++#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */ ++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ ++#define CONFIG_SYS_GENERIC_BOARD ++ ++/* Boot Argument Buffer Size */ ++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE ++ ++#define CONFIG_SYS_LOAD_ADDR 0x48000000 /* default load address */ ++ ++/* standalone support */ ++#define CONFIG_STANDALONE_LOAD_ADDR 0x48000000 ++ ++#define CONFIG_SYS_HZ 1000 ++ ++/* baudrate */ ++#define CONFIG_BAUDRATE 115200 ++ ++/* The stack sizes are set up in start.S using the settings below */ ++#define CONFIG_STACKSIZE (256 << 10) /* 256 KiB */ ++ ++/* FLASH and environment organization */ ++ ++#define CONFIG_SYS_NO_FLASH ++ ++#define CONFIG_SYS_MONITOR_LEN (512 << 10) /* 512 KiB */ ++#define CONFIG_IDENT_STRING " Allwinner Technology" ++ ++#define CONFIG_ENV_OFFSET (544 << 10) /* (8 + 24 + 512) KiB */ ++#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */ ++ ++#ifdef CONFIG_SPL_FEL ++#define RUN_BOOT_RAM "run boot_ram;" ++#else ++#define RUN_BOOT_RAM "" ++#endif ++ ++#define CONFIG_BOOTCOMMAND \ ++ RUN_BOOT_RAM \ ++ "if run loadbootenv; then " \ ++ "echo Loaded environment from ${bootenv};" \ ++ "env import -t ${scriptaddr} ${filesize};" \ ++ "fi;" \ ++ "if test -n \"${uenvcmd}\"; then " \ ++ "echo Running uenvcmd ...;" \ ++ "run uenvcmd;" \ ++ "fi;" \ ++ "if run loadbootscr; then "\ ++ "echo Jumping to ${bootscr};" \ ++ "source ${scriptaddr};" \ ++ "fi;" \ ++ "run autoboot;" \ ++ "" ++ ++#ifdef CONFIG_CMD_WATCHDOG ++#define RESET_WATCHDOG "watchdog 0" ++#else ++#define RESET_WATCHDOG "true" ++#endif ++ ++#define CONFIG_EXTRA_ENV_SETTINGS \ ++ "bootm_size=0x10000000\0" \ ++ "console=ttyS0,115200\0" \ ++ "panicarg=panic=10\0" \ ++ "extraargs=\0" \ ++ "loglevel=8\0" \ ++ "scriptaddr=0x44000000\0" \ ++ "device=mmc\0" \ ++ "partition=0:1\0" \ ++ "setargs=" \ ++ "if test -z \\"$root\\"; then"\ ++ " if test \\"$bootpath\\" = "/boot/"; then"\ ++ " root="/dev/mmcblk0p1 rootwait";"\ ++ " else" \ ++ " root="/dev/mmcblk0p2 rootwait";"\ ++ " fi;"\ ++ " fi;"\ ++ " setenv bootargs console=${console} root=${root}" \ ++ " loglevel=${loglevel} ${panicarg} ${extraargs}" \ ++ "\0" \ ++ "kernel=uImage\0" \ ++ "bootenv=uEnv.txt\0" \ ++ "bootscr=boot.scr\0" \ ++ "script=script.bin\0" \ ++ "loadbootscr=" \ ++ "fatload $device $partition $scriptaddr ${bootscr}" \ ++ " || " \ ++ "ext2load $device $partition $scriptaddr boot/${bootscr}" \ ++ " ||" \ ++ "ext2load $device $partition $scriptaddr ${bootscr}" \ ++ "\0" \ ++ "loadbootenv=" \ ++ "fatload $device $partition $scriptaddr ${bootenv}" \ ++ " || " \ ++ "ext2load $device $partition $scriptaddr boot/${bootenv}" \ ++ " || " \ ++ "ext2load $device $partition $scriptaddr ${bootenv}" \ ++ "\0" \ ++ "loadkernel=" \ ++ "if "\ ++ "bootpath=/boot/" \ ++ " && " \ ++ "ext2load $device $partition 0x43000000 ${bootpath}${script}" \ ++ " && " \ ++ "ext2load $device $partition 0x48000000 ${bootpath}${kernel}" \ ++ ";then true; elif " \ ++ "bootpath=/" \ ++ " && " \ ++ "fatload $device $partition 0x43000000 ${script}" \ ++ " && " \ ++ "fatload $device $partition 0x48000000 ${kernel}" \ ++ ";then true; elif " \ ++ "bootpath=/" \ ++ " && " \ ++ "ext2load $device $partition 0x43000000 ${bootpath}${script}" \ ++ " && " \ ++ "ext2load $device $partition 0x48000000 ${bootpath}${kernel}" \ ++ ";then true; else "\ ++ "false" \ ++ ";fi" \ ++ "\0" \ ++ "autoboot=" \ ++ "run loadkernel" \ ++ " && " \ ++ "run setargs" \ ++ " && " \ ++ RESET_WATCHDOG \ ++ " && " \ ++ "bootm 0x48000000" \ ++ "\0" \ ++ "boot_ram=" \ ++ "saved_stdout=$stdout;setenv stdout nc;"\ ++ "if iminfo 0x41000000; then" \ ++ " " RESET_WATCHDOG ";"\ ++ " setenv stdout $saved_stdout;" \ ++ " source 0x41000000;" \ ++ "else" \ ++ " setenv stdout $saved_stdout;" \ ++ "fi" \ ++ "\0" \ ++ "" ++ ++#define CONFIG_SYS_BOOT_GET_CMDLINE ++ ++#include <config_cmd_default.h> ++ ++#define CONFIG_FAT_WRITE /* enable write access */ ++ ++#define CONFIG_SPL_FRAMEWORK ++#define CONFIG_SPL_LIBCOMMON_SUPPORT ++#define CONFIG_SPL_SERIAL_SUPPORT ++#define CONFIG_SPL_LIBGENERIC_SUPPORT ++#define CONFIG_SPL_DISPLAY_PRINT ++ ++/* Falcon boot mode support */ ++/* Disabled by default on sun4i/sun7i. Many GCC versions produces a too ++ * large SPL for A10/A20 with this on. sun5i however accepts a much larger ++ * SPL ++ */ ++#if defined( CONFIG_SUN5I ) || defined ( CONFIG_SYS_THUMB_BUILD ) ++#define CONFIG_SPL_OS_BOOT ++#endif ++ ++#ifdef CONFIG_SPL_FEL ++ ++#define CONFIG_SPL ++#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds" ++#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/armv7/sunxi" ++#define CONFIG_SPL_TEXT_BASE 0x2000 ++#define CONFIG_SPL_MAX_SIZE 0x4000 /* 16 KiB */ ++ ++#else /* CONFIG_SPL */ ++ ++#define CONFIG_SPL_BSS_START_ADDR 0x4ff80000 ++#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 /* 512 KiB */ ++ ++#define CONFIG_SPL_TEXT_BASE 0x20 /* sram start+header */ ++#ifdef CONFIG_SUN5I ++#define CONFIG_SPL_MAX_SIZE 0x75e0 /* 7748+ is used */ ++#else ++#define CONFIG_SPL_MAX_SIZE 0x5fe0 /* 24KB on sun4i/sun7i */ ++#endif ++ ++#define CONFIG_SPL_LIBDISK_SUPPORT ++#define CONFIG_SPL_MMC_SUPPORT ++ ++#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds" ++ ++#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 80 /* 40KiB */ ++#define CONFIG_SPL_PAD_TO 32768 /* decimal for 'dd' */ ++ ++#endif /* CONFIG_SPL */ ++/* end of 32 KiB in sram */ ++#define LOW_LEVEL_SRAM_STACK 0x00008000 /* End of sram */ ++#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK ++#define CONFIG_SYS_SPL_MALLOC_START 0x4ff00000 ++#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00080000 /* 512 KiB */ ++ ++#ifdef CONFIG_SPL_OS_BOOT ++#define CONFIG_CMD_SPL ++#define CONFIG_SYS_SPL_ARGS_ADDR (PHYS_SDRAM_0 + 0x100) ++#ifdef CONFIG_SPL_MMC_SUPPORT ++#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR 1344 ++#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS 256 ++#define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR 1600 ++#endif ++#endif ++ ++#undef CONFIG_CMD_FPGA ++#undef CONFIG_CMD_NET ++#undef CONFIG_CMD_NFS ++ ++/* I2C */ ++#if !defined CONFIG_SUN6I && !defined CONFIG_SUN8I ++#define CONFIG_SPL_I2C_SUPPORT ++#endif ++/* No CONFIG_SYS_I2C as we use the non converted mvtwsi driver */ ++#define CONFIG_HARD_I2C ++#define CONFIG_SYS_I2C_SUNXI ++#define CONFIG_SYS_I2C_SPEED 400000 ++#define CONFIG_SYS_I2C_SLAVE 0x7f ++#define CONFIG_CMD_I2C ++ ++/* Watchdog */ ++#if 0 ++#define CONFIG_WATCHDOG /* automatic watchdog support */ ++#define CONFIG_CMD_WATCHDOG /* watchdog command setting the watchdog timeout */ ++#endif ++ ++/* GPIO */ ++#define CONFIG_SUNXI_GPIO ++#define CONFIG_CMD_GPIO ++ ++/* PMU */ ++#if !defined CONFIG_AXP152_POWER && !defined CONFIG_AXP221_POWER && !defined CONFIG_NO_AXP ++#define CONFIG_AXP209_POWER ++#endif ++#if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || defined CONFIG_AXP221_POWER ++#define CONFIG_SPL_POWER_SUPPORT ++#endif ++ ++#ifdef CONFIG_STATUSLED ++#define STATUS_LED_BIT CONFIG_STATUSLED ++#endif ++#ifdef CONFIG_STATUSLED1 ++#define STATUS_LED_BIT1 CONFIG_STATUSLED1 ++#endif ++#ifdef CONFIG_STATUSLED2 ++#define STATUS_LED_BIT2 CONFIG_STATUSLED2 ++#endif ++#ifdef CONFIG_STATUSLED3 ++#define STATUS_LED_BIT3 CONFIG_STATUSLED3 ++#endif ++ ++#ifndef CONFIG_SPL_BUILD ++#ifdef STATUS_LED_BIT ++#define CONFIG_GPIO_LED ++#define CONFIG_STATUS_LED ++#ifndef STATUS_LED_BOOT ++#define STATUS_LED_BOOT 0 ++#endif ++#ifndef STATUS_LED_STATE ++#define STATUS_LED_STATE STATUS_LED_ON ++#define STATUS_LED_PERIOD 1 ++#endif ++#ifndef STATUS_LED_STATE1 ++#define STATUS_LED_STATE1 STATUS_LED_OFF ++#define STATUS_LED_PERIOD1 1 ++#endif ++#ifndef STATUS_LED_STATE2 ++#define STATUS_LED_STATE2 STATUS_LED_OFF ++#define STATUS_LED_PERIOD2 1 ++#endif ++#ifndef STATUS_LED_STATE3 ++#define STATUS_LED_STATE3 STATUS_LED_OFF ++#define STATUS_LED_PERIOD3 1 ++#endif ++#define CONFIG_BOARD_SPECIFIC_LED ++#define CONFIG_CMD_LED ++#endif ++#endif ++ ++/* Define this to have serial channel 1 (UART0) redirected to SD port */ ++/* #define CONFIG_UART0_PORT_F */ ++ ++#ifndef CONFIG_CONS_INDEX ++#define CONFIG_CONS_INDEX 1 /* UART0 */ ++#endif ++ ++/* Ethernet support */ ++#ifdef CONFIG_SUNXI_EMAC ++#define CONFIG_MII /* MII PHY management */ ++#endif ++ ++#ifdef CONFIG_SUNXI_GMAC ++#define CONFIG_DESIGNWARE_ETH /* GMAC can use designware driver */ ++#define CONFIG_DW_AUTONEG ++#define CONFIG_PHY_GIGE /* GMAC can use gigabit PHY */ ++#define CONFIG_PHY_ADDR 1 ++#define CONFIG_MII /* MII PHY management */ ++#define CONFIG_PHYLIB ++#endif ++ ++#ifdef CONFIG_CMD_NET ++#define CONFIG_CMD_NFS ++#define CONFIG_CMD_DNS ++#define CONFIG_NETCONSOLE ++#define CONFIG_BOOTP_DNS2 ++#define CONFIG_BOOTP_SEND_HOSTNAME ++#endif ++ ++#if !defined CONFIG_ENV_IS_IN_MMC && \ ++ !defined CONFIG_ENV_IS_IN_NAND && \ ++ !defined CONFIG_ENV_IS_IN_FAT && \ ++ !defined CONFIG_ENV_IS_IN_SPI_FLASH ++#define CONFIG_ENV_IS_NOWHERE ++#endif ++ ++#define CONFIG_MISC_INIT_R ++ ++#ifndef CONFIG_SPL_BUILD ++#include <config_distro_defaults.h> ++#endif ++ ++#endif /* _SUNXI_COMMON_CONFIG_H */ +diff -ruN u-boot-2014.04/include/netdev.h u-boot-sunxi/include/netdev.h +--- u-boot-2014.04/include/netdev.h 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/include/netdev.h 2014-09-06 16:58:36.485953106 +0200 +@@ -79,7 +79,8 @@ + int skge_initialize(bd_t *bis); + int smc91111_initialize(u8 dev_num, int base_addr); + int smc911x_initialize(u8 dev_num, int base_addr); +-int sunxi_wemac_initialize(bd_t *bis); ++int sunxi_emac_initialize(bd_t *bis); ++int sunxi_gmac_initialize(bd_t *bis); + int tsi108_eth_initialize(bd_t *bis); + int uec_standard_init(bd_t *bis); + int uli526x_initialize(bd_t *bis); +diff -ruN u-boot-2014.04/Makefile u-boot-sunxi/Makefile +--- u-boot-2014.04/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/Makefile 2014-09-06 16:58:35.065953148 +0200 +@@ -870,6 +870,13 @@ + u-boot.spr: spl/u-boot-spl.img u-boot.img FORCE + $(call if_changed,pad_cat) + ++ifneq ($(CONFIG_SUNXI),) ++OBJCOPYFLAGS_u-boot-sunxi-with-spl.bin = -I binary -O binary \ ++ --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff ++u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.img FORCE ++ $(call if_changed,pad_cat) ++endif ++ + ifneq ($(CONFIG_TEGRA),) + OBJCOPYFLAGS_u-boot-nodtb-tegra.bin = -O binary --pad-to=$(CONFIG_SYS_TEXT_BASE) + u-boot-nodtb-tegra.bin: spl/u-boot-spl u-boot.bin FORCE +@@ -1081,6 +1088,9 @@ + spl/u-boot-spl: tools prepare + $(Q)$(MAKE) obj=spl -f $(srctree)/spl/Makefile all + ++spl/sunxi-spl.bin: spl/u-boot-spl ++ @: ++ + tpl/u-boot-tpl.bin: tools prepare + $(Q)$(MAKE) obj=tpl -f $(srctree)/spl/Makefile all CONFIG_TPL_BUILD=y + +diff -ruN u-boot-2014.04/mkconfig u-boot-sunxi/mkconfig +--- u-boot-2014.04/mkconfig 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/mkconfig 2014-09-06 16:58:36.509953105 +0200 +@@ -174,6 +174,7 @@ + echo "#define CONFIG_SYS_ARCH "${arch}"" >> config.h + echo "#define CONFIG_SYS_CPU "${cpu}"" >> config.h + echo "#define CONFIG_SYS_BOARD "${board}"" >> config.h ++echo "#define CONFIG_SYS_TARGET "${BOARD_NAME}"" >> config.h + + [ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR "${vendor}"" >> config.h + +diff -ruN u-boot-2014.04/snapshot.commit u-boot-sunxi/snapshot.commit +--- u-boot-2014.04/snapshot.commit 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/snapshot.commit 2014-09-06 16:58:36.521953105 +0200 +@@ -1 +1 @@ +-dda0dbfc69f3d560c87f5be85f127ed862ea6721 Mon, 14 Apr 2014 15:19:24 -0400 ++$Format:%H %cD$ +diff -ruN u-boot-2014.04/spl/Makefile u-boot-sunxi/spl/Makefile +--- u-boot-2014.04/spl/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/spl/Makefile 2014-09-06 16:58:36.521953105 +0200 +@@ -188,6 +188,12 @@ + ALL-y += $(obj)/$(BOARD)-spl.bin + endif + ++ifdef CONFIG_SUNXI ++ifndef CONFIG_SPL_FEL ++ALL-y += $(obj)/sunxi-spl.bin ++endif ++endif ++ + all: $(ALL-y) + + ifdef CONFIG_SAMSUNG +@@ -215,6 +221,13 @@ + LDFLAGS_$(SPL_BIN) += -Ttext $(CONFIG_SPL_TEXT_BASE) + endif + ++ifdef CONFIG_SUNXI ++quiet_cmd_mksunxiboot = MKSUNXI $@ ++cmd_mksunxiboot = $(objtree)/tools/mksunxiboot $< $@ ++$(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin ++ $(call if_changed,mksunxiboot) ++endif ++ + quiet_cmd_u-boot-spl = LD $@ + cmd_u-boot-spl = cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-init)) --start-group \ +diff -ruN u-boot-2014.04/tools/.gitignore u-boot-sunxi/tools/.gitignore +--- u-boot-2014.04/tools/.gitignore 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/tools/.gitignore 2014-09-06 16:58:36.521953105 +0200 +@@ -9,6 +9,7 @@ + /mkexynosspl + /mpc86x_clk + /mxsboot ++/mksunxiboot + /ncb + /proftool + /relocate-rela +diff -ruN u-boot-2014.04/tools/Makefile u-boot-sunxi/tools/Makefile +--- u-boot-2014.04/tools/Makefile 2014-04-14 21:19:24.000000000 +0200 ++++ u-boot-sunxi/tools/Makefile 2014-09-06 16:58:36.521953105 +0200 +@@ -120,6 +120,8 @@ + hostprogs-$(CONFIG_MX28) += mxsboot$(SFX) + HOSTCFLAGS_mxsboot$(SFX).o := -pedantic + ++hostprogs-$(CONFIG_SUNXI) += mksunxiboot$(SFX) ++ + hostprogs-$(CONFIG_NETCONSOLE) += ncb$(SFX) + hostprogs-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX) + +diff -ruN u-boot-2014.04/tools/mksunxiboot.c u-boot-sunxi/tools/mksunxiboot.c +--- u-boot-2014.04/tools/mksunxiboot.c 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/tools/mksunxiboot.c 2014-09-06 16:58:36.529953105 +0200 +@@ -0,0 +1,140 @@ ++/* ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie tangliang@allwinnertech.com ++ * ++ * a simple tool to generate bootable image for sunxi platform. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++#include <fcntl.h> ++#include <stdio.h> ++#include <unistd.h> ++#include <stdlib.h> ++#include <string.h> ++#include <errno.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++ ++/* boot head definition from sun4i boot code */ ++struct boot_file_head { ++ uint32_t b_instruction; /* one intruction jumping to real code */ ++ uint8_t magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */ ++ uint32_t check_sum; /* generated by PC */ ++ uint32_t length; /* generated by PC */ ++ /* ++ * We use a simplified header, only filling in what is needed ++ * by the boot ROM. To be compatible with Allwinner tools we ++ * would need to implement the proper fields here instead of ++ * padding. ++ */ ++ uint8_t pad[12]; /* align to 32 bytes */ ++}; ++ ++#define BOOT0_MAGIC "eGON.BT0" ++#define STAMP_VALUE 0x5F0A6C39 ++ ++/* check sum functon from sun4i boot code */ ++int gen_check_sum(struct boot_file_head *head_p) ++{ ++ uint32_t length; ++ uint32_t *buf; ++ uint32_t loop; ++ uint32_t i; ++ uint32_t sum; ++ ++ length = head_p->length; ++ if ((length & 0x3) != 0) /* must 4-byte-aligned */ ++ return -1; ++ buf = (uint32_t *)head_p; ++ head_p->check_sum = STAMP_VALUE; /* fill stamp */ ++ loop = length >> 2; ++ ++ /* calculate the sum */ ++ for (i = 0, sum = 0; i < loop; i++) ++ sum += buf[i]; ++ ++ /* write back check sum */ ++ head_p->check_sum = sum; ++ ++ return 0; ++} ++ ++#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a)-1) ++#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) ++ ++#define SUN4I_SRAM_SIZE 0x7600 /* 0x7748+ is used by BROM */ ++#define SRAM_LOAD_MAX_SIZE (SUN4I_SRAM_SIZE - sizeof(struct boot_file_head)) ++#define BLOCK_SIZE 512 ++ ++struct boot_img { ++ struct boot_file_head header; ++ char code[SRAM_LOAD_MAX_SIZE]; ++ char pad[BLOCK_SIZE]; ++}; ++ ++int main(int argc, char *argv[]) ++{ ++ int fd_in, fd_out; ++ struct boot_img img; ++ unsigned file_size; ++ int count; ++ ++ if (argc < 2) { ++ printf("\tThis program makes an input bin file to sun4i " \ ++ "bootable image.\n" \ ++ "\tUsage: %s input_file out_putfile\n", argv[0]); ++ return EXIT_FAILURE; ++ } ++ ++ fd_in = open(argv[1], O_RDONLY); ++ if (fd_in < 0) { ++ perror("Open input file"); ++ return EXIT_FAILURE; ++ } ++ ++ memset(img.pad, 0, BLOCK_SIZE); ++ ++ /* get input file size */ ++ file_size = lseek(fd_in, 0, SEEK_END); ++ ++ if (file_size > SRAM_LOAD_MAX_SIZE) { ++ fprintf(stderr, "ERROR: File too large!\n"); ++ return EXIT_FAILURE; ++ } ++ ++ fd_out = open(argv[2], O_WRONLY | O_CREAT, 0666); ++ if (fd_out < 0) { ++ perror("Open output file"); ++ return EXIT_FAILURE; ++ } ++ ++ /* read file to buffer to calculate checksum */ ++ lseek(fd_in, 0, SEEK_SET); ++ count = read(fd_in, img.code, file_size); ++ if (count != file_size) { ++ perror("Reading input image"); ++ return EXIT_FAILURE; ++ } ++ ++ /* fill the header */ ++ img.header.b_instruction = /* b instruction */ ++ 0xEA000000 | /* jump to the first instr after the header */ ++ ((sizeof(struct boot_file_head) / sizeof(int) - 2) ++ & 0x00FFFFFF); ++ memcpy(img.header.magic, BOOT0_MAGIC, 8); /* no '0' termination */ ++ img.header.length = ++ ALIGN(file_size + sizeof(struct boot_file_head), BLOCK_SIZE); ++ gen_check_sum(&img.header); ++ ++ count = write(fd_out, &img, img.header.length); ++ if (count != img.header.length) { ++ perror("Writing output"); ++ return EXIT_FAILURE; ++ } ++ ++ close(fd_in); ++ close(fd_out); ++ ++ return EXIT_SUCCESS; ++} +diff -ruN u-boot-2014.04/tools/mksunxiboot.README u-boot-sunxi/tools/mksunxiboot.README +--- u-boot-2014.04/tools/mksunxiboot.README 1970-01-01 01:00:00.000000000 +0100 ++++ u-boot-sunxi/tools/mksunxiboot.README 2014-09-06 16:58:36.529953105 +0200 +@@ -0,0 +1,13 @@ ++This program make a arm binary file can be loaded by Allwinner A10 and related ++chips from storage media such as nand and mmc. ++ ++More information about A10 boot, please refer to ++http://rhombus-tech.net/allwinner_a10/a10_boot_process/ ++ ++To compile this program, just type make, you will get 'mksunxiboot'. ++ ++To use it, ++$./mksunxiboot u-boot.bin u-boot-mmc.bin ++then you can write it to a mmc card with dd. ++$sudo dd if=u-boot-mmc.bin of=/dev/sdb bs=1024 seek=8 ++then insert your mmc card to your A10 tablet, you can boot from mmc card. diff --git a/src/patches/u-boot/sunxi/002-uboot-jwrdegoede-psci-support.patch b/src/patches/u-boot/sunxi/002-uboot-jwrdegoede-psci-support.patch new file mode 100644 index 0000000..65407aa --- /dev/null +++ b/src/patches/u-boot/sunxi/002-uboot-jwrdegoede-psci-support.patch @@ -0,0 +1,1495 @@ +From 86f31982ac62e80fe586cad2e0a49a7b22e3d4ee Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:07 +0000 +Subject: [PATCH] ARM: HYP/non-sec: move switch to non-sec to the last boot + phase + +Having the switch to non-secure in the "prep" phase is causing +all kind of troubles, as that stage can be called multiple times. + +Instead, move the switch to non-secure to the last possible phase, +when there is no turning back anymore. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/lib/bootm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c +index 47ee070..10634a4 100644 +--- a/arch/arm/lib/bootm.c ++++ b/arch/arm/lib/bootm.c +@@ -242,7 +242,6 @@ static void boot_prep_linux(bootm_headers_t *images) + printf("FDT and ATAGS support not compiled in - hanging\n"); + hang(); + } +- do_nonsec_virt_switch(); + } + + /* Subcommand: GO */ +@@ -287,8 +286,10 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) + else + r2 = gd->bd->bi_boot_params; + +- if (!fake) ++ if (!fake) { ++ do_nonsec_virt_switch(); + kernel_entry(0, machid, r2); ++ } + #endif + } + +From c26d288f6cbc6d53219001d42476f314c403257b Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:08 +0000 +Subject: [PATCH] ARM: HYP/non-sec: add a barrier after setting SCR.NS==1 + +A CP15 instruction execution can be reordered, requiring an +isb to be sure it is executed in program order. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/nonsec_virt.S | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S +index 6367e09..12de5c2 100644 +--- a/arch/arm/cpu/armv7/nonsec_virt.S ++++ b/arch/arm/cpu/armv7/nonsec_virt.S +@@ -46,6 +46,7 @@ _secure_monitor: + #endif + + mcr p15, 0, r1, c1, c1, 0 @ write SCR (with NS bit set) ++ isb + + #ifdef CONFIG_ARMV7_VIRT + mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value +From 06feeea3c84cc58ff3d5c19f6a430886495f86ce Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:09 +0000 +Subject: [PATCH] ARM: non-sec: reset CNTVOFF to zero + +Before switching to non-secure, make sure that CNTVOFF is set +to zero on all CPUs. Otherwise, kernel running in non-secure +without HYP enabled (hence using virtual timers) may observe +timers that are not synchronized, effectively seeing time +going backward... + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/nonsec_virt.S | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S +index 12de5c2..b5c946f 100644 +--- a/arch/arm/cpu/armv7/nonsec_virt.S ++++ b/arch/arm/cpu/armv7/nonsec_virt.S +@@ -38,10 +38,10 @@ _secure_monitor: + bic r1, r1, #0x4e @ clear IRQ, FIQ, EA, nET bits + orr r1, r1, #0x31 @ enable NS, AW, FW bits + +-#ifdef CONFIG_ARMV7_VIRT + mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 + and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits + cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT) ++#ifdef CONFIG_ARMV7_VIRT + orreq r1, r1, #0x100 @ allow HVC instruction + #endif + +@@ -52,7 +52,14 @@ _secure_monitor: + mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value + mcreq p15, 4, r0, c12, c0, 0 @ write HVBAR + #endif ++ bne 1f + ++ @ Reset CNTVOFF to 0 before leaving monitor mode ++ mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 ++ ands r0, r0, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits ++ movne r0, #0 ++ mcrrne p15, 4, r0, r0, c14 @ Reset CNTVOFF to zero ++1: + movs pc, lr @ return to non-secure SVC + + _hyp_trap: +From 054bcf5147ff5a20298bce5b3bdfbf3e1c797594 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:10 +0000 +Subject: [PATCH] ARM: add missing HYP mode constant + +In order to be able to use the various mode constants (far more +readable than random hex values), add the missing HYP and A +values. + +Also update arm/lib/interrupts.c to display HYP instead of an +unknown value. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/include/asm/proc-armv/ptrace.h | 2 ++ + arch/arm/lib/interrupts.c | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/include/asm/proc-armv/ptrace.h b/arch/arm/include/asm/proc-armv/ptrace.h +index 21aef58..71df5a9 100644 +--- a/arch/arm/include/asm/proc-armv/ptrace.h ++++ b/arch/arm/include/asm/proc-armv/ptrace.h +@@ -38,12 +38,14 @@ struct pt_regs { + #define IRQ_MODE 0x12 + #define SVC_MODE 0x13 + #define ABT_MODE 0x17 ++#define HYP_MODE 0x1a + #define UND_MODE 0x1b + #define SYSTEM_MODE 0x1f + #define MODE_MASK 0x1f + #define T_BIT 0x20 + #define F_BIT 0x40 + #define I_BIT 0x80 ++#define A_BIT 0x100 + #define CC_V_BIT (1 << 28) + #define CC_C_BIT (1 << 29) + #define CC_Z_BIT (1 << 30) +diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c +index 758b013..f6b7c03 100644 +--- a/arch/arm/lib/interrupts.c ++++ b/arch/arm/lib/interrupts.c +@@ -103,7 +103,7 @@ void show_regs (struct pt_regs *regs) + "UK12_26", "UK13_26", "UK14_26", "UK15_26", + "USER_32", "FIQ_32", "IRQ_32", "SVC_32", + "UK4_32", "UK5_32", "UK6_32", "ABT_32", +- "UK8_32", "UK9_32", "UK10_32", "UND_32", ++ "UK8_32", "UK9_32", "HYP_32", "UND_32", + "UK12_32", "UK13_32", "UK14_32", "SYS_32", + }; + +From 213a8d9b7e613210d3c7d8b99c95b454ad0527d8 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:11 +0000 +Subject: [PATCH] ARM: HYP/non-sec: add separate section for secure code + +In anticipation of refactoring the HYP/non-secure code to run +from secure RAM, add a new linker section that will contain that +code. + +Nothing is using it just yet. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/config.mk | 2 +- + arch/arm/cpu/u-boot.lds | 30 ++++++++++++++++++++++++++++++ + arch/arm/lib/sections.c | 2 ++ + 3 files changed, 33 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/config.mk b/arch/arm/config.mk +index 66ecc2e..2bdfca5 100644 +--- a/arch/arm/config.mk ++++ b/arch/arm/config.mk +@@ -113,7 +113,7 @@ endif + ifdef CONFIG_ARM64 + OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn + else +-OBJCOPYFLAGS += -j .text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn ++OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn + endif + + ifneq ($(CONFIG_IMX_CONFIG),) +diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds +index 33c1f99..f45885d 100644 +--- a/arch/arm/cpu/u-boot.lds ++++ b/arch/arm/cpu/u-boot.lds +@@ -7,6 +7,8 @@ + * SPDX-License-Identifier: GPL-2.0+ + */ + ++#include <config.h> ++ + OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") + OUTPUT_ARCH(arm) + ENTRY(_start) +@@ -22,6 +24,34 @@ SECTIONS + *(.text*) + } + ++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) || defined(CONFIG_ARMV7_PSCI) ++ ++#ifndef CONFIG_ARMV7_SECURE_BASE ++#define CONFIG_ARMV7_SECURE_BASE ++#endif ++ ++ .__secure_start : { ++ . = ALIGN(0x1000); ++ *(.__secure_start) ++ } ++ ++ .secure_text CONFIG_ARMV7_SECURE_BASE : ++ AT(ADDR(.__secure_start) + SIZEOF(.__secure_start)) ++ { ++ *(._secure.text) ++ } ++ ++ . = LOADADDR(.__secure_start) + ++ SIZEOF(.__secure_start) + ++ SIZEOF(.secure_text); ++ ++ __secure_end_lma = .; ++ .__secure_end : AT(__secure_end_lma) { ++ *(.__secure_end) ++ LONG(0x1d1071c); /* Must output something to reset LMA */ ++ } ++#endif ++ + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + +diff --git a/arch/arm/lib/sections.c b/arch/arm/lib/sections.c +index 5b30bcb..a1205c3 100644 +--- a/arch/arm/lib/sections.c ++++ b/arch/arm/lib/sections.c +@@ -25,4 +25,6 @@ char __image_copy_start[0] __attribute__((section(".__image_copy_start"))); + char __image_copy_end[0] __attribute__((section(".__image_copy_end"))); + char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); + char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); ++char __secure_start[0] __attribute__((section(".__secure_start"))); ++char __secure_end[0] __attribute__((section(".__secure_end"))); + char _end[0] __attribute__((section(".__end"))); +From d7ebd8f57e84ea92ef0cf55080f0acec9c6d1ace Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:12 +0000 +Subject: [PATCH] ARM: HYP/non-sec: allow relocation to secure RAM + +The current non-sec switching code suffers from one major issue: +it cannot run in secure RAM, as a large part of u-boot still needs +to be run while we're switched to non-secure. + +This patch reworks the whole HYP/non-secure strategy by: +- making sure the secure code is the *last* thing u-boot executes + before entering the payload +- performing an exception return from secure mode directly into + the payload +- allowing the code to be dynamically relocated to secure RAM + before switching to non-secure. + +This involves quite a bit of horrible code, specially as u-boot +relocation is quite primitive. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/nonsec_virt.S | 161 +++++++++++++++++++-------------------- + arch/arm/cpu/armv7/virt-v7.c | 59 +++++--------- + arch/arm/include/asm/armv7.h | 10 ++- + arch/arm/include/asm/secure.h | 26 +++++++ + arch/arm/lib/bootm.c | 22 +++--- + 5 files changed, 138 insertions(+), 140 deletions(-) + create mode 100644 arch/arm/include/asm/secure.h + +diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S +index b5c946f..2a43e3c 100644 +--- a/arch/arm/cpu/armv7/nonsec_virt.S ++++ b/arch/arm/cpu/armv7/nonsec_virt.S +@@ -10,10 +10,13 @@ + #include <linux/linkage.h> + #include <asm/gic.h> + #include <asm/armv7.h> ++#include <asm/proc-armv/ptrace.h> + + .arch_extension sec + .arch_extension virt + ++ .pushsection ._secure.text, "ax" ++ + .align 5 + /* the vector table for secure state and HYP mode */ + _monitor_vectors: +@@ -22,51 +25,86 @@ _monitor_vectors: + adr pc, _secure_monitor + .word 0 + .word 0 +- adr pc, _hyp_trap ++ .word 0 + .word 0 + .word 0 + ++.macro is_cpu_virt_capable tmp ++ mrc p15, 0, \tmp, c0, c1, 1 @ read ID_PFR1 ++ and \tmp, \tmp, #CPUID_ARM_VIRT_MASK @ mask virtualization bits ++ cmp \tmp, #(1 << CPUID_ARM_VIRT_SHIFT) ++.endm ++ + /* + * secure monitor handler + * U-boot calls this "software interrupt" in start.S + * This is executed on a "smc" instruction, we use a "smc #0" to switch + * to non-secure state. +- * We use only r0 and r1 here, due to constraints in the caller. ++ * r0, r1, r2: passed to the callee ++ * ip: target PC + */ + _secure_monitor: +- mrc p15, 0, r1, c1, c1, 0 @ read SCR +- bic r1, r1, #0x4e @ clear IRQ, FIQ, EA, nET bits +- orr r1, r1, #0x31 @ enable NS, AW, FW bits ++ mrc p15, 0, r5, c1, c1, 0 @ read SCR ++ bic r5, r5, #0x4e @ clear IRQ, FIQ, EA, nET bits ++ orr r5, r5, #0x31 @ enable NS, AW, FW bits + +- mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 +- and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits +- cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT) ++ mov r6, #SVC_MODE @ default mode is SVC ++ is_cpu_virt_capable r4 + #ifdef CONFIG_ARMV7_VIRT +- orreq r1, r1, #0x100 @ allow HVC instruction ++ orreq r5, r5, #0x100 @ allow HVC instruction ++ moveq r6, #HYP_MODE @ Enter the kernel as HYP + #endif + +- mcr p15, 0, r1, c1, c1, 0 @ write SCR (with NS bit set) ++ mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set) + isb + +-#ifdef CONFIG_ARMV7_VIRT +- mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value +- mcreq p15, 4, r0, c12, c0, 0 @ write HVBAR +-#endif + bne 1f + + @ Reset CNTVOFF to 0 before leaving monitor mode +- mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 +- ands r0, r0, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits +- movne r0, #0 +- mcrrne p15, 4, r0, r0, c14 @ Reset CNTVOFF to zero ++ mrc p15, 0, r4, c0, c1, 1 @ read ID_PFR1 ++ ands r4, r4, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits ++ movne r4, #0 ++ mcrrne p15, 4, r4, r4, c14 @ Reset CNTVOFF to zero + 1: +- movs pc, lr @ return to non-secure SVC +- +-_hyp_trap: +- mrs lr, elr_hyp @ for older asm: .byte 0x00, 0xe3, 0x0e, 0xe1 +- mov pc, lr @ do no switch modes, but +- @ return to caller +- ++ mov lr, ip ++ mov ip, #(F_BIT | I_BIT | A_BIT) @ Set A, I and F ++ tst lr, #1 @ Check for Thumb PC ++ orrne ip, ip, #T_BIT @ Set T if Thumb ++ orr ip, ip, r6 @ Slot target mode in ++ msr spsr_cxfs, ip @ Set full SPSR ++ movs pc, lr @ ERET to non-secure ++ ++ENTRY(_do_nonsec_entry) ++ mov ip, r0 ++ mov r0, r1 ++ mov r1, r2 ++ mov r2, r3 ++ smc #0 ++ENDPROC(_do_nonsec_entry) ++ ++.macro get_cbar_addr addr ++#ifdef CONFIG_ARM_GIC_BASE_ADDRESS ++ ldr \addr, =CONFIG_ARM_GIC_BASE_ADDRESS ++#else ++ mrc p15, 4, \addr, c15, c0, 0 @ read CBAR ++ bfc \addr, #0, #15 @ clear reserved bits ++#endif ++.endm ++ ++.macro get_gicd_addr addr ++ get_cbar_addr \addr ++ add \addr, \addr, #GIC_DIST_OFFSET @ GIC dist i/f offset ++.endm ++ ++.macro get_gicc_addr addr, tmp ++ get_cbar_addr \addr ++ is_cpu_virt_capable \tmp ++ movne \tmp, #GIC_CPU_OFFSET_A9 @ GIC CPU offset for A9 ++ moveq \tmp, #GIC_CPU_OFFSET_A15 @ GIC CPU offset for A15/A7 ++ add \addr, \addr, \tmp ++.endm ++ ++#ifndef CONFIG_ARMV7_PSCI + /* + * Secondary CPUs start here and call the code for the core specific parts + * of the non-secure and HYP mode transition. The GIC distributor specific +@@ -74,31 +112,21 @@ _hyp_trap: + * Then they go back to wfi and wait to be woken up by the kernel again. + */ + ENTRY(_smp_pen) +- mrs r0, cpsr +- orr r0, r0, #0xc0 +- msr cpsr, r0 @ disable interrupts +- ldr r1, =_start +- mcr p15, 0, r1, c12, c0, 0 @ set VBAR ++ cpsid i ++ cpsid f + + bl _nonsec_init +- mov r12, r0 @ save GICC address +-#ifdef CONFIG_ARMV7_VIRT +- bl _switch_to_hyp +-#endif +- +- ldr r1, [r12, #GICC_IAR] @ acknowledge IPI +- str r1, [r12, #GICC_EOIR] @ signal end of interrupt + + adr r0, _smp_pen @ do not use this address again + b smp_waitloop @ wait for IPIs, board specific + ENDPROC(_smp_pen) ++#endif + + /* + * Switch a core to non-secure state. + * + * 1. initialize the GIC per-core interface + * 2. allow coprocessor access in non-secure modes +- * 3. switch the cpu mode (by calling "smc #0") + * + * Called from smp_pen by secondary cores and directly by the BSP. + * Do not assume that the stack is available and only use registers +@@ -108,38 +136,23 @@ ENDPROC(_smp_pen) + * though, but we check this in C before calling this function. + */ + ENTRY(_nonsec_init) +-#ifdef CONFIG_ARM_GIC_BASE_ADDRESS +- ldr r2, =CONFIG_ARM_GIC_BASE_ADDRESS +-#else +- mrc p15, 4, r2, c15, c0, 0 @ read CBAR +- bfc r2, #0, #15 @ clear reserved bits +-#endif +- add r3, r2, #GIC_DIST_OFFSET @ GIC dist i/f offset ++ get_gicd_addr r3 ++ + mvn r1, #0 @ all bits to 1 + str r1, [r3, #GICD_IGROUPRn] @ allow private interrupts + +- mrc p15, 0, r0, c0, c0, 0 @ read MIDR +- ldr r1, =MIDR_PRIMARY_PART_MASK +- and r0, r0, r1 @ mask out variant and revision ++ get_gicc_addr r3, r1 + +- ldr r1, =MIDR_CORTEX_A7_R0P0 & MIDR_PRIMARY_PART_MASK +- cmp r0, r1 @ check for Cortex-A7 +- +- ldr r1, =MIDR_CORTEX_A15_R0P0 & MIDR_PRIMARY_PART_MASK +- cmpne r0, r1 @ check for Cortex-A15 +- +- movne r1, #GIC_CPU_OFFSET_A9 @ GIC CPU offset for A9 +- moveq r1, #GIC_CPU_OFFSET_A15 @ GIC CPU offset for A15/A7 +- add r3, r2, r1 @ r3 = GIC CPU i/f addr +- +- mov r1, #1 @ set GICC_CTLR[enable] ++ mov r1, #3 @ Enable both groups + str r1, [r3, #GICC_CTLR] @ and clear all other bits + mov r1, #0xff + str r1, [r3, #GICC_PMR] @ set priority mask register + ++ mrc p15, 0, r0, c1, c1, 2 + movw r1, #0x3fff +- movt r1, #0x0006 +- mcr p15, 0, r1, c1, c1, 2 @ NSACR = all copros to non-sec ++ movt r1, #0x0004 ++ orr r0, r0, r1 ++ mcr p15, 0, r0, c1, c1, 2 @ NSACR = all copros to non-sec + + /* The CNTFRQ register of the generic timer needs to be + * programmed in secure state. Some primary bootloaders / firmware +@@ -157,21 +170,9 @@ ENTRY(_nonsec_init) + + adr r1, _monitor_vectors + mcr p15, 0, r1, c12, c0, 1 @ set MVBAR to secure vectors +- +- mrc p15, 0, ip, c12, c0, 0 @ save secure copy of VBAR +- + isb +- smc #0 @ call into MONITOR mode +- +- mcr p15, 0, ip, c12, c0, 0 @ write non-secure copy of VBAR +- +- mov r1, #1 +- str r1, [r3, #GICC_CTLR] @ enable non-secure CPU i/f +- add r2, r2, #GIC_DIST_OFFSET +- str r1, [r2, #GICD_CTLR] @ allow private interrupts + + mov r0, r3 @ return GICC address +- + bx lr + ENDPROC(_nonsec_init) + +@@ -183,18 +184,10 @@ ENTRY(smp_waitloop) + ldr r1, [r1] + cmp r0, r1 @ make sure we dont execute this code + beq smp_waitloop @ again (due to a spurious wakeup) +- mov pc, r1 ++ mov r0, r1 ++ b _do_nonsec_entry + ENDPROC(smp_waitloop) + .weak smp_waitloop + #endif + +-ENTRY(_switch_to_hyp) +- mov r0, lr +- mov r1, sp @ save SVC copy of LR and SP +- isb +- hvc #0 @ for older asm: .byte 0x70, 0x00, 0x40, 0xe1 +- mov sp, r1 +- mov lr, r0 @ restore SVC copy of LR and SP +- +- bx lr +-ENDPROC(_switch_to_hyp) ++ .popsection +diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c +index 2cd604f..6500030 100644 +--- a/arch/arm/cpu/armv7/virt-v7.c ++++ b/arch/arm/cpu/armv7/virt-v7.c +@@ -13,17 +13,10 @@ + #include <asm/armv7.h> + #include <asm/gic.h> + #include <asm/io.h> ++#include <asm/secure.h> + + unsigned long gic_dist_addr; + +-static unsigned int read_cpsr(void) +-{ +- unsigned int reg; +- +- asm volatile ("mrs %0, cpsr\n" : "=r" (reg)); +- return reg; +-} +- + static unsigned int read_id_pfr1(void) + { + unsigned int reg; +@@ -72,6 +65,18 @@ static unsigned long get_gicd_base_address(void) + #endif + } + ++static void relocate_secure_section(void) ++{ ++#ifdef CONFIG_ARMV7_SECURE_BASE ++ size_t sz = __secure_end - __secure_start; ++ ++ memcpy((void *)CONFIG_ARMV7_SECURE_BASE, __secure_start, sz); ++ flush_dcache_range(CONFIG_ARMV7_SECURE_BASE, ++ CONFIG_ARMV7_SECURE_BASE + sz + 1); ++ invalidate_icache_all(); ++#endif ++} ++ + static void kick_secondary_cpus_gic(unsigned long gicdaddr) + { + /* kick all CPUs (except this one) by writing to GICD_SGIR */ +@@ -83,35 +88,7 @@ void __weak smp_kick_all_cpus(void) + kick_secondary_cpus_gic(gic_dist_addr); + } + +-int armv7_switch_hyp(void) +-{ +- unsigned int reg; +- +- /* check whether we are in HYP mode already */ +- if ((read_cpsr() & 0x1f) == 0x1a) { +- debug("CPU already in HYP mode\n"); +- return 0; +- } +- +- /* check whether the CPU supports the virtualization extensions */ +- reg = read_id_pfr1(); +- if ((reg & CPUID_ARM_VIRT_MASK) != 1 << CPUID_ARM_VIRT_SHIFT) { +- printf("HYP mode: Virtualization extensions not implemented.\n"); +- return -1; +- } +- +- /* call the HYP switching code on this CPU also */ +- _switch_to_hyp(); +- +- if ((read_cpsr() & 0x1F) != 0x1a) { +- printf("HYP mode: switch not successful.\n"); +- return -1; +- } +- +- return 0; +-} +- +-int armv7_switch_nonsec(void) ++int armv7_init_nonsec(void) + { + unsigned int reg; + unsigned itlinesnr, i; +@@ -147,11 +124,13 @@ int armv7_switch_nonsec(void) + for (i = 1; i <= itlinesnr; i++) + writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i); + +- smp_set_core_boot_addr((unsigned long)_smp_pen, -1); ++#ifndef CONFIG_ARMV7_PSCI ++ smp_set_core_boot_addr((unsigned long)secure_ram_addr(_smp_pen), -1); + smp_kick_all_cpus(); ++#endif + + /* call the non-sec switching code on this CPU also */ +- _nonsec_init(); +- ++ relocate_secure_section(); ++ secure_ram_addr(_nonsec_init)(); + return 0; + } +diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h +index 395444e..11476dd 100644 +--- a/arch/arm/include/asm/armv7.h ++++ b/arch/arm/include/asm/armv7.h +@@ -78,13 +78,17 @@ void v7_outer_cache_inval_range(u32 start, u32 end); + + #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) + +-int armv7_switch_nonsec(void); +-int armv7_switch_hyp(void); ++int armv7_init_nonsec(void); + + /* defined in assembly file */ + unsigned int _nonsec_init(void); ++void _do_nonsec_entry(void *target_pc, unsigned long r0, ++ unsigned long r1, unsigned long r2); + void _smp_pen(void); +-void _switch_to_hyp(void); ++ ++extern char __secure_start[]; ++extern char __secure_end[]; ++ + #endif /* CONFIG_ARMV7_NONSEC || CONFIG_ARMV7_VIRT */ + + #endif /* ! __ASSEMBLY__ */ +diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h +new file mode 100644 +index 0000000..effdb18 +--- /dev/null ++++ b/arch/arm/include/asm/secure.h +@@ -0,0 +1,26 @@ ++#ifndef __ASM_SECURE_H ++#define __ASM_SECURE_H ++ ++#include <config.h> ++ ++#ifdef CONFIG_ARMV7_SECURE_BASE ++/* ++ * Warning, horror ahead. ++ * ++ * The target code lives in our "secure ram", but u-boot doesn't know ++ * that, and has blindly added reloc_off to every relocation ++ * entry. Gahh. Do the opposite conversion. This hack also prevents ++ * GCC from generating code veeners, which u-boot doesn't relocate at ++ * all... ++ */ ++#define secure_ram_addr(_fn) ({ \ ++ DECLARE_GLOBAL_DATA_PTR; \ ++ void *__fn = _fn; \ ++ typeof(_fn) *__tmp = (__fn - gd->reloc_off); \ ++ __tmp; \ ++ }) ++#else ++#define secure_ram_addr(_fn) (_fn) ++#endif ++ ++#endif +diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c +index 10634a4..61aa14e 100644 +--- a/arch/arm/lib/bootm.c ++++ b/arch/arm/lib/bootm.c +@@ -20,6 +20,7 @@ + #include <libfdt.h> + #include <fdt_support.h> + #include <asm/bootm.h> ++#include <asm/secure.h> + #include <linux/compiler.h> + + #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) +@@ -184,27 +185,17 @@ static void setup_end_tag(bd_t *bd) + + __weak void setup_board_tags(struct tag **in_params) {} + ++#ifdef CONFIG_ARM64 + static void do_nonsec_virt_switch(void) + { +-#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) +- if (armv7_switch_nonsec() == 0) +-#ifdef CONFIG_ARMV7_VIRT +- if (armv7_switch_hyp() == 0) +- debug("entered HYP mode\n"); +-#else +- debug("entered non-secure state\n"); +-#endif +-#endif +- +-#ifdef CONFIG_ARM64 + smp_kick_all_cpus(); + flush_dcache_all(); /* flush cache before swtiching to EL2 */ + armv8_switch_to_el2(); + #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 + armv8_switch_to_el1(); + #endif +-#endif + } ++#endif + + /* Subcommand: PREP */ + static void boot_prep_linux(bootm_headers_t *images) +@@ -287,8 +278,13 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) + r2 = gd->bd->bi_boot_params; + + if (!fake) { +- do_nonsec_virt_switch(); ++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) ++ armv7_init_nonsec(); ++ secure_ram_addr(_do_nonsec_entry)(kernel_entry, ++ 0, machid, r2); ++#else + kernel_entry(0, machid, r2); ++#endif + } + #endif + } +From 8ea1554da4a6e556d3213a77cf59daa1c154bdb5 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:13 +0000 +Subject: [PATCH] ARM: HYP/non-sec: add generic ARMv7 PSCI code + +Implement core support for PSCI. As this is generic code, it doesn't +implement anything really useful (all the functions are returning +Not Implemented). + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/Makefile | 4 ++ + arch/arm/cpu/armv7/psci.S | 105 ++++++++++++++++++++++++++++++++++++++++++++ + arch/arm/include/asm/psci.h | 35 +++++++++++++++ + 3 files changed, 144 insertions(+) + create mode 100644 arch/arm/cpu/armv7/psci.S + create mode 100644 arch/arm/include/asm/psci.h + +diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile +index 6f17771..0cf5c45 100644 +--- a/arch/arm/cpu/armv7/Makefile ++++ b/arch/arm/cpu/armv7/Makefile +@@ -24,6 +24,10 @@ obj-y += nonsec_virt.o + obj-y += virt-v7.o + endif + ++ifneq ($(CONFIG_ARMV7_PSCI),) ++obj-y += psci.o ++endif ++ + obj-$(CONFIG_KONA) += kona-common/ + obj-$(CONFIG_OMAP_COMMON) += omap-common/ + obj-$(CONFIG_TEGRA) += tegra-common/ +diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S +new file mode 100644 +index 0000000..a9341e0 +--- /dev/null ++++ b/arch/arm/cpu/armv7/psci.S +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier marc.zyngier@arm.com ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include <config.h> ++#include <linux/linkage.h> ++#include <asm/psci.h> ++ ++ .pushsection ._secure.text, "ax" ++ ++ .arch_extension sec ++ ++ .align 5 ++ .globl _psci_vectors ++_psci_vectors: ++ b default_psci_vector @ reset ++ b default_psci_vector @ undef ++ b _smc_psci @ smc ++ b default_psci_vector @ pabort ++ b default_psci_vector @ dabort ++ b default_psci_vector @ hyp ++ b default_psci_vector @ irq ++ b psci_fiq_enter @ fiq ++ ++ENTRY(psci_fiq_enter) ++ movs pc, lr ++ENDPROC(psci_fiq_enter) ++.weak psci_fiq_enter ++ ++ENTRY(default_psci_vector) ++ movs pc, lr ++ENDPROC(default_psci_vector) ++.weak default_psci_vector ++ ++ENTRY(psci_cpu_suspend) ++ENTRY(psci_cpu_off) ++ENTRY(psci_cpu_on) ++ENTRY(psci_migrate) ++ mov r0, #ARM_PSCI_RET_NI @ Return -1 (Not Implemented) ++ mov pc, lr ++ENDPROC(psci_migrate) ++ENDPROC(psci_cpu_on) ++ENDPROC(psci_cpu_off) ++ENDPROC(psci_cpu_suspend) ++.weak psci_cpu_suspend ++.weak psci_cpu_off ++.weak psci_cpu_on ++.weak psci_migrate ++ ++_psci_table: ++ .word ARM_PSCI_FN_CPU_SUSPEND ++ .word psci_cpu_suspend ++ .word ARM_PSCI_FN_CPU_OFF ++ .word psci_cpu_off ++ .word ARM_PSCI_FN_CPU_ON ++ .word psci_cpu_on ++ .word ARM_PSCI_FN_MIGRATE ++ .word psci_migrate ++ .word 0 ++ .word 0 ++ ++_smc_psci: ++ push {r3-r7,lr} ++ ++ @ Switch to secure ++ mrc p15, 0, r7, c1, c1, 0 ++ bic r4, r7, #1 ++ mcr p15, 0, r4, c1, c1, 0 ++ isb ++ ++ adr r4, _psci_table ++1: ldr r5, [r4] @ Load PSCI function ID ++ ldr r6, [r4, #4] @ Load target PC ++ cmp r5, #0 @ If reach the end, bail out ++ mvneq r0, #0 @ Return -1 (Not Implemented) ++ beq 2f ++ cmp r0, r5 @ If not matching, try next entry ++ addne r4, r4, #8 ++ bne 1b ++ cmp r6, #0 @ Not implemented ++ moveq r0, #ARM_PSCI_RET_NI ++ beq 2f ++ ++ blx r6 @ Execute PSCI function ++ ++ @ Switch back to non-secure ++ mcr p15, 0, r7, c1, c1, 0 ++ ++2: pop {r3-r7, lr} ++ movs pc, lr @ Return to the kernel ++ ++ .popsection +diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h +new file mode 100644 +index 0000000..704b4b0 +--- /dev/null ++++ b/arch/arm/include/asm/psci.h +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier marc.zyngier@arm.com ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#ifndef __ARM_PSCI_H__ ++#define __ARM_PSCI_H__ ++ ++/* PSCI interface */ ++#define ARM_PSCI_FN_BASE 0x95c1ba5e ++#define ARM_PSCI_FN(n) (ARM_PSCI_FN_BASE + (n)) ++ ++#define ARM_PSCI_FN_CPU_SUSPEND ARM_PSCI_FN(0) ++#define ARM_PSCI_FN_CPU_OFF ARM_PSCI_FN(1) ++#define ARM_PSCI_FN_CPU_ON ARM_PSCI_FN(2) ++#define ARM_PSCI_FN_MIGRATE ARM_PSCI_FN(3) ++ ++#define ARM_PSCI_RET_SUCCESS 0 ++#define ARM_PSCI_RET_NI (-1) ++#define ARM_PSCI_RET_INVAL (-2) ++#define ARM_PSCI_RET_DENIED (-3) ++ ++#endif /* __ARM_PSCI_H__ */ +From 0ca6171c385fed00125b320592ee94922f44f13a Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:14 +0000 +Subject: [PATCH] ARM: HYP/non-sec: add the option for a second-stage monitor + +Allow the switch to a second stage secure monitor just before +switching to non-secure. + +This allows a resident piece of firmware to be active once the +kernel has been entered (the u-boot monitor is dead anyway, +its pages being reused). + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/nonsec_virt.S | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S +index 2a43e3c..745670e 100644 +--- a/arch/arm/cpu/armv7/nonsec_virt.S ++++ b/arch/arm/cpu/armv7/nonsec_virt.S +@@ -44,10 +44,19 @@ _monitor_vectors: + * ip: target PC + */ + _secure_monitor: ++#ifdef CONFIG_ARMV7_PSCI ++ ldr r5, =_psci_vectors @ Switch to the next monitor ++ mcr p15, 0, r5, c12, c0, 1 ++ isb ++ ++ @ Obtain a secure stack, and configure the PSCI backend ++ bl psci_arch_init ++#endif ++ + mrc p15, 0, r5, c1, c1, 0 @ read SCR +- bic r5, r5, #0x4e @ clear IRQ, FIQ, EA, nET bits ++ bic r5, r5, #0x4a @ clear IRQ, EA, nET bits + orr r5, r5, #0x31 @ enable NS, AW, FW bits +- ++ @ FIQ preserved for secure mode + mov r6, #SVC_MODE @ default mode is SVC + is_cpu_virt_capable r4 + #ifdef CONFIG_ARMV7_VIRT +From 9aa373162eb2cc0055a6e4ecd46977c911de1124 Mon Sep 17 00:00:00 2001 +From: Ma Haijun mahaijuns@gmail.com +Date: Sat, 15 Feb 2014 12:51:10 +0000 +Subject: [PATCH] ARM: convert arch_fixup_memory_node to a generic FDT fixup + function + +Some architecture needs extra device tree setup. Instead of adding +yet another hook, convert arch_fixup_memory_node to be a generic +FDT fixup function. + +[maz: collapsed 3 patches into one, rewrote commit message] + +Signed-off-by: Ma Haijun mahaijuns@gmail.com +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/lib/bootm-fdt.c | 2 +- + arch/arm/lib/bootm.c | 2 +- + common/image-fdt.c | 7 +++++-- + include/common.h | 6 +++--- + 4 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c +index e40691d..8394e15 100644 +--- a/arch/arm/lib/bootm-fdt.c ++++ b/arch/arm/lib/bootm-fdt.c +@@ -20,7 +20,7 @@ + + DECLARE_GLOBAL_DATA_PTR; + +-int arch_fixup_memory_node(void *blob) ++int arch_fixup_fdt(void *blob) + { + bd_t *bd = gd->bd; + int bank; +diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c +index 61aa14e..4cff6b0 100644 +--- a/arch/arm/lib/bootm.c ++++ b/arch/arm/lib/bootm.c +@@ -357,7 +357,7 @@ void boot_prep_vxworks(bootm_headers_t *images) + if (images->ft_addr) { + off = fdt_path_offset(images->ft_addr, "/memory"); + if (off < 0) { +- if (arch_fixup_memory_node(images->ft_addr)) ++ if (arch_fixup_fdt(images->ft_addr)) + puts("## WARNING: fixup memory failed!\n"); + } + } +diff --git a/common/image-fdt.c b/common/image-fdt.c +index a54a919..6f074de 100644 +--- a/common/image-fdt.c ++++ b/common/image-fdt.c +@@ -445,7 +445,7 @@ __weak int ft_verify_fdt(void *fdt) + return 1; + } + +-__weak int arch_fixup_memory_node(void *blob) ++__weak int arch_fixup_fdt(void *blob) + { + return 0; + } +@@ -462,7 +462,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob, + puts(" - must RESET the board to recover.\n"); + return -1; + } +- arch_fixup_memory_node(blob); ++ if (arch_fixup_fdt(blob) < 0) { ++ puts("ERROR: arch specific fdt fixup failed"); ++ return -1; ++ } + if (IMAGE_OF_BOARD_SETUP) + ft_board_setup(blob, gd->bd); + fdt_fixup_ethernet(blob); +diff --git a/include/common.h b/include/common.h +index cbd3c9e..700b015 100644 +--- a/include/common.h ++++ b/include/common.h +@@ -326,14 +326,14 @@ int arch_early_init_r(void); + void board_show_dram(ulong size); + + /** +- * arch_fixup_memory_node() - Write arch-specific memory information to fdt ++ * arch_fixup_fdt() - Write arch-specific information to fdt + * +- * Defined in arch/$(ARCH)/lib/bootm.c ++ * Defined in arch/$(ARCH)/lib/bootm-fdt.c + * + * @blob: FDT blob to write to + * @return 0 if ok, or -ve FDT_ERR_... on failure + */ +-int arch_fixup_memory_node(void *blob); ++int arch_fixup_fdt(void *blob); + + /* common/flash.c */ + void flash_perror (int); +From ccdf689da800c9f1c5226146e936b071c7ec8800 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:15 +0000 +Subject: [PATCH] ARM: HYP/non-sec/PSCI: emit DT nodes + +Generate the PSCI node in the device tree. + +Also add a reserve section for the "secure" code that lives in +in normal RAM, so that the kernel knows it'd better not trip on +it. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/Makefile | 1 + + arch/arm/cpu/armv7/virt-dt.c | 100 +++++++++++++++++++++++++++++++++++++++++++ + arch/arm/include/asm/armv7.h | 1 + + arch/arm/lib/bootm-fdt.c | 11 ++++- + 4 files changed, 111 insertions(+), 2 deletions(-) + create mode 100644 arch/arm/cpu/armv7/virt-dt.c + +diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile +index 0cf5c45..93a5a69 100644 +--- a/arch/arm/cpu/armv7/Makefile ++++ b/arch/arm/cpu/armv7/Makefile +@@ -22,6 +22,7 @@ endif + ifneq ($(CONFIG_ARMV7_NONSEC)$(CONFIG_ARMV7_VIRT),) + obj-y += nonsec_virt.o + obj-y += virt-v7.o ++obj-y += virt-dt.o + endif + + ifneq ($(CONFIG_ARMV7_PSCI),) +diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c +new file mode 100644 +index 0000000..0b0d6a7 +--- /dev/null ++++ b/arch/arm/cpu/armv7/virt-dt.c +@@ -0,0 +1,100 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier marc.zyngier@arm.com ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include <common.h> ++#include <stdio_dev.h> ++#include <linux/ctype.h> ++#include <linux/types.h> ++#include <asm/global_data.h> ++#include <libfdt.h> ++#include <fdt_support.h> ++#include <asm/armv7.h> ++#include <asm/psci.h> ++ ++static int fdt_psci(void *fdt) ++{ ++#ifdef CONFIG_ARMV7_PSCI ++ int nodeoff; ++ int tmp; ++ ++ nodeoff = fdt_path_offset(fdt, "/cpus"); ++ if (nodeoff < 0) { ++ printf("couldn't find /cpus\n"); ++ return nodeoff; ++ } ++ ++ /* add 'enable-method = "psci"' to each cpu node */ ++ for (tmp = fdt_first_subnode(fdt, nodeoff); ++ tmp >= 0; ++ tmp = fdt_next_subnode(fdt, tmp)) { ++ const struct fdt_property *prop; ++ int len; ++ ++ prop = fdt_get_property(fdt, tmp, "device_type", &len); ++ if (!prop) ++ continue; ++ if (len < 4) ++ continue; ++ if (strcmp(prop->data, "cpu")) ++ continue; ++ ++ fdt_setprop_string(fdt, tmp, "enable-method", "psci"); ++ } ++ ++ nodeoff = fdt_path_offset(fdt, "/psci"); ++ if (nodeoff < 0) { ++ nodeoff = fdt_path_offset(fdt, "/"); ++ if (nodeoff < 0) ++ return nodeoff; ++ ++ nodeoff = fdt_add_subnode(fdt, nodeoff, "psci"); ++ if (nodeoff < 0) ++ return nodeoff; ++ } ++ ++ tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci"); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc"); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON); ++ if (tmp) ++ return tmp; ++ tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE); ++ if (tmp) ++ return tmp; ++#endif ++ return 0; ++} ++ ++int armv7_update_dt(void *fdt) ++{ ++#ifndef CONFIG_ARMV7_SECURE_BASE ++ /* secure code lives in RAM, keep it alive */ ++ fdt_add_mem_rsv(fdt, (unsigned long)__secure_start, ++ __secure_end - __secure_start); ++#endif ++ ++ return fdt_psci(fdt); ++} +diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h +index 11476dd..323f282 100644 +--- a/arch/arm/include/asm/armv7.h ++++ b/arch/arm/include/asm/armv7.h +@@ -79,6 +79,7 @@ void v7_outer_cache_inval_range(u32 start, u32 end); + #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) + + int armv7_init_nonsec(void); ++int armv7_update_dt(void *fdt); + + /* defined in assembly file */ + unsigned int _nonsec_init(void); +diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c +index 8394e15..ccb76c7 100644 +--- a/arch/arm/lib/bootm-fdt.c ++++ b/arch/arm/lib/bootm-fdt.c +@@ -17,13 +17,14 @@ + + #include <common.h> + #include <fdt_support.h> ++#include <asm/armv7.h> + + DECLARE_GLOBAL_DATA_PTR; + + int arch_fixup_fdt(void *blob) + { + bd_t *bd = gd->bd; +- int bank; ++ int bank, ret; + u64 start[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; + +@@ -32,5 +33,11 @@ int arch_fixup_fdt(void *blob) + size[bank] = bd->bi_dram[bank].size; + } + +- return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); ++ ret = fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); ++ if (ret) ++ return ret; ++ ++#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) ++ return armv7_update_dt(blob); ++#endif + } +From d5ee64675e6481e4f29e48e494ea132cd74786c8 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:17 +0000 +Subject: [PATCH] sunxi: HYP/non-sec: add sun7i PSCI backend + +So far, only supporting the CPU_ON method. +Other functions can be added later. + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + arch/arm/cpu/armv7/sunxi/Makefile | 3 + + arch/arm/cpu/armv7/sunxi/psci.S | 162 ++++++++++++++++++++++++++++++++++++++ + include/configs/sun7i.h | 6 ++ + 3 files changed, 171 insertions(+) + create mode 100644 arch/arm/cpu/armv7/sunxi/psci.S + +diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile +index 19e4b17..0df6772 100644 +--- a/arch/arm/cpu/armv7/sunxi/Makefile ++++ b/arch/arm/cpu/armv7/sunxi/Makefile +@@ -32,6 +32,9 @@ obj-y += cpu_info.o + ifdef CONFIG_CMD_WATCHDOG + obj-$(CONFIG_CMD_WATCHDOG) += cmd_watchdog.o + endif ++ifdef CONFIG_ARMV7_PSCI ++obj-y += psci.o ++endif + endif + + ifdef CONFIG_SPL_BUILD +diff --git a/arch/arm/cpu/armv7/sunxi/psci.S b/arch/arm/cpu/armv7/sunxi/psci.S +new file mode 100644 +index 0000000..0084c81 +--- /dev/null ++++ b/arch/arm/cpu/armv7/sunxi/psci.S +@@ -0,0 +1,162 @@ ++/* ++ * Copyright (C) 2013 - ARM Ltd ++ * Author: Marc Zyngier marc.zyngier@arm.com ++ * ++ * Based on code by Carl van Schaik carl@ok-labs.com. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 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 http://www.gnu.org/licenses/. ++ */ ++ ++#include <config.h> ++#include <asm/psci.h> ++#include <asm/arch/cpu.h> ++ ++/* ++ * Memory layout: ++ * ++ * SECURE_RAM to text_end : ++ * ._secure_text section ++ * text_end to ALIGN_PAGE(text_end): ++ * nothing ++ * ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000) ++ * 1kB of stack per CPU (4 CPUs max). ++ */ ++ ++ .pushsection ._secure.text, "ax" ++ ++ .arch_extension sec ++ ++#define ONE_MS (CONFIG_SYS_CLK_FREQ / 1000) ++#define TEN_MS (10 * ONE_MS) ++ ++.macro timer_wait reg, ticks ++ @ Program CNTP_TVAL ++ movw \reg, #(\ticks & 0xffff) ++ movt \reg, #(\ticks >> 16) ++ mcr p15, 0, \reg, c14, c2, 0 ++ isb ++ @ Enable physical timer, mask interrupt ++ mov \reg, #3 ++ mcr p15, 0, \reg, c14, c2, 1 ++ @ Poll physical timer until ISTATUS is on ++1: isb ++ mrc p15, 0, \reg, c14, c2, 1 ++ ands \reg, \reg, #4 ++ bne 1b ++ @ Disable timer ++ mov \reg, #0 ++ mcr p15, 0, \reg, c14, c2, 1 ++ isb ++.endm ++ ++.globl psci_arch_init ++psci_arch_init: ++ mrc p15, 0, r5, c1, c1, 0 @ Read SCR ++ bic r5, r5, #1 @ Secure mode ++ mcr p15, 0, r5, c1, c1, 0 @ Write SCR ++ isb ++ ++ mrc p15, 0, r4, c0, c0, 5 @ MPIDR ++ and r4, r4, #3 @ cpu number in cluster ++ mov r5, #400 @ 1kB of stack per CPU ++ mul r4, r4, r5 ++ ++ adr r5, text_end @ end of text ++ add r5, r5, #0x2000 @ Skip two pages ++ lsr r5, r5, #12 @ Align to start of page ++ lsl r5, r5, #12 ++ sub sp, r5, r4 @ here's our stack! ++ ++ bx lr ++ ++ @ r1 = target CPU ++ @ r2 = target PC ++.globl psci_cpu_on ++psci_cpu_on: ++ adr r0, _target_pc ++ str r2, [r0] ++ dsb ++ ++ movw r0, #(SUNXI_CPUCFG_BASE & 0xffff) ++ movt r0, #(SUNXI_CPUCFG_BASE >> 16) ++ ++ @ CPU mask ++ and r1, r1, #3 @ only care about first cluster ++ mov r4, #1 ++ lsl r4, r4, r1 ++ ++ adr r6, _sunxi_cpu_entry ++ str r6, [r0, #0x1a4] @ PRIVATE_REG (boot vector) ++ ++ @ Assert reset on target CPU ++ mov r6, #0 ++ lsl r5, r1, #6 @ 64 bytes per CPU ++ add r5, r5, #0x40 @ Offset from base ++ add r5, r5, r0 @ CPU control block ++ str r6, [r5] @ Reset CPU ++ ++ @ l1 invalidate ++ ldr r6, [r0, #0x184] ++ bic r6, r6, r4 ++ str r6, [r0, #0x184] ++ ++ @ Lock CPU ++ ldr r6, [r0, #0x1e4] ++ bic r6, r6, r4 ++ str r6, [r0, #0x1e4] ++ ++ @ Release power clamp ++ movw r6, #0x1ff ++ movt r6, #0 ++1: lsrs r6, r6, #1 ++ str r6, [r0, #0x1b0] ++ bne 1b ++ ++ timer_wait r1, TEN_MS ++ ++ @ Clear power gating ++ ldr r6, [r0, #0x1b4] ++ bic r6, r6, #1 ++ str r6, [r0, #0x1b4] ++ ++ @ Deassert reset on target CPU ++ mov r6, #3 ++ str r6, [r5] ++ ++ @ Unlock CPU ++ ldr r6, [r0, #0x1e4] ++ orr r6, r6, r4 ++ str r6, [r0, #0x1e4] ++ ++ mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS ++ mov pc, lr ++ ++_target_pc: ++ .word 0 ++ ++_sunxi_cpu_entry: ++ @ Set SMP bit ++ mrc p15, 0, r0, c1, c0, 1 ++ orr r0, r0, #0x40 ++ mcr p15, 0, r0, c1, c0, 1 ++ isb ++ ++ bl _nonsec_init ++ bl psci_arch_init ++ ++ adr r0, _target_pc ++ ldr r0, [r0] ++ b _do_nonsec_entry ++ ++text_end: ++ .popsection +diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h +index 11cc9ea..bae7b37 100644 +--- a/include/configs/sun7i.h ++++ b/include/configs/sun7i.h +@@ -22,6 +22,12 @@ + #define CONFIG_BOARD_POSTCLK_INIT 1 + #endif + ++#define CONFIG_ARMV7_VIRT 1 ++#define CONFIG_ARMV7_NONSEC 1 ++#define CONFIG_ARMV7_PSCI 1 ++#define CONFIG_ARMV7_PSCI_NR_CPUS 2 ++#define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE ++ + /* + * Include common sunxi configuration where most the settings are + */ +From a74a847c3727209a45c30a80c01b930938941dd4 Mon Sep 17 00:00:00 2001 +From: Marc Zyngier marc.zyngier@arm.com +Date: Sat, 7 Dec 2013 11:19:18 +0000 +Subject: [PATCH] sunxi: HYP/non-sec: configure CNTFRQ on all CPUs + +CNTFRQ needs to be properly configured on all CPUs. Otherwise, +virtual machines hoping to find valuable information on secondary +CPUs will be disapointed... + +Signed-off-by: Marc Zyngier marc.zyngier@arm.com +--- + include/configs/sun7i.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h +index bae7b37..58a254b 100644 +--- a/include/configs/sun7i.h ++++ b/include/configs/sun7i.h +@@ -27,6 +27,7 @@ + #define CONFIG_ARMV7_PSCI 1 + #define CONFIG_ARMV7_PSCI_NR_CPUS 2 + #define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE ++#define CONFIG_SYS_CLK_FREQ 24000000 + + /* + * Include common sunxi configuration where most the settings are diff --git a/src/patches/u-boot/sunxi/003-uboot-fix-gmac-not-working-reliable-on-bananapi.patch b/src/patches/u-boot/sunxi/003-uboot-fix-gmac-not-working-reliable-on-bananapi.patch new file mode 100644 index 0000000..6bc8c93 --- /dev/null +++ b/src/patches/u-boot/sunxi/003-uboot-fix-gmac-not-working-reliable-on-bananapi.patch @@ -0,0 +1,20 @@ +diff --git a/board/sunxi/gmac.c b/board/sunxi/gmac.c +index e7ff952..f58c963 100644 +--- a/board/sunxi/gmac.c ++++ b/board/sunxi/gmac.c +@@ -24,6 +24,15 @@ int sunxi_gmac_initialize(bd_t *bis) + CCM_GMAC_CTRL_GPIT_MII); + #endif + ++ /* ++ * HdG: this is necessary to get GMAC to work reliable on the ++ * Bananapi. We don't know what these undocumented bits do, so this ++ * is a Bananapi specific hack for now. ++ */ ++#ifdef CONFIG_BANANAPI ++ setbits_le32(&ccm->gmac_clk_cfg, 0x3 << 10); ++#endif ++ + /* Configure pin mux settings for GMAC */ + for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(16); pin++) { + #ifdef CONFIG_RGMII diff --git a/src/scripts/update-bootloader b/src/scripts/update-bootloader new file mode 100644 index 0000000..ad6fdb6 --- /dev/null +++ b/src/scripts/update-bootloader @@ -0,0 +1,142 @@ +#!/bin/bash +############################################################################ +# # +# This file is part of the IPFire Firewall. # +# # +# IPFire 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. # +# # +# IPFire 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 IPFire; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# # +# Copyright (C) 2014 IPFire Team info@ipfire.org. # +# # +############################################################################ + +GRUB_INSTALL_ARGS="--no-floppy --recheck" + +function find_bootloader_device() { + local mp + for mp in /boot /; do + if find_device "${mp}"; then + return 0 + fi + done + + return 1 +} + +function find_device() { + local mountpoint="${1}" + + local root + local dev mp fs flags rest + while read -r dev mp fs flags rest; do + # Skip unwanted entries + [ "${dev}" = "rootfs" ] && continue + + if [ "${mp}" = "${mountpoint}" ] && [ -b "${dev}" ]; then + root="$(basename "${dev}")" + break + fi + done < /proc/mounts + + # Get the actual device from the partition that holds / + while [ -n "${root}" ]; do + if [ -e "/sys/block/${root}" ]; then + echo "${root}" + return 0 + fi + + # Remove last character + root="${root::-1}" + done + + return 1 +} + +function device_is_mdraid() { + local device="${1}" + + [ -d "/sys/block/${device}/md" ] +} + +function mdraid_get_slaves() { + local device="${1}" + + local slave + for slave in /sys/block/${device}/slaves/*; do + basename "${slave}" + done 2>/dev/null +} + +function grub_update_config() { + echo "Updating configuration..." + + if ! grub-mkconfig -o /boot/grub/grub.cfg &>/dev/null; then + echo "Could not update configuration. Aborting." >&2 + return 1 + fi + + return 0 +} + +function grub_install() { + local device="${1}" + + echo "Installing GRUB on ${device}..." + + if [ ! -b "${device}" ]; then + echo "${device} does not exist or is not a block device" >&2 + return 1 + fi + + local args + for args in "" "--force"; do + if grub-install ${GRUB_INSTALL_ARGS} ${args} "${device}" &>/dev/null; then + return 0 + fi + done + + echo "Could not install GRUB on ${device}" >&2 + return 1 +} + +function main() { + # Find the root device + local device="$(find_bootloader_device)" + if [ -z "${device}" ]; then + echo "Could not find root device. Aborting." >&2 + exit 1 + fi + + echo "Found bootloader device: /dev/${device}" + + # Update configuration files + grub_update_config || exit $? + + # Handle mdraid devices + if device_is_mdraid "${device}"; then + local slave + for slave in $(mdraid_get_slaves "${device}"); do + grub_install "/dev/${slave}" + done + + # Handle normal block devices + else + grub_install "/dev/${device}" + fi + + return 0 +} + +# Run main function +main diff --git a/src/setup/po/da.po b/src/setup/po/da.po index 7c696e5..bf05c10 100644 --- a/src/setup/po/da.po +++ b/src/setup/po/da.po @@ -9,8 +9,8 @@ msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-08-21 15:12+0000\n" -"PO-Revision-Date: 2014-08-21 15:13+0000\n" -"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"PO-Revision-Date: 2014-08-24 14:21+0000\n" +"Last-Translator: Henrik Simonsen cybermaze@gmail.com\n" "Language-Team: Danish (http://www.transifex.com/projects/p/ipfire/language/da/)%5Cn" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -440,7 +440,7 @@ msgid "" "Current config: %s\n" "\n" "%s" -msgstr "" +msgstr "Nuværende konfiguration: %s\n\n%s"
#: networking.c:268 msgid "Network configuration menu" diff --git a/src/setup/po/de.po b/src/setup/po/de.po index b1d7d3a..12333a6 100644 --- a/src/setup/po/de.po +++ b/src/setup/po/de.po @@ -10,7 +10,7 @@ msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-08-21 15:12+0000\n" -"PO-Revision-Date: 2014-08-21 18:01+0000\n" +"PO-Revision-Date: 2014-08-24 19:39+0000\n" "Last-Translator: Stefan Schantl stefan.schantl@ipfire.org\n" "Language-Team: German (http://www.transifex.com/projects/p/ipfire/language/de/)%5Cn" "MIME-Version: 1.0\n" @@ -138,7 +138,7 @@ msgstr "Hostname"
#: hostname.c:46 msgid "Enter the machine's hostname." -msgstr "Bitte geben Sie den Hostname der Maschine ein." +msgstr "Bitte geben Sie den Hostnamen der Maschine ein."
#: hostname.c:53 msgid "Hostname cannot be empty." @@ -158,7 +158,7 @@ msgstr "Tastaturbelegung"
#: keymap.c:85 msgid "Choose the type of keyboard you are using from the list below." -msgstr "Wählen Sie aus dieser Liste den Tastatur-Typ aus, den Sie benutzen." +msgstr "Bitte wählen Sie aus der Liste das gewünschte Tastatur-Layout aus."
#: main.c:68 timezone.c:77 msgid "Timezone" diff --git a/src/setup/po/fa.po b/src/setup/po/fa.po index 2e2adc4..58a2008 100644 --- a/src/setup/po/fa.po +++ b/src/setup/po/fa.po @@ -3,14 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# hashem ghavami hashem.wolf@gmail.com, 2014 # Khalil Delavaran khalil.delavaran@gmail.com, 2014 msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-08-21 15:12+0000\n" -"PO-Revision-Date: 2014-08-21 15:13+0000\n" -"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"PO-Revision-Date: 2014-11-12 18:28+0000\n" +"Last-Translator: Khalil Delavaran khalil.delavaran@gmail.com\n" "Language-Team: Persian (http://www.transifex.com/projects/p/ipfire/language/fa/)%5Cn" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -52,7 +53,7 @@ msgstr "پسوند نام دامنه:" #: networking.c:442 networking.c:552 networking.c:603 networking.c:610 #: networking.c:713 timezone.c:63 msgid "Unable to open settings file" -msgstr "" +msgstr "نمی توان فایل پیکربندی را باز کرد"
#: dhcp.c:111 msgid "DHCP server configuration" @@ -60,7 +61,7 @@ msgstr "پیکربندی سرور DHCP"
#: dhcp.c:116 msgid "Configure the DHCP server by entering the settings information." -msgstr "" +msgstr "سرویس دهنده DHcp با داده و تنظیمات وارد شده پیکربندی شد"
#: dhcp.c:125 msgid "Enabled" @@ -85,7 +86,7 @@ msgstr "نمی خواهم" msgid "" "The following fields are invalid:\n" "\n" -msgstr "" +msgstr "شاخص های زیر اشتباه هستند:\n\n"
#: dhcp.c:159 msgid "Start address" @@ -129,7 +130,7 @@ msgstr "نام دامنه نمی تواند فاصله داشته باشد."
#: domainname.c:53 msgid "Domain name may only contain letters, numbers, hyphens and periods." -msgstr "" +msgstr "نام دامنه ممکن است شامل حروف، اعداد، خط فاصله و دوره های باشذ"
#: hostname.c:46 main.c:69 msgid "Hostname" @@ -149,23 +150,23 @@ msgstr "نام هاست نمیتواند فاصله داشته باشد."
#: hostname.c:58 msgid "Hostname may only contain letters, numbers and hyphens." -msgstr "" +msgstr "نام هاست ممکن است شامل حروف، اعداد و خط فاصله باشد."
#: keymap.c:84 main.c:67 msgid "Keyboard mapping" -msgstr "" +msgstr "نگاشت کیبورد"
#: keymap.c:85 msgid "Choose the type of keyboard you are using from the list below." -msgstr "" +msgstr "نوع کی بورد خود را از لیست زیر گزینش کنید."
#: main.c:68 timezone.c:77 msgid "Timezone" -msgstr "" +msgstr "منطقه زمانی"
#: main.c:71 networking.c:110 networking.c:115 networking.c:447 msgid "Networking" -msgstr "" +msgstr "شبکه بندی"
#: main.c:72 misc.c:147 msgid "ISDN" @@ -181,15 +182,15 @@ msgstr "گذر واژه 'admin'"
#: main.c:90 msgid " <Tab>/<Alt-Tab> between elements | <Space> selects" -msgstr "" +msgstr " <Tab>/<Alt-Tab> میان عنصری | <Space> گزینش"
#: main.c:97 msgid "Section menu" -msgstr "" +msgstr "برش منو"
#: main.c:98 msgid "Select the item you wish to configure." -msgstr "" +msgstr "اینترفیسی که قصد پیکربندی دوباره آنرا دارید گزینش کنید."
#: main.c:99 msgid "Quit" @@ -207,50 +208,50 @@ msgstr "گوشزد" msgid "" "Initial setup was not entirely complete. You must ensure that Setup is " "properly finished by running setup again at the shell." -msgstr "" +msgstr "راه اندازی به پایان نرسیده است. شما با اجرای دوباره راه اندازی در خط فرمان باید مطمئن شوید که راه اندازی پایان یافته است."
#: misc.c:62 #, c-format msgid "Unable to write %s/main/hostname.conf" -msgstr "" +msgstr "نمی توان %s/main/hostname.conf را نوشت."
#: misc.c:71 msgid "Unable to open main hosts file." -msgstr "" +msgstr "نمی توان فایل هاست های اصلی را باز کرد."
#: misc.c:76 msgid "Unable to write /etc/hosts." -msgstr "" +msgstr "نمی توان در /etc/hosts نوشت."
#: misc.c:117 msgid "Unable to write /etc/hosts.deny." -msgstr "" +msgstr "نمی توان در /etc/hosts.deny نوشت."
#: misc.c:125 msgid "Unable to write /etc/hosts.allow." -msgstr "" +msgstr "نمی توان در /etc/hosts.allow نوشت."
#: misc.c:136 msgid "Unable to set hostname." -msgstr "" +msgstr "نمی توان نام هاست را پیکربندی کرد."
#: misc.c:147 msgid "Scanning and configuring ISDN devices." -msgstr "" +msgstr "پویش و پیکربندی دستگاه های ISDN."
#: misc.c:148 msgid "Unable to scan for ISDN devices." -msgstr "" +msgstr "نمی توان دستگاههای ISDN را پویش کرد."
#: netstuff.c:86 #, c-format msgid "Interface - %s" -msgstr "" +msgstr "اینترفیس - %s"
#: netstuff.c:91 #, c-format msgid "Enter the IP address information for the %s interface." -msgstr "" +msgstr "داده های آدرس IP برای اینترفیس %s را بنویسید."
#: netstuff.c:103 msgid "Static" @@ -270,7 +271,7 @@ msgstr "نام هاست DHCP:"
#: netstuff.c:115 msgid "Force DHCP MTU:" -msgstr "" +msgstr "DHCP MTU به زور:"
#: netstuff.c:134 msgid "IP address:" @@ -282,7 +283,7 @@ msgstr "ماسک شبکه:"
#: netstuff.c:173 networking.c:749 msgid "The following fields are invalid:" -msgstr "" +msgstr "شاخص های زیر اشتباه هستند"
#: netstuff.c:183 msgid "IP address" @@ -298,16 +299,16 @@ msgstr "نام هاست DHCP"
#: netstuff.c:396 netstuff.c:709 msgid "Unset" -msgstr "" +msgstr "تنظیم نشده"
#: netstuff.c:669 #, c-format msgid "Please choose a networkcard for the following interface - %s." -msgstr "" +msgstr "خواهشمند است یک کارت شبکه برای اینترفیس %s زیر گزینش کنید."
#: netstuff.c:672 msgid "Extended Network Menu" -msgstr "" +msgstr "منوی گسترده شبکه"
#: netstuff.c:673 networking.c:520 msgid "Select" @@ -315,28 +316,28 @@ msgstr "گزینش"
#: netstuff.c:673 msgid "Identify" -msgstr "" +msgstr "شناختن"
#: netstuff.c:678 msgid "Device Identification" -msgstr "" +msgstr "شناسایی دستگاه"
#: netstuff.c:678 msgid "The lights on the selected port should flash now for 10 seconds..." -msgstr "" +msgstr "چراغ های پورت گزینش شده، هم اکنون باید برای 10 ثانیه چشمک بزنند..."
#: netstuff.c:679 msgid "Identification is not supported by this interface." -msgstr "" +msgstr "این اینترفیس شناسایی را پشتیبانی نمی کند."
#: netstuff.c:691 msgid "There are no unassigned interfaces on your system." -msgstr "" +msgstr "هیچ رابط اختصاص داده نشده بر روی سیستم شما وجود ندارد."
#: netstuff.c:732 #, c-format msgid "Do you really want to remove the assigned %s interface?" -msgstr "" +msgstr "آیا شما واقعا می خواهید اینترفیس %s اختصاص داده شده را پاک کنید؟"
#: netstuff.c:755 msgid "Select network driver" @@ -344,35 +345,35 @@ msgstr "گزینش راه انداز شبکه"
#: netstuff.c:755 msgid "Set additional module parameters" -msgstr "" +msgstr "پیکربندی پارامترهای افزوده ماژول"
#: netstuff.c:762 msgid "Loading module..." -msgstr "" +msgstr "بارگذاری ماژول..."
#: netstuff.c:777 msgid "Unable to load driver module." -msgstr "" +msgstr "نمی توان راه انداز ماژول را بارگذاری کرد."
#: netstuff.c:780 msgid "Module name cannot be blank." -msgstr "" +msgstr "نام ماژول نمی تواند پوچ باشد."
#: networking.c:110 msgid "Stopping network..." -msgstr "" +msgstr "از کار انداختن شبکه..."
#: networking.c:115 msgid "Restarting network..." -msgstr "" +msgstr "شروع دوباره شبکه..."
#: networking.c:146 msgid "No GREEN interface assigned." -msgstr "" +msgstr "به اینترفیس سبز میزانی داده نشده است."
#: networking.c:152 msgid "Missing an IP address on GREEN." -msgstr "" +msgstr "آدرس IP بر روی سبز یافت نشد."
#: networking.c:163 msgid "Error" @@ -384,43 +385,43 @@ msgstr "نادیده گرفتن"
#: networking.c:164 msgid "No RED interface assigned." -msgstr "" +msgstr "برای اینترفیس قرمز میزانی داده نشده است."
#: networking.c:173 msgid "Missing an IP address on RED." -msgstr "" +msgstr "آدرس IP بر روی قرمز یافت نشد."
#: networking.c:183 msgid "No ORANGE interface assigned." -msgstr "" +msgstr "برای اینترفیس نارنجی میزانی داده نشده است."
#: networking.c:189 msgid "Missing an IP address on ORANGE." -msgstr "" +msgstr "آدرس IP بر روی نارنجی یافت نشد."
#: networking.c:199 msgid "No BLUE interface assigned." -msgstr "" +msgstr "برای اینترفیس آبی میزانی داده نشده است."
#: networking.c:205 msgid "Missing an IP address on BLUE." -msgstr "" +msgstr "آدرس IP بر روی آبی یافت نشد."
#: networking.c:217 msgid "Misssing DNS." -msgstr "" +msgstr "DNS یافت نشد."
#: networking.c:224 msgid "Missing Default Gateway." -msgstr "" +msgstr "Gateway پیش پندار یافت نشد."
#: networking.c:237 networking.c:304 msgid "Network configuration type" -msgstr "" +msgstr "چگونگی پیکربندی شبکه"
#: networking.c:238 networking.c:409 msgid "Drivers and card assignments" -msgstr "" +msgstr "راه انداز ها و تکالیف کارت ها"
#: networking.c:239 networking.c:640 msgid "Address settings" @@ -428,11 +429,11 @@ msgstr "پیکربندی آدرس"
#: networking.c:240 networking.c:743 msgid "DNS and Gateway settings" -msgstr "" +msgstr "پیکربندی DNS و Gateway"
#: networking.c:260 msgid "When configuration is complete, a network restart will be required." -msgstr "" +msgstr "وقتی پیکربندی کامل شد سرویس شبکه در صورت نیاز راه اندازی مجدد خواهد شد"
#: networking.c:267 #, c-format @@ -440,11 +441,11 @@ msgid "" "Current config: %s\n" "\n" "%s" -msgstr "" +msgstr "پیکربندی جاری: %s\n\n%s"
#: networking.c:268 msgid "Network configuration menu" -msgstr "" +msgstr "منوی پیکربندی شبکه"
#: networking.c:269 networking.c:520 networking.c:642 msgid "Done" @@ -457,7 +458,7 @@ msgid "" "list those interfaces which have ethernet attached. If you change this " "setting, a network restart will be required, and you will have to " "reconfigure the network driver assignments." -msgstr "" +msgstr "پیکربندی شبکه برای %s را گزینش کنید. لیست روش های پیکربندی زیر آن اینترفیس ها، وقتیکه به شبکه متصل شده اند. اگر شما پیکربندی را دگرگون سازید، یک شبکه نیاز به خاموش روشن دارد، و شما راه انداز شبکه اختصاص داده شده را دوباره پیکربندی کنید."
#: networking.c:307 #, c-format @@ -465,7 +466,7 @@ msgid "" "Not enough netcards for your choice.\n" "\n" "Needed: %d - Available: %d\n" -msgstr "" +msgstr "کارتهای شبکه برای گزینش شما کافی نیست.\n\nنیازمند: %d - در دسترس: %d\n"
#: networking.c:359 msgid "" @@ -475,21 +476,21 @@ msgstr ""
#: networking.c:408 msgid "Do you wish to change these settings?" -msgstr "" +msgstr "ایا قصد دارید این تنظیمات تغییر دهید؟"
#: networking.c:447 msgid "Restarting non-local network..." -msgstr "" +msgstr "شروع دوباره شبکه..."
#: networking.c:464 msgid "" "Please choose the interface you wish to change.\n" "\n" -msgstr "" +msgstr "خواهشمند است اینترفیسی را که می خواهید دگرگون سازید را گزینش کنید.\n\n"
#: networking.c:519 msgid "Assigned Cards" -msgstr "" +msgstr "کارت های واگذار شده"
#: networking.c:520 msgid "Remove" @@ -506,7 +507,7 @@ msgstr ""
#: networking.c:641 msgid "Select the interface you wish to reconfigure." -msgstr "" +msgstr "اینترفیس که قصد پیکربندی مجدد را دارید انتخاب کنید"
#: networking.c:729 msgid "Default gateway:" @@ -524,12 +525,12 @@ msgstr "Gateway پیش پندار"
#: networking.c:780 msgid "Secondary DNS specified without a Primary DNS" -msgstr "" +msgstr "دومین DNS بدون پیکربندی نخستین DNS"
#: passwords.c:33 msgid "" "Enter the 'root' user password. Login as this user for commandline access." -msgstr "" +msgstr "رمز عبور کاربر ریشه را وارد کنید.این کاربر سطح دسترسی خط فرمان را فراهم میکند"
#: passwords.c:38 passwords.c:61 msgid "Setting password" @@ -558,7 +559,7 @@ msgstr "پیکربندی %s 'admin' گذر واژه کاربر..." #: passwords.c:62 #, c-format msgid "Problem setting %s 'admin' user password." -msgstr "" +msgstr "ایراد در پیکربندی %s گذر واژه کاربر 'admin'"
#: passwords.c:76 msgid "Password:" @@ -582,4 +583,4 @@ msgstr "در گذر واژه نمی توان فاصله گذاشت."
#: timezone.c:77 msgid "Choose the timezone you are in from the list below." -msgstr "" +msgstr " از لیست منطقه زمانی خود را انتخاب کنید" diff --git a/src/setup/po/fr.po b/src/setup/po/fr.po index 914095d..eb04ad4 100644 --- a/src/setup/po/fr.po +++ b/src/setup/po/fr.po @@ -3,13 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# irenee Munyaneza muirenee@yahoo.fr, 2014 msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-08-21 15:12+0000\n" -"PO-Revision-Date: 2014-08-21 15:13+0000\n" -"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"PO-Revision-Date: 2014-10-06 16:32+0000\n" +"Last-Translator: irenee Munyaneza muirenee@yahoo.fr\n" "Language-Team: French (http://www.transifex.com/projects/p/ipfire/language/fr/)%5Cn" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -78,7 +79,7 @@ msgstr "" #: networking.c:410 networking.c:560 networking.c:653 networking.c:746 #: passwords.c:89 timezone.c:78 msgid "Cancel" -msgstr "" +msgstr "Annuler"
#: dhcp.c:156 msgid "" @@ -112,7 +113,7 @@ msgstr ""
#: domainname.c:42 main.c:70 msgid "Domain name" -msgstr "" +msgstr "Nom de domaine"
#: domainname.c:42 msgid "Enter Domain name" @@ -200,7 +201,7 @@ msgstr ""
#: main.c:174 netstuff.c:733 networking.c:560 networking.c:653 msgid "Warning" -msgstr "" +msgstr "Avertissement"
#: main.c:175 msgid "" @@ -273,7 +274,7 @@ msgstr ""
#: netstuff.c:134 msgid "IP address:" -msgstr "" +msgstr "Adresse IP"
#: netstuff.c:146 msgid "Network mask:" @@ -285,7 +286,7 @@ msgstr ""
#: netstuff.c:183 msgid "IP address" -msgstr "" +msgstr "Adresse IP"
#: netstuff.c:189 msgid "Network mask" @@ -355,7 +356,7 @@ msgstr ""
#: netstuff.c:780 msgid "Module name cannot be blank." -msgstr "" +msgstr "Le nom du module ne doit pas être vide"
#: networking.c:110 msgid "Stopping network..." @@ -375,7 +376,7 @@ msgstr ""
#: networking.c:163 msgid "Error" -msgstr "" +msgstr "Erreur"
#: networking.c:163 msgid "Ignore" @@ -423,7 +424,7 @@ msgstr ""
#: networking.c:239 networking.c:640 msgid "Address settings" -msgstr "" +msgstr "Configuration d'adresse"
#: networking.c:240 networking.c:743 msgid "DNS and Gateway settings" @@ -443,7 +444,7 @@ msgstr ""
#: networking.c:268 msgid "Network configuration menu" -msgstr "" +msgstr "Menu de configuration Reseau"
#: networking.c:269 networking.c:520 networking.c:642 msgid "Done" @@ -488,7 +489,7 @@ msgstr ""
#: networking.c:519 msgid "Assigned Cards" -msgstr "" +msgstr "Cartes attribuées"
#: networking.c:520 msgid "Remove" @@ -509,7 +510,7 @@ msgstr ""
#: networking.c:729 msgid "Default gateway:" -msgstr "" +msgstr "Passerelle par defaut"
#: networking.c:744 msgid "" @@ -519,7 +520,7 @@ msgstr ""
#: networking.c:773 msgid "Default gateway" -msgstr "" +msgstr "Passerelle par défaut"
#: networking.c:780 msgid "Secondary DNS specified without a Primary DNS" @@ -532,7 +533,7 @@ msgstr ""
#: passwords.c:38 passwords.c:61 msgid "Setting password" -msgstr "" +msgstr "Configuration du mot de passe"
#: passwords.c:38 msgid "Setting 'root' password...." @@ -561,15 +562,15 @@ msgstr ""
#: passwords.c:76 msgid "Password:" -msgstr "" +msgstr "Mot de passe"
#: passwords.c:77 msgid "Again:" -msgstr "" +msgstr "Encore"
#: passwords.c:95 msgid "Password cannot be blank." -msgstr "" +msgstr "Le mot de passe ne doit pas être vide"
#: passwords.c:102 msgid "Passwords do not match." @@ -577,7 +578,7 @@ msgstr ""
#: passwords.c:109 msgid "Password cannot contain spaces." -msgstr "" +msgstr "Le mot de passe ne doit pas contenir des espaces"
#: timezone.c:77 msgid "Choose the timezone you are in from the list below." diff --git a/src/setup/po/hr.po b/src/setup/po/hr.po new file mode 100644 index 0000000..3ecc4d3 --- /dev/null +++ b/src/setup/po/hr.po @@ -0,0 +1,584 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR The IPFire Project (www.ipfire.org) +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: IPFire Project\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-08-21 15:12+0000\n" +"PO-Revision-Date: 2014-10-31 14:31+0000\n" +"Last-Translator: Blago Culjak blago.culjak@hotmail.com\n" +"Language-Team: Croatian (http://www.transifex.com/projects/p/ipfire/language/hr/)%5Cn" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: hr\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: dhcp.c:50 +msgid "Start address:" +msgstr "Početna adresa:" + +#: dhcp.c:51 +msgid "End address:" +msgstr "Krajna adresa:" + +#: dhcp.c:52 networking.c:717 +msgid "Primary DNS:" +msgstr "Primarni DNS:" + +#: dhcp.c:53 networking.c:723 +msgid "Secondary DNS:" +msgstr "Sekundarni DNS:" + +#: dhcp.c:54 +msgid "Default lease (mins):" +msgstr "Zadani zakup (min):" + +#: dhcp.c:55 +msgid "Max lease (mins):" +msgstr "Max zakup (min):" + +#: dhcp.c:56 +msgid "Domain name suffix:" +msgstr "Sufiks naziva domene:" + +#: dhcp.c:86 dhcp.c:93 dhcp.c:101 domainname.c:34 hostname.c:37 keymap.c:70 +#: misc.c:40 misc.c:52 netstuff.c:377 netstuff.c:566 netstuff.c:704 +#: networking.c:134 networking.c:255 networking.c:291 networking.c:346 +#: networking.c:442 networking.c:552 networking.c:603 networking.c:610 +#: networking.c:713 timezone.c:63 +msgid "Unable to open settings file" +msgstr "Nije moguće otvoriti datoteku s postavkama" + +#: dhcp.c:111 +msgid "DHCP server configuration" +msgstr "Konfiguracija DHCP poslužitelja" + +#: dhcp.c:116 +msgid "Configure the DHCP server by entering the settings information." +msgstr "Konfiguracija DHCP poslužitelj s unosom postavki." + +#: dhcp.c:125 +msgid "Enabled" +msgstr "Omogućeno" + +#: dhcp.c:142 domainname.c:43 hostname.c:47 keymap.c:86 main.c:99 main.c:172 +#: main.c:174 netstuff.c:157 netstuff.c:733 netstuff.c:756 networking.c:163 +#: networking.c:269 networking.c:305 networking.c:409 networking.c:560 +#: networking.c:642 networking.c:653 networking.c:746 passwords.c:89 +#: timezone.c:78 +msgid "OK" +msgstr "OK" + +#: dhcp.c:143 domainname.c:43 hostname.c:47 keymap.c:86 netstuff.c:158 +#: netstuff.c:673 netstuff.c:733 netstuff.c:756 networking.c:305 +#: networking.c:410 networking.c:560 networking.c:653 networking.c:746 +#: passwords.c:89 timezone.c:78 +msgid "Cancel" +msgstr "Otkazati" + +#: dhcp.c:156 +msgid "" +"The following fields are invalid:\n" +"\n" +msgstr "Sljedeća polja su nevažeća:\n\n" + +#: dhcp.c:159 +msgid "Start address" +msgstr "Početna adresa" + +#: dhcp.c:165 +msgid "End address" +msgstr "Završna adresa" + +#: dhcp.c:173 networking.c:755 +msgid "Primary DNS" +msgstr "Primarni DNS" + +#: dhcp.c:182 networking.c:764 +msgid "Secondary DNS" +msgstr "Sekundarni DNS" + +#: dhcp.c:189 +msgid "Default lease time" +msgstr "Zadano vrijeme zakupa" + +#: dhcp.c:195 +msgid "Max. lease time" +msgstr "Max. vrijeme zakupa" + +#: domainname.c:42 main.c:70 +msgid "Domain name" +msgstr "Naziv domene" + +#: domainname.c:42 +msgid "Enter Domain name" +msgstr "Unesite naziv domene" + +#: domainname.c:48 +msgid "Domain name cannot be empty." +msgstr "Naziv domene ne smije biti prazan." + +#: domainname.c:50 +msgid "Domain name cannot contain spaces." +msgstr "Naziv domene ne smije sadržavati razmake." + +#: domainname.c:53 +msgid "Domain name may only contain letters, numbers, hyphens and periods." +msgstr "Naziv domene može sadržavati samo slova, brojeve, crtice i točkice." + +#: hostname.c:46 main.c:69 +msgid "Hostname" +msgstr "Ime računala" + +#: hostname.c:46 +msgid "Enter the machine's hostname." +msgstr "Upišite naziv računala." + +#: hostname.c:53 +msgid "Hostname cannot be empty." +msgstr "Naziv računala ne može biti prazan." + +#: hostname.c:55 +msgid "Hostname cannot contain spaces." +msgstr "Naziv računala ne može sadržavati razmake." + +#: hostname.c:58 +msgid "Hostname may only contain letters, numbers and hyphens." +msgstr "Naziv računala može sadržavati samo slova, brojeve i crtice." + +#: keymap.c:84 main.c:67 +msgid "Keyboard mapping" +msgstr "Vrsta tipkovnice" + +#: keymap.c:85 +msgid "Choose the type of keyboard you are using from the list below." +msgstr "Izaberite vrstu tipkovnice koju koristite s popisa u nastavku." + +#: main.c:68 timezone.c:77 +msgid "Timezone" +msgstr "Vremenska zona" + +#: main.c:71 networking.c:110 networking.c:115 networking.c:447 +msgid "Networking" +msgstr "Mreža" + +#: main.c:72 misc.c:147 +msgid "ISDN" +msgstr "ISDN" + +#: main.c:73 +msgid "'root' password" +msgstr "'root' lozinka" + +#: main.c:74 +msgid "'admin' password" +msgstr "'admin' lozinka" + +#: main.c:90 +msgid " <Tab>/<Alt-Tab> between elements | <Space> selects" +msgstr " <Tab>/<Alt-Tab> odabiranje drugih opcija | <Space> Izaberi" + +#: main.c:97 +msgid "Section menu" +msgstr "Izbornik" + +#: main.c:98 +msgid "Select the item you wish to configure." +msgstr "Odaberite stavku koju želite konfigurirati." + +#: main.c:99 +msgid "Quit" +msgstr "Odustati" + +#: main.c:172 +msgid "Setup is complete." +msgstr "Podešavanje je dovršeno." + +#: main.c:174 netstuff.c:733 networking.c:560 networking.c:653 +msgid "Warning" +msgstr "Upozorenje" + +#: main.c:175 +msgid "" +"Initial setup was not entirely complete. You must ensure that Setup is " +"properly finished by running setup again at the shell." +msgstr "Početno postavljanje nije u potpunosti završeno. Morate završiti postavljanje prije ponovnog postavljanja u shellu." + +#: misc.c:62 +#, c-format +msgid "Unable to write %s/main/hostname.conf" +msgstr "Nije moguće zapisati %s/main/hostname.conf" + +#: misc.c:71 +msgid "Unable to open main hosts file." +msgstr "Nije moguće otvoriti glavnu hosts datoteku." + +#: misc.c:76 +msgid "Unable to write /etc/hosts." +msgstr "Nije moguće zapisati /etc/hosts." + +#: misc.c:117 +msgid "Unable to write /etc/hosts.deny." +msgstr "Nije moguće zapisati /etc/hosts.deny" + +#: misc.c:125 +msgid "Unable to write /etc/hosts.allow." +msgstr "Nije moguće zapisati /etc/hosts.allow." + +#: misc.c:136 +msgid "Unable to set hostname." +msgstr "Nije moguće postaviti naziv računala (hostname)." + +#: misc.c:147 +msgid "Scanning and configuring ISDN devices." +msgstr "Skeniranje i postavljanje ISDN uređaja." + +#: misc.c:148 +msgid "Unable to scan for ISDN devices." +msgstr "Nije moguće skenirati ISDN uređaj." + +#: netstuff.c:86 +#, c-format +msgid "Interface - %s" +msgstr "Sučelje - %s" + +#: netstuff.c:91 +#, c-format +msgid "Enter the IP address information for the %s interface." +msgstr "Unesite podatke o IP adresi za %s sučelje." + +#: netstuff.c:103 +msgid "Static" +msgstr "Statička" + +#: netstuff.c:104 +msgid "DHCP" +msgstr "DHCP" + +#: netstuff.c:105 +msgid "PPP DIALUP (PPPoE, modem, ATM ...)" +msgstr "PPP DIALUP (PPPoE, modem, ATM ...)" + +#: netstuff.c:113 +msgid "DHCP Hostname:" +msgstr "DHCP naziv računala:" + +#: netstuff.c:115 +msgid "Force DHCP MTU:" +msgstr "Prisili DHCP MTU:" + +#: netstuff.c:134 +msgid "IP address:" +msgstr "IP adresa:" + +#: netstuff.c:146 +msgid "Network mask:" +msgstr "Mreža maska:" + +#: netstuff.c:173 networking.c:749 +msgid "The following fields are invalid:" +msgstr "Sljedeća polja su nevažeća:" + +#: netstuff.c:183 +msgid "IP address" +msgstr "IP adresa" + +#: netstuff.c:189 +msgid "Network mask" +msgstr "Mreža maska" + +#: netstuff.c:198 +msgid "DHCP hostname" +msgstr "DHCP naziv računala" + +#: netstuff.c:396 netstuff.c:709 +msgid "Unset" +msgstr "Nije postavljeno" + +#: netstuff.c:669 +#, c-format +msgid "Please choose a networkcard for the following interface - %s." +msgstr "Odaberite mrežnu karticu za sučelje - %s." + +#: netstuff.c:672 +msgid "Extended Network Menu" +msgstr "Dodatni izbornik mreže" + +#: netstuff.c:673 networking.c:520 +msgid "Select" +msgstr "Odabrati" + +#: netstuff.c:673 +msgid "Identify" +msgstr "Identificirati" + +#: netstuff.c:678 +msgid "Device Identification" +msgstr "Identifikacija uređaja" + +#: netstuff.c:678 +msgid "The lights on the selected port should flash now for 10 seconds..." +msgstr "Svjetla na odabranom ulazu bi trebala bljeskati 10 sekundi..." + +#: netstuff.c:679 +msgid "Identification is not supported by this interface." +msgstr "Identifikacija ne podržava ovo sučelje." + +#: netstuff.c:691 +msgid "There are no unassigned interfaces on your system." +msgstr "Nema dodijeljenih sučelja na vašem sustavu." + +#: netstuff.c:732 +#, c-format +msgid "Do you really want to remove the assigned %s interface?" +msgstr "Da li stvarno želite ukloniti dodijeljeno %s sučelje?" + +#: netstuff.c:755 +msgid "Select network driver" +msgstr "Odaberite mrežni driver" + +#: netstuff.c:755 +msgid "Set additional module parameters" +msgstr "Postavite dodatne parametre modula" + +#: netstuff.c:762 +msgid "Loading module..." +msgstr "Očitavam modul..." + +#: netstuff.c:777 +msgid "Unable to load driver module." +msgstr "Nije moguće učitati upravljački modul." + +#: netstuff.c:780 +msgid "Module name cannot be blank." +msgstr "Naziv modula ne može biti prazan." + +#: networking.c:110 +msgid "Stopping network..." +msgstr "Zaustavljanje mreže..." + +#: networking.c:115 +msgid "Restarting network..." +msgstr "Ponovno pokretanje mreže..." + +#: networking.c:146 +msgid "No GREEN interface assigned." +msgstr "Nije dodijeljeno GREEN sučelje." + +#: networking.c:152 +msgid "Missing an IP address on GREEN." +msgstr "Nedostaje IP adresa na GREEN sučelju." + +#: networking.c:163 +msgid "Error" +msgstr "Pogreška" + +#: networking.c:163 +msgid "Ignore" +msgstr "Ignorirati" + +#: networking.c:164 +msgid "No RED interface assigned." +msgstr "Nije dodijeljeno RED sučelje." + +#: networking.c:173 +msgid "Missing an IP address on RED." +msgstr "Nedostaje IP adresu na RED sučelju." + +#: networking.c:183 +msgid "No ORANGE interface assigned." +msgstr "Nije dodijeljeno ORANGE sučelje." + +#: networking.c:189 +msgid "Missing an IP address on ORANGE." +msgstr "Nedostaje IP adresu na Orange sučelju." + +#: networking.c:199 +msgid "No BLUE interface assigned." +msgstr "Nije dodijeljeno BLUE sučelje." + +#: networking.c:205 +msgid "Missing an IP address on BLUE." +msgstr "Nedostaje IP adresu na BLUE sučelju." + +#: networking.c:217 +msgid "Misssing DNS." +msgstr "Nedostaje DNS." + +#: networking.c:224 +msgid "Missing Default Gateway." +msgstr "Nedostaje Zadani Gateway." + +#: networking.c:237 networking.c:304 +msgid "Network configuration type" +msgstr "Tip mrežnih postavki" + +#: networking.c:238 networking.c:409 +msgid "Drivers and card assignments" +msgstr "Driveri i dodjele kartice" + +#: networking.c:239 networking.c:640 +msgid "Address settings" +msgstr "Postavke adresa" + +#: networking.c:240 networking.c:743 +msgid "DNS and Gateway settings" +msgstr "DNS i Gateway postavke" + +#: networking.c:260 +msgid "When configuration is complete, a network restart will be required." +msgstr "Kad konfiguracija je završi, ponovno pokretanje mreže je obvezno." + +#: networking.c:267 +#, c-format +msgid "" +"Current config: %s\n" +"\n" +"%s" +msgstr "Trenutna konfiguracija:%s\n\n%s" + +#: networking.c:268 +msgid "Network configuration menu" +msgstr "Izbornik postavki mreže" + +#: networking.c:269 networking.c:520 networking.c:642 +msgid "Done" +msgstr "Završeno" + +#: networking.c:300 +#, c-format +msgid "" +"Select the network configuration for %s. The following configuration types " +"list those interfaces which have ethernet attached. If you change this " +"setting, a network restart will be required, and you will have to " +"reconfigure the network driver assignments." +msgstr "Odaberite konfiguraciju mreže za %s. Sljedeća lista su vrste postavki onih Ethernet sučelja koja su dodana. Ako promijenite ovu postavku, ponovno pokretanje mreže će biti potrebno, a vi ćete morati ponovno dodijeliti mrežne drivere." + +#: networking.c:307 +#, c-format +msgid "" +"Not enough netcards for your choice.\n" +"\n" +"Needed: %d - Available: %d\n" +msgstr "Nema dovoljno nmrežnih kartica za vaš izbor.\n\nPotrebno: %d - Dostupno: %d\n" + +#: networking.c:359 +msgid "" +"Configure network drivers, and which interface each card is assigned to. The current configuration is as follows:\n" +"\n" +msgstr "Konfiguracija mrežnih upravljačkih programa, svakome sučelju kojemu kartica je dodijeljena. Trenutna konfiguracija: \n\n" + +#: networking.c:408 +msgid "Do you wish to change these settings?" +msgstr "Želite li promijeniti ove postavke?" + +#: networking.c:447 +msgid "Restarting non-local network..." +msgstr "Ponovno pokretanje ne-lokalne mreže ..." + +#: networking.c:464 +msgid "" +"Please choose the interface you wish to change.\n" +"\n" +msgstr "Odaberite sučelje koje želite promijeniti. \n\n" + +#: networking.c:519 +msgid "Assigned Cards" +msgstr "Dodijeljene kartice" + +#: networking.c:520 +msgid "Remove" +msgstr "Ukloniti" + +#: networking.c:556 networking.c:649 +#, c-format +msgid "" +"If you change this IP address, and you are logged in remotely, your " +"connection to the %s machine will be broken, and you will have to reconnect " +"on the new IP. This is a risky operation, and should only be attempted if " +"you have physical access to the machine, should something go wrong." +msgstr "Ako promijenite ovu IP adresu, i ako ste prijavljeni udaljeno, vaša veza s %s će biti prekinuta, a vi ćete morati ponovno povezati na novu IP adresu. Pošto je ovo rizično, te bi trebali ovo raditi samo ako imate fizički pristup uređaju, ako nešto pođe krivo." + +#: networking.c:641 +msgid "Select the interface you wish to reconfigure." +msgstr "Izaberite sučelje koje želite ponovo konfigurirati." + +#: networking.c:729 +msgid "Default gateway:" +msgstr "Zadani pristupnik (gateway):" + +#: networking.c:744 +msgid "" +"Enter the DNS and gateway information. These settings are used only with " +"Static IP (and DHCP if DNS set) on the RED interface." +msgstr "Unesite DNS i gateway informacije. Ove postavke se koristite samo s Statičkim IP-om (i DHCP ako je DNS postavljen) na RED sučelju." + +#: networking.c:773 +msgid "Default gateway" +msgstr "Zadani pristupnik (gateway):" + +#: networking.c:780 +msgid "Secondary DNS specified without a Primary DNS" +msgstr "Sekundarni DNS je naveden bez Primarnog DNSa" + +#: passwords.c:33 +msgid "" +"Enter the 'root' user password. Login as this user for commandline access." +msgstr "Unesite 'root' lozinku. Prijavite se kao ovoj korisnik za Commandline pristup." + +#: passwords.c:38 passwords.c:61 +msgid "Setting password" +msgstr "Postavljanje lozinke" + +#: passwords.c:38 +msgid "Setting 'root' password...." +msgstr "Postavljanje 'root' lozinke...." + +#: passwords.c:39 +msgid "Problem setting 'root' password." +msgstr "Problem s postavljanjem 'root' lozinke." + +#: passwords.c:53 +#, c-format +msgid "" +"Enter %s 'admin' user password. This is the user to use for logging into the" +" %s web administration pages." +msgstr "Upišite %s 'admin' lozinku. To je korisnik koji se prijavljiva na %s web sučelje za administraciju." + +#: passwords.c:60 +#, c-format +msgid "Setting %s 'admin' user password..." +msgstr "Postavljanje %s 'admin' korisničke lozinke ..." + +#: passwords.c:62 +#, c-format +msgid "Problem setting %s 'admin' user password." +msgstr "Problem postavljanja %s 'admin' korisničke lozinke." + +#: passwords.c:76 +msgid "Password:" +msgstr "Lozinka:" + +#: passwords.c:77 +msgid "Again:" +msgstr "Ponovno:" + +#: passwords.c:95 +msgid "Password cannot be blank." +msgstr "Lozinka ne može biti prazna." + +#: passwords.c:102 +msgid "Passwords do not match." +msgstr "Lozinke se ne podudaraju." + +#: passwords.c:109 +msgid "Password cannot contain spaces." +msgstr "Lozinka ne može sadržavati razmak." + +#: timezone.c:77 +msgid "Choose the timezone you are in from the list below." +msgstr "Odaberite vremensku zonu u kojoj se nalazite na popisu." diff --git a/src/setup/po/it.po b/src/setup/po/it.po index 8f14b37..778a65e 100644 --- a/src/setup/po/it.po +++ b/src/setup/po/it.po @@ -3,13 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# luX lucianocataldo@gmail.com, 2014 +# Mario mc9085@mclink.it, 2014 msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-08-21 15:12+0000\n" -"PO-Revision-Date: 2014-08-21 15:13+0000\n" -"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"PO-Revision-Date: 2014-09-30 13:22+0000\n" +"Last-Translator: Mario mc9085@mclink.it\n" "Language-Team: Italian (http://www.transifex.com/projects/p/ipfire/language/it/)%5Cn" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,31 +21,31 @@ msgstr ""
#: dhcp.c:50 msgid "Start address:" -msgstr "" +msgstr "Indirizzo iniziale:"
#: dhcp.c:51 msgid "End address:" -msgstr "" +msgstr "Indirizzo finale:"
#: dhcp.c:52 networking.c:717 msgid "Primary DNS:" -msgstr "" +msgstr "DNS primario:"
#: dhcp.c:53 networking.c:723 msgid "Secondary DNS:" -msgstr "" +msgstr "DNS secondario:"
#: dhcp.c:54 msgid "Default lease (mins):" -msgstr "" +msgstr "Durata di Default del lease (min):"
#: dhcp.c:55 msgid "Max lease (mins):" -msgstr "" +msgstr "Durata massima del lease (min):"
#: dhcp.c:56 msgid "Domain name suffix:" -msgstr "" +msgstr "Suffisso del nome di Dominio:"
#: dhcp.c:86 dhcp.c:93 dhcp.c:101 domainname.c:34 hostname.c:37 keymap.c:70 #: misc.c:40 misc.c:52 netstuff.c:377 netstuff.c:566 netstuff.c:704 @@ -51,19 +53,19 @@ msgstr "" #: networking.c:442 networking.c:552 networking.c:603 networking.c:610 #: networking.c:713 timezone.c:63 msgid "Unable to open settings file" -msgstr "" +msgstr "Impossibile aprire il file delle impostazioni"
#: dhcp.c:111 msgid "DHCP server configuration" -msgstr "" +msgstr "Configurazione server DHCP"
#: dhcp.c:116 msgid "Configure the DHCP server by entering the settings information." -msgstr "" +msgstr "Configura il server DHCP immettendo le informazioni necessarie."
#: dhcp.c:125 msgid "Enabled" -msgstr "" +msgstr "Abilitato"
#: dhcp.c:142 domainname.c:43 hostname.c:47 keymap.c:86 main.c:99 main.c:172 #: main.c:174 netstuff.c:157 netstuff.c:733 netstuff.c:756 networking.c:163 @@ -71,367 +73,367 @@ msgstr "" #: networking.c:642 networking.c:653 networking.c:746 passwords.c:89 #: timezone.c:78 msgid "OK" -msgstr "" +msgstr "OK"
#: dhcp.c:143 domainname.c:43 hostname.c:47 keymap.c:86 netstuff.c:158 #: netstuff.c:673 netstuff.c:733 netstuff.c:756 networking.c:305 #: networking.c:410 networking.c:560 networking.c:653 networking.c:746 #: passwords.c:89 timezone.c:78 msgid "Cancel" -msgstr "" +msgstr "Annulla"
#: dhcp.c:156 msgid "" "The following fields are invalid:\n" "\n" -msgstr "" +msgstr "I seguenti campi non sono validi:\n\n"
#: dhcp.c:159 msgid "Start address" -msgstr "" +msgstr "Indirizzo iniziale"
#: dhcp.c:165 msgid "End address" -msgstr "" +msgstr "Indirizzo finale"
#: dhcp.c:173 networking.c:755 msgid "Primary DNS" -msgstr "" +msgstr "DNS primario"
#: dhcp.c:182 networking.c:764 msgid "Secondary DNS" -msgstr "" +msgstr "DNS secondario"
#: dhcp.c:189 msgid "Default lease time" -msgstr "" +msgstr "Tempo di lease di Default"
#: dhcp.c:195 msgid "Max. lease time" -msgstr "" +msgstr "Tempo di lease massimo"
#: domainname.c:42 main.c:70 msgid "Domain name" -msgstr "" +msgstr "Nome di Dominio"
#: domainname.c:42 msgid "Enter Domain name" -msgstr "" +msgstr "Inserire il nome del Dominio"
#: domainname.c:48 msgid "Domain name cannot be empty." -msgstr "" +msgstr "Il nome di Dominio non può essere vuoto."
#: domainname.c:50 msgid "Domain name cannot contain spaces." -msgstr "" +msgstr "Il nome di dominio non può contenere spazi."
#: domainname.c:53 msgid "Domain name may only contain letters, numbers, hyphens and periods." -msgstr "" +msgstr "Il nome del Dominio può contenere solamente lettere, numeri, trattini e punti."
#: hostname.c:46 main.c:69 msgid "Hostname" -msgstr "" +msgstr "Nome host"
#: hostname.c:46 msgid "Enter the machine's hostname." -msgstr "" +msgstr "Inserire il nome host della macchina."
#: hostname.c:53 msgid "Hostname cannot be empty." -msgstr "" +msgstr "Il nome host non può essere vuoto."
#: hostname.c:55 msgid "Hostname cannot contain spaces." -msgstr "" +msgstr "Il nome host non può contenere spazi"
#: hostname.c:58 msgid "Hostname may only contain letters, numbers and hyphens." -msgstr "" +msgstr "Il nome host può contenere solo lettere, numeri e trattini."
#: keymap.c:84 main.c:67 msgid "Keyboard mapping" -msgstr "" +msgstr "Mappatura della tastiera"
#: keymap.c:85 msgid "Choose the type of keyboard you are using from the list below." -msgstr "" +msgstr "Scegli la configurazione della tua tastiera dalla lista sottostante."
#: main.c:68 timezone.c:77 msgid "Timezone" -msgstr "" +msgstr "Fuso orario"
#: main.c:71 networking.c:110 networking.c:115 networking.c:447 msgid "Networking" -msgstr "" +msgstr "Networking"
#: main.c:72 misc.c:147 msgid "ISDN" -msgstr "" +msgstr "ISDN"
#: main.c:73 msgid "'root' password" -msgstr "" +msgstr "Password di 'root'"
#: main.c:74 msgid "'admin' password" -msgstr "" +msgstr "Password di 'admin'"
#: main.c:90 msgid " <Tab>/<Alt-Tab> between elements | <Space> selects" -msgstr "" +msgstr "<Tab>/<Alt-Tab> spostati tra gli elementi | <Space> selezione"
#: main.c:97 msgid "Section menu" -msgstr "" +msgstr "Menu di sezione"
#: main.c:98 msgid "Select the item you wish to configure." -msgstr "" +msgstr "Scegli l'elemento che vuoi configurare."
#: main.c:99 msgid "Quit" -msgstr "" +msgstr "Abbandona"
#: main.c:172 msgid "Setup is complete." -msgstr "" +msgstr "L'installazione è completata."
#: main.c:174 netstuff.c:733 networking.c:560 networking.c:653 msgid "Warning" -msgstr "" +msgstr "Attenzione"
#: main.c:175 msgid "" "Initial setup was not entirely complete. You must ensure that Setup is " "properly finished by running setup again at the shell." -msgstr "" +msgstr "Il setup iniziale non è stato completato. Completa il Setup inserendo la stinga "setup" nella shell. "
#: misc.c:62 #, c-format msgid "Unable to write %s/main/hostname.conf" -msgstr "" +msgstr "Impossibile scrivere %s/main/hostname.conf"
#: misc.c:71 msgid "Unable to open main hosts file." -msgstr "" +msgstr "Impossibile aprire il file hosts principale."
#: misc.c:76 msgid "Unable to write /etc/hosts." -msgstr "" +msgstr "Impossibile scrivere /etc/hosts."
#: misc.c:117 msgid "Unable to write /etc/hosts.deny." -msgstr "" +msgstr "Impossibile scrivere /etc/hosts.deny."
#: misc.c:125 msgid "Unable to write /etc/hosts.allow." -msgstr "" +msgstr "Impossibile scrivere /etc/hosts.allow."
#: misc.c:136 msgid "Unable to set hostname." -msgstr "" +msgstr "Impossibile impostare l'hostname."
#: misc.c:147 msgid "Scanning and configuring ISDN devices." -msgstr "" +msgstr "Scansionando e configurando i dispositivi ISDN."
#: misc.c:148 msgid "Unable to scan for ISDN devices." -msgstr "" +msgstr "Impossibile scansionare i dispositivi ISDN."
#: netstuff.c:86 #, c-format msgid "Interface - %s" -msgstr "" +msgstr "Interfaccia - %s"
#: netstuff.c:91 #, c-format msgid "Enter the IP address information for the %s interface." -msgstr "" +msgstr "Inserisci l'indirizzo IP per l'interfaccia %s."
#: netstuff.c:103 msgid "Static" -msgstr "" +msgstr "Statico"
#: netstuff.c:104 msgid "DHCP" -msgstr "" +msgstr "DHCP"
#: netstuff.c:105 msgid "PPP DIALUP (PPPoE, modem, ATM ...)" -msgstr "" +msgstr "PPP DIALUP (PPPoE, modem, ATM ...)"
#: netstuff.c:113 msgid "DHCP Hostname:" -msgstr "" +msgstr "DHCP Hostname:"
#: netstuff.c:115 msgid "Force DHCP MTU:" -msgstr "" +msgstr "Forza DHCP MTU:"
#: netstuff.c:134 msgid "IP address:" -msgstr "" +msgstr "Indirizzo IP:"
#: netstuff.c:146 msgid "Network mask:" -msgstr "" +msgstr "Maschera di rete:"
#: netstuff.c:173 networking.c:749 msgid "The following fields are invalid:" -msgstr "" +msgstr "I seguenti campi non sono validi:"
#: netstuff.c:183 msgid "IP address" -msgstr "" +msgstr "Indirizzo IP"
#: netstuff.c:189 msgid "Network mask" -msgstr "" +msgstr "Maschera di rete"
#: netstuff.c:198 msgid "DHCP hostname" -msgstr "" +msgstr "DHCP hostname"
#: netstuff.c:396 netstuff.c:709 msgid "Unset" -msgstr "" +msgstr "Non stabilito"
#: netstuff.c:669 #, c-format msgid "Please choose a networkcard for the following interface - %s." -msgstr "" +msgstr "Scegli una interfaccia di rete tra le seguenti - %s."
#: netstuff.c:672 msgid "Extended Network Menu" -msgstr "" +msgstr "Menu di Rete esteso"
#: netstuff.c:673 networking.c:520 msgid "Select" -msgstr "" +msgstr "Selezionare"
#: netstuff.c:673 msgid "Identify" -msgstr "" +msgstr "Identificare"
#: netstuff.c:678 msgid "Device Identification" -msgstr "" +msgstr "Identificazione del dispositivo"
#: netstuff.c:678 msgid "The lights on the selected port should flash now for 10 seconds..." -msgstr "" +msgstr "I led della porta selezionata lampeggeranno ora per 10 secondi... "
#: netstuff.c:679 msgid "Identification is not supported by this interface." -msgstr "" +msgstr "L'identificazione non è supportata da questa interfaccia."
#: netstuff.c:691 msgid "There are no unassigned interfaces on your system." -msgstr "" +msgstr "Non ci sono interfacce non assegnate nel sistema."
#: netstuff.c:732 #, c-format msgid "Do you really want to remove the assigned %s interface?" -msgstr "" +msgstr "Vuoi veramente rimuovere l'assegnazione dell'l'interfaccia %s?"
#: netstuff.c:755 msgid "Select network driver" -msgstr "" +msgstr "Scegli un driver di rete"
#: netstuff.c:755 msgid "Set additional module parameters" -msgstr "" +msgstr "Inserisci parametri addizionali per il modulo"
#: netstuff.c:762 msgid "Loading module..." -msgstr "" +msgstr "Caricando il modulo..."
#: netstuff.c:777 msgid "Unable to load driver module." -msgstr "" +msgstr "Impossibile caricare i driver per il modulo."
#: netstuff.c:780 msgid "Module name cannot be blank." -msgstr "" +msgstr "Il nome del modulo non può essere lasciato in bianco."
#: networking.c:110 msgid "Stopping network..." -msgstr "" +msgstr "Arrestando la rete..."
#: networking.c:115 msgid "Restarting network..." -msgstr "" +msgstr "Riavviando la rete..."
#: networking.c:146 msgid "No GREEN interface assigned." -msgstr "" +msgstr "Non è stata assegnata l'interfaccia GREEN."
#: networking.c:152 msgid "Missing an IP address on GREEN." -msgstr "" +msgstr "Indirizzo IP dell'interfaccia GREEN mancante."
#: networking.c:163 msgid "Error" -msgstr "" +msgstr "Errore"
#: networking.c:163 msgid "Ignore" -msgstr "" +msgstr "Ignora"
#: networking.c:164 msgid "No RED interface assigned." -msgstr "" +msgstr "Non è stata assegnata l'interfaccia RED."
#: networking.c:173 msgid "Missing an IP address on RED." -msgstr "" +msgstr "Indirizzo IP dell'interfaccia RED mancante."
#: networking.c:183 msgid "No ORANGE interface assigned." -msgstr "" +msgstr "Non è stata assegnata l'interfaccia ORANGE."
#: networking.c:189 msgid "Missing an IP address on ORANGE." -msgstr "" +msgstr "Indirizzo IP dell'interfaccia ORANGE mancante."
#: networking.c:199 msgid "No BLUE interface assigned." -msgstr "" +msgstr "Non è stata assegnata l'interfaccia BLUE."
#: networking.c:205 msgid "Missing an IP address on BLUE." -msgstr "" +msgstr "Indirizzo IP dell'interfaccia BLUE mancante."
#: networking.c:217 msgid "Misssing DNS." -msgstr "" +msgstr "DNS mancanti."
#: networking.c:224 msgid "Missing Default Gateway." -msgstr "" +msgstr "Manca il Gateway di Default."
#: networking.c:237 networking.c:304 msgid "Network configuration type" -msgstr "" +msgstr "Tipo di configurazione di rete."
#: networking.c:238 networking.c:409 msgid "Drivers and card assignments" -msgstr "" +msgstr "Assegnazione dei driver e delle schede"
#: networking.c:239 networking.c:640 msgid "Address settings" -msgstr "" +msgstr "Impostazioni dell'indirizzo"
#: networking.c:240 networking.c:743 msgid "DNS and Gateway settings" -msgstr "" +msgstr "Impostazioni DNG e Gateway"
#: networking.c:260 msgid "When configuration is complete, a network restart will be required." -msgstr "" +msgstr "Quando la configurazione sarà completata, sarà necessario un riavvio della rete."
#: networking.c:267 #, c-format @@ -439,15 +441,15 @@ msgid "" "Current config: %s\n" "\n" "%s" -msgstr "" +msgstr "Configurazione corrente: %s\n\n%s"
#: networking.c:268 msgid "Network configuration menu" -msgstr "" +msgstr "Menu di configurazione della rete"
#: networking.c:269 networking.c:520 networking.c:642 msgid "Done" -msgstr "" +msgstr "Fatto"
#: networking.c:300 #, c-format @@ -456,7 +458,7 @@ msgid "" "list those interfaces which have ethernet attached. If you change this " "setting, a network restart will be required, and you will have to " "reconfigure the network driver assignments." -msgstr "" +msgstr "Scegli la configurazione di rete per l'interfaccia %s. I seguenti tipi di configurazione mostrano le interfacce con collegamento ethernet. Se cambi le impostazioni sarà richiesto un riavvio della rete, e sarà necessario riconfigurare le assegnazioni dei driver di rete."
#: networking.c:307 #, c-format @@ -464,35 +466,35 @@ msgid "" "Not enough netcards for your choice.\n" "\n" "Needed: %d - Available: %d\n" -msgstr "" +msgstr "Non solo più disponibili schede di rete per la tua scelta.\n\nRichieste: %d - Disponibili: %d\n"
#: networking.c:359 msgid "" "Configure network drivers, and which interface each card is assigned to. The current configuration is as follows:\n" "\n" -msgstr "" +msgstr "Configura i driver di rete e le assegnazioni delle schede alle interfacce. La configurazione attuale è la seguente:\n\n"
#: networking.c:408 msgid "Do you wish to change these settings?" -msgstr "" +msgstr "Desideri cambiare queste impostazioni?"
#: networking.c:447 msgid "Restarting non-local network..." -msgstr "" +msgstr "Riavviando la rete esterna..."
#: networking.c:464 msgid "" "Please choose the interface you wish to change.\n" "\n" -msgstr "" +msgstr "Seleziona l'interfaccia che desideri cambiare.\n\n"
#: networking.c:519 msgid "Assigned Cards" -msgstr "" +msgstr "Schede assegnate"
#: networking.c:520 msgid "Remove" -msgstr "" +msgstr "Rimuovi"
#: networking.c:556 networking.c:649 #, c-format @@ -501,84 +503,84 @@ msgid "" "connection to the %s machine will be broken, and you will have to reconnect " "on the new IP. This is a risky operation, and should only be attempted if " "you have physical access to the machine, should something go wrong." -msgstr "" +msgstr "Se cambi l'indirizzo IP e sei collegato in maniera remota, la connessione alla macchina %s sarà interrotta e sarà necessario riconnettersi usando il nuovo indirizzo. Questa è una operazione rischiosa e dovrebbe essere eseguita solamente se è disponibile un accesso fisico alla macchina, in caso qualcosa vada storto. "
#: networking.c:641 msgid "Select the interface you wish to reconfigure." -msgstr "" +msgstr "Scegli l'interfaccia che vuoi riconfigurare."
#: networking.c:729 msgid "Default gateway:" -msgstr "" +msgstr "Gateway di Default:"
#: networking.c:744 msgid "" "Enter the DNS and gateway information. These settings are used only with " "Static IP (and DHCP if DNS set) on the RED interface." -msgstr "" +msgstr "Immettere i parametri per il DNS ed il Gateway. Queste impostazioni saranno prese in considerazione solamente con l'opzione "IP Statico" (e DHCP se sono stati impostati i DNS) dell'interfaccia RED. "
#: networking.c:773 msgid "Default gateway" -msgstr "" +msgstr "Gateway di Default"
#: networking.c:780 msgid "Secondary DNS specified without a Primary DNS" -msgstr "" +msgstr "E' stato specificato un DNS secondario senza un DNS primario"
#: passwords.c:33 msgid "" "Enter the 'root' user password. Login as this user for commandline access." -msgstr "" +msgstr "Immettere la Password per l'utente 'root'. Quando ci si collega da riga di comando, usare questo utente."
#: passwords.c:38 passwords.c:61 msgid "Setting password" -msgstr "" +msgstr "Impostando la Password"
#: passwords.c:38 msgid "Setting 'root' password...." -msgstr "" +msgstr "Impostando la Password per l'utente 'root'..."
#: passwords.c:39 msgid "Problem setting 'root' password." -msgstr "" +msgstr "Problemi durante l'impostazione della Password per l'utente 'root'."
#: passwords.c:53 #, c-format msgid "" "Enter %s 'admin' user password. This is the user to use for logging into the" " %s web administration pages." -msgstr "" +msgstr "Introdurre la Password per l'utente 'admin' di %s. Quando ci si collega all'interfaccia web di %s usare questo utente. "
#: passwords.c:60 #, c-format msgid "Setting %s 'admin' user password..." -msgstr "" +msgstr "Impostando la Password dell'utente 'admin' di %s..."
#: passwords.c:62 #, c-format msgid "Problem setting %s 'admin' user password." -msgstr "" +msgstr "Si sono verificati problemi durante la configurazione della Password dell'utente 'admin' di %s."
#: passwords.c:76 msgid "Password:" -msgstr "" +msgstr "Password:"
#: passwords.c:77 msgid "Again:" -msgstr "" +msgstr "Nuovamente:"
#: passwords.c:95 msgid "Password cannot be blank." -msgstr "" +msgstr "La Password non può essere vuota."
#: passwords.c:102 msgid "Passwords do not match." -msgstr "" +msgstr "Le password non corrispondono."
#: passwords.c:109 msgid "Password cannot contain spaces." -msgstr "" +msgstr "La Password non può contenere spazi."
#: timezone.c:77 msgid "Choose the timezone you are in from the list below." -msgstr "" +msgstr "Scegli il tuo fuso orario dalla lista sottostante." diff --git a/src/setup/po/ja_JP.po b/src/setup/po/ja_JP.po new file mode 100644 index 0000000..0d2d2b6 --- /dev/null +++ b/src/setup/po/ja_JP.po @@ -0,0 +1,584 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR The IPFire Project (www.ipfire.org) +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: IPFire Project\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-08-21 15:12+0000\n" +"PO-Revision-Date: 2014-08-12 10:08+0000\n" +"Last-Translator: FULL NAME EMAIL@ADDRESS\n" +"Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/ipfire/language/ja_JP/)%5Cn" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ja_JP\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: dhcp.c:50 +msgid "Start address:" +msgstr "" + +#: dhcp.c:51 +msgid "End address:" +msgstr "" + +#: dhcp.c:52 networking.c:717 +msgid "Primary DNS:" +msgstr "" + +#: dhcp.c:53 networking.c:723 +msgid "Secondary DNS:" +msgstr "" + +#: dhcp.c:54 +msgid "Default lease (mins):" +msgstr "" + +#: dhcp.c:55 +msgid "Max lease (mins):" +msgstr "" + +#: dhcp.c:56 +msgid "Domain name suffix:" +msgstr "" + +#: dhcp.c:86 dhcp.c:93 dhcp.c:101 domainname.c:34 hostname.c:37 keymap.c:70 +#: misc.c:40 misc.c:52 netstuff.c:377 netstuff.c:566 netstuff.c:704 +#: networking.c:134 networking.c:255 networking.c:291 networking.c:346 +#: networking.c:442 networking.c:552 networking.c:603 networking.c:610 +#: networking.c:713 timezone.c:63 +msgid "Unable to open settings file" +msgstr "" + +#: dhcp.c:111 +msgid "DHCP server configuration" +msgstr "" + +#: dhcp.c:116 +msgid "Configure the DHCP server by entering the settings information." +msgstr "" + +#: dhcp.c:125 +msgid "Enabled" +msgstr "" + +#: dhcp.c:142 domainname.c:43 hostname.c:47 keymap.c:86 main.c:99 main.c:172 +#: main.c:174 netstuff.c:157 netstuff.c:733 netstuff.c:756 networking.c:163 +#: networking.c:269 networking.c:305 networking.c:409 networking.c:560 +#: networking.c:642 networking.c:653 networking.c:746 passwords.c:89 +#: timezone.c:78 +msgid "OK" +msgstr "" + +#: dhcp.c:143 domainname.c:43 hostname.c:47 keymap.c:86 netstuff.c:158 +#: netstuff.c:673 netstuff.c:733 netstuff.c:756 networking.c:305 +#: networking.c:410 networking.c:560 networking.c:653 networking.c:746 +#: passwords.c:89 timezone.c:78 +msgid "Cancel" +msgstr "" + +#: dhcp.c:156 +msgid "" +"The following fields are invalid:\n" +"\n" +msgstr "" + +#: dhcp.c:159 +msgid "Start address" +msgstr "" + +#: dhcp.c:165 +msgid "End address" +msgstr "" + +#: dhcp.c:173 networking.c:755 +msgid "Primary DNS" +msgstr "" + +#: dhcp.c:182 networking.c:764 +msgid "Secondary DNS" +msgstr "" + +#: dhcp.c:189 +msgid "Default lease time" +msgstr "" + +#: dhcp.c:195 +msgid "Max. lease time" +msgstr "" + +#: domainname.c:42 main.c:70 +msgid "Domain name" +msgstr "" + +#: domainname.c:42 +msgid "Enter Domain name" +msgstr "" + +#: domainname.c:48 +msgid "Domain name cannot be empty." +msgstr "" + +#: domainname.c:50 +msgid "Domain name cannot contain spaces." +msgstr "" + +#: domainname.c:53 +msgid "Domain name may only contain letters, numbers, hyphens and periods." +msgstr "" + +#: hostname.c:46 main.c:69 +msgid "Hostname" +msgstr "" + +#: hostname.c:46 +msgid "Enter the machine's hostname." +msgstr "" + +#: hostname.c:53 +msgid "Hostname cannot be empty." +msgstr "" + +#: hostname.c:55 +msgid "Hostname cannot contain spaces." +msgstr "" + +#: hostname.c:58 +msgid "Hostname may only contain letters, numbers and hyphens." +msgstr "" + +#: keymap.c:84 main.c:67 +msgid "Keyboard mapping" +msgstr "" + +#: keymap.c:85 +msgid "Choose the type of keyboard you are using from the list below." +msgstr "" + +#: main.c:68 timezone.c:77 +msgid "Timezone" +msgstr "" + +#: main.c:71 networking.c:110 networking.c:115 networking.c:447 +msgid "Networking" +msgstr "" + +#: main.c:72 misc.c:147 +msgid "ISDN" +msgstr "" + +#: main.c:73 +msgid "'root' password" +msgstr "" + +#: main.c:74 +msgid "'admin' password" +msgstr "" + +#: main.c:90 +msgid " <Tab>/<Alt-Tab> between elements | <Space> selects" +msgstr "" + +#: main.c:97 +msgid "Section menu" +msgstr "" + +#: main.c:98 +msgid "Select the item you wish to configure." +msgstr "" + +#: main.c:99 +msgid "Quit" +msgstr "" + +#: main.c:172 +msgid "Setup is complete." +msgstr "" + +#: main.c:174 netstuff.c:733 networking.c:560 networking.c:653 +msgid "Warning" +msgstr "" + +#: main.c:175 +msgid "" +"Initial setup was not entirely complete. You must ensure that Setup is " +"properly finished by running setup again at the shell." +msgstr "" + +#: misc.c:62 +#, c-format +msgid "Unable to write %s/main/hostname.conf" +msgstr "" + +#: misc.c:71 +msgid "Unable to open main hosts file." +msgstr "" + +#: misc.c:76 +msgid "Unable to write /etc/hosts." +msgstr "" + +#: misc.c:117 +msgid "Unable to write /etc/hosts.deny." +msgstr "" + +#: misc.c:125 +msgid "Unable to write /etc/hosts.allow." +msgstr "" + +#: misc.c:136 +msgid "Unable to set hostname." +msgstr "" + +#: misc.c:147 +msgid "Scanning and configuring ISDN devices." +msgstr "" + +#: misc.c:148 +msgid "Unable to scan for ISDN devices." +msgstr "" + +#: netstuff.c:86 +#, c-format +msgid "Interface - %s" +msgstr "" + +#: netstuff.c:91 +#, c-format +msgid "Enter the IP address information for the %s interface." +msgstr "" + +#: netstuff.c:103 +msgid "Static" +msgstr "" + +#: netstuff.c:104 +msgid "DHCP" +msgstr "" + +#: netstuff.c:105 +msgid "PPP DIALUP (PPPoE, modem, ATM ...)" +msgstr "" + +#: netstuff.c:113 +msgid "DHCP Hostname:" +msgstr "" + +#: netstuff.c:115 +msgid "Force DHCP MTU:" +msgstr "" + +#: netstuff.c:134 +msgid "IP address:" +msgstr "" + +#: netstuff.c:146 +msgid "Network mask:" +msgstr "" + +#: netstuff.c:173 networking.c:749 +msgid "The following fields are invalid:" +msgstr "" + +#: netstuff.c:183 +msgid "IP address" +msgstr "" + +#: netstuff.c:189 +msgid "Network mask" +msgstr "" + +#: netstuff.c:198 +msgid "DHCP hostname" +msgstr "" + +#: netstuff.c:396 netstuff.c:709 +msgid "Unset" +msgstr "" + +#: netstuff.c:669 +#, c-format +msgid "Please choose a networkcard for the following interface - %s." +msgstr "" + +#: netstuff.c:672 +msgid "Extended Network Menu" +msgstr "" + +#: netstuff.c:673 networking.c:520 +msgid "Select" +msgstr "" + +#: netstuff.c:673 +msgid "Identify" +msgstr "" + +#: netstuff.c:678 +msgid "Device Identification" +msgstr "" + +#: netstuff.c:678 +msgid "The lights on the selected port should flash now for 10 seconds..." +msgstr "" + +#: netstuff.c:679 +msgid "Identification is not supported by this interface." +msgstr "" + +#: netstuff.c:691 +msgid "There are no unassigned interfaces on your system." +msgstr "" + +#: netstuff.c:732 +#, c-format +msgid "Do you really want to remove the assigned %s interface?" +msgstr "" + +#: netstuff.c:755 +msgid "Select network driver" +msgstr "" + +#: netstuff.c:755 +msgid "Set additional module parameters" +msgstr "" + +#: netstuff.c:762 +msgid "Loading module..." +msgstr "" + +#: netstuff.c:777 +msgid "Unable to load driver module." +msgstr "" + +#: netstuff.c:780 +msgid "Module name cannot be blank." +msgstr "" + +#: networking.c:110 +msgid "Stopping network..." +msgstr "" + +#: networking.c:115 +msgid "Restarting network..." +msgstr "" + +#: networking.c:146 +msgid "No GREEN interface assigned." +msgstr "" + +#: networking.c:152 +msgid "Missing an IP address on GREEN." +msgstr "" + +#: networking.c:163 +msgid "Error" +msgstr "" + +#: networking.c:163 +msgid "Ignore" +msgstr "" + +#: networking.c:164 +msgid "No RED interface assigned." +msgstr "" + +#: networking.c:173 +msgid "Missing an IP address on RED." +msgstr "" + +#: networking.c:183 +msgid "No ORANGE interface assigned." +msgstr "" + +#: networking.c:189 +msgid "Missing an IP address on ORANGE." +msgstr "" + +#: networking.c:199 +msgid "No BLUE interface assigned." +msgstr "" + +#: networking.c:205 +msgid "Missing an IP address on BLUE." +msgstr "" + +#: networking.c:217 +msgid "Misssing DNS." +msgstr "" + +#: networking.c:224 +msgid "Missing Default Gateway." +msgstr "" + +#: networking.c:237 networking.c:304 +msgid "Network configuration type" +msgstr "" + +#: networking.c:238 networking.c:409 +msgid "Drivers and card assignments" +msgstr "" + +#: networking.c:239 networking.c:640 +msgid "Address settings" +msgstr "" + +#: networking.c:240 networking.c:743 +msgid "DNS and Gateway settings" +msgstr "" + +#: networking.c:260 +msgid "When configuration is complete, a network restart will be required." +msgstr "" + +#: networking.c:267 +#, c-format +msgid "" +"Current config: %s\n" +"\n" +"%s" +msgstr "" + +#: networking.c:268 +msgid "Network configuration menu" +msgstr "" + +#: networking.c:269 networking.c:520 networking.c:642 +msgid "Done" +msgstr "" + +#: networking.c:300 +#, c-format +msgid "" +"Select the network configuration for %s. The following configuration types " +"list those interfaces which have ethernet attached. If you change this " +"setting, a network restart will be required, and you will have to " +"reconfigure the network driver assignments." +msgstr "" + +#: networking.c:307 +#, c-format +msgid "" +"Not enough netcards for your choice.\n" +"\n" +"Needed: %d - Available: %d\n" +msgstr "" + +#: networking.c:359 +msgid "" +"Configure network drivers, and which interface each card is assigned to. The current configuration is as follows:\n" +"\n" +msgstr "" + +#: networking.c:408 +msgid "Do you wish to change these settings?" +msgstr "" + +#: networking.c:447 +msgid "Restarting non-local network..." +msgstr "" + +#: networking.c:464 +msgid "" +"Please choose the interface you wish to change.\n" +"\n" +msgstr "" + +#: networking.c:519 +msgid "Assigned Cards" +msgstr "" + +#: networking.c:520 +msgid "Remove" +msgstr "" + +#: networking.c:556 networking.c:649 +#, c-format +msgid "" +"If you change this IP address, and you are logged in remotely, your " +"connection to the %s machine will be broken, and you will have to reconnect " +"on the new IP. This is a risky operation, and should only be attempted if " +"you have physical access to the machine, should something go wrong." +msgstr "" + +#: networking.c:641 +msgid "Select the interface you wish to reconfigure." +msgstr "" + +#: networking.c:729 +msgid "Default gateway:" +msgstr "" + +#: networking.c:744 +msgid "" +"Enter the DNS and gateway information. These settings are used only with " +"Static IP (and DHCP if DNS set) on the RED interface." +msgstr "" + +#: networking.c:773 +msgid "Default gateway" +msgstr "" + +#: networking.c:780 +msgid "Secondary DNS specified without a Primary DNS" +msgstr "" + +#: passwords.c:33 +msgid "" +"Enter the 'root' user password. Login as this user for commandline access." +msgstr "" + +#: passwords.c:38 passwords.c:61 +msgid "Setting password" +msgstr "" + +#: passwords.c:38 +msgid "Setting 'root' password...." +msgstr "" + +#: passwords.c:39 +msgid "Problem setting 'root' password." +msgstr "" + +#: passwords.c:53 +#, c-format +msgid "" +"Enter %s 'admin' user password. This is the user to use for logging into the" +" %s web administration pages." +msgstr "" + +#: passwords.c:60 +#, c-format +msgid "Setting %s 'admin' user password..." +msgstr "" + +#: passwords.c:62 +#, c-format +msgid "Problem setting %s 'admin' user password." +msgstr "" + +#: passwords.c:76 +msgid "Password:" +msgstr "" + +#: passwords.c:77 +msgid "Again:" +msgstr "" + +#: passwords.c:95 +msgid "Password cannot be blank." +msgstr "" + +#: passwords.c:102 +msgid "Passwords do not match." +msgstr "" + +#: passwords.c:109 +msgid "Password cannot contain spaces." +msgstr "" + +#: timezone.c:77 +msgid "Choose the timezone you are in from the list below." +msgstr "" diff --git a/src/setup/po/pl.po b/src/setup/po/pl.po index 607394a..ee6183f 100644 --- a/src/setup/po/pl.po +++ b/src/setup/po/pl.po @@ -3,13 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# btelega btelega@gmail.com, 2014 +# Przemysław Karpeta przemyslaw.karpeta@gmail.com, 2014 msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-08-21 15:12+0000\n" -"PO-Revision-Date: 2014-08-21 15:13+0000\n" -"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"PO-Revision-Date: 2014-11-03 15:36+0000\n" +"Last-Translator: Przemysław Karpeta przemyslaw.karpeta@gmail.com\n" "Language-Team: Polish (http://www.transifex.com/projects/p/ipfire/language/pl/)%5Cn" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,31 +21,31 @@ msgstr ""
#: dhcp.c:50 msgid "Start address:" -msgstr "" +msgstr "Adres początkowy:"
#: dhcp.c:51 msgid "End address:" -msgstr "" +msgstr "Adres końcowy:"
#: dhcp.c:52 networking.c:717 msgid "Primary DNS:" -msgstr "" +msgstr "Główny DNS:"
#: dhcp.c:53 networking.c:723 msgid "Secondary DNS:" -msgstr "" +msgstr "Pomocniczy DNS:"
#: dhcp.c:54 msgid "Default lease (mins):" -msgstr "" +msgstr "Domyślna dzierżawa (min.):"
#: dhcp.c:55 msgid "Max lease (mins):" -msgstr "" +msgstr "Maksymalna dzierżawa (min.):"
#: dhcp.c:56 msgid "Domain name suffix:" -msgstr "" +msgstr "Przyrostek domeny: "
#: dhcp.c:86 dhcp.c:93 dhcp.c:101 domainname.c:34 hostname.c:37 keymap.c:70 #: misc.c:40 misc.c:52 netstuff.c:377 netstuff.c:566 netstuff.c:704 @@ -51,19 +53,19 @@ msgstr "" #: networking.c:442 networking.c:552 networking.c:603 networking.c:610 #: networking.c:713 timezone.c:63 msgid "Unable to open settings file" -msgstr "" +msgstr "Nie można otworzyć pliku ustawień"
#: dhcp.c:111 msgid "DHCP server configuration" -msgstr "" +msgstr "Konfiguracja serwera DHCP "
#: dhcp.c:116 msgid "Configure the DHCP server by entering the settings information." -msgstr "" +msgstr "Skonfiguruj serwer DHCP wprowadzając właściwe ustawienia."
#: dhcp.c:125 msgid "Enabled" -msgstr "" +msgstr "Włączony"
#: dhcp.c:142 domainname.c:43 hostname.c:47 keymap.c:86 main.c:99 main.c:172 #: main.c:174 netstuff.c:157 netstuff.c:733 netstuff.c:756 networking.c:163 @@ -71,367 +73,367 @@ msgstr "" #: networking.c:642 networking.c:653 networking.c:746 passwords.c:89 #: timezone.c:78 msgid "OK" -msgstr "" +msgstr "OK"
#: dhcp.c:143 domainname.c:43 hostname.c:47 keymap.c:86 netstuff.c:158 #: netstuff.c:673 netstuff.c:733 netstuff.c:756 networking.c:305 #: networking.c:410 networking.c:560 networking.c:653 networking.c:746 #: passwords.c:89 timezone.c:78 msgid "Cancel" -msgstr "" +msgstr "Anuluj"
#: dhcp.c:156 msgid "" "The following fields are invalid:\n" "\n" -msgstr "" +msgstr "Następujące pola są nieprawidłowe:\n\n"
#: dhcp.c:159 msgid "Start address" -msgstr "" +msgstr "Adres początkowy"
#: dhcp.c:165 msgid "End address" -msgstr "" +msgstr "Adres końcowy"
#: dhcp.c:173 networking.c:755 msgid "Primary DNS" -msgstr "" +msgstr "Główny DNS"
#: dhcp.c:182 networking.c:764 msgid "Secondary DNS" -msgstr "" +msgstr "Pomocniczy DNS"
#: dhcp.c:189 msgid "Default lease time" -msgstr "" +msgstr "Domyślny okres dzierżawy"
#: dhcp.c:195 msgid "Max. lease time" -msgstr "" +msgstr "Maksymalny okres dzierżawy"
#: domainname.c:42 main.c:70 msgid "Domain name" -msgstr "" +msgstr "Nazwa Domeny"
#: domainname.c:42 msgid "Enter Domain name" -msgstr "" +msgstr "Wpisz nazwę Domeny"
#: domainname.c:48 msgid "Domain name cannot be empty." -msgstr "" +msgstr "Nazwa Domeny nie może być pusta"
#: domainname.c:50 msgid "Domain name cannot contain spaces." -msgstr "" +msgstr "Nazwa domeny nie może zawierać spacji."
#: domainname.c:53 msgid "Domain name may only contain letters, numbers, hyphens and periods." -msgstr "" +msgstr "Nazwa domeny może zawierać jedynie litery, cyfry, myślniki i kropki."
#: hostname.c:46 main.c:69 msgid "Hostname" -msgstr "" +msgstr "Nazwa hosta"
#: hostname.c:46 msgid "Enter the machine's hostname." -msgstr "" +msgstr "Wprowadź nazwę hosta."
#: hostname.c:53 msgid "Hostname cannot be empty." -msgstr "" +msgstr "Nazwa hosta nie może być pusta."
#: hostname.c:55 msgid "Hostname cannot contain spaces." -msgstr "" +msgstr "Nazwa hosta nie może zawierać spacji."
#: hostname.c:58 msgid "Hostname may only contain letters, numbers and hyphens." -msgstr "" +msgstr "Nazwa hosta może zawierać tylko litery, cyfry i myślniki."
#: keymap.c:84 main.c:67 msgid "Keyboard mapping" -msgstr "" +msgstr "Mapowanie klawiatury"
#: keymap.c:85 msgid "Choose the type of keyboard you are using from the list below." -msgstr "" +msgstr "Wybierz używany przez siebie typ klawiatury z poniższej listy."
#: main.c:68 timezone.c:77 msgid "Timezone" -msgstr "" +msgstr "Strefa czasowa"
#: main.c:71 networking.c:110 networking.c:115 networking.c:447 msgid "Networking" -msgstr "" +msgstr "Sieć"
#: main.c:72 misc.c:147 msgid "ISDN" -msgstr "" +msgstr "ISDN"
#: main.c:73 msgid "'root' password" -msgstr "" +msgstr "Hasło użytkownika 'root'"
#: main.c:74 msgid "'admin' password" -msgstr "" +msgstr "Hasło użytkownika 'admin'"
#: main.c:90 msgid " <Tab>/<Alt-Tab> between elements | <Space> selects" -msgstr "" +msgstr " <Tab>/<Alt-Tab> przełącza między elementami | <Space> wybiera"
#: main.c:97 msgid "Section menu" -msgstr "" +msgstr "Menu sekcji"
#: main.c:98 msgid "Select the item you wish to configure." -msgstr "" +msgstr "Wybierz element który chcesz skonfigurować."
#: main.c:99 msgid "Quit" -msgstr "" +msgstr "Wyjście"
#: main.c:172 msgid "Setup is complete." -msgstr "" +msgstr "Instalacja zakończona"
#: main.c:174 netstuff.c:733 networking.c:560 networking.c:653 msgid "Warning" -msgstr "" +msgstr "Ostrzeżenie"
#: main.c:175 msgid "" "Initial setup was not entirely complete. You must ensure that Setup is " "properly finished by running setup again at the shell." -msgstr "" +msgstr "Wstępna konfiguracjia nie została ukończona. Musisz upewnić się, że konfiguracja jest ukończona poprzez ponowne uruchomienie polecenia 'setup' w powłoce."
#: misc.c:62 #, c-format msgid "Unable to write %s/main/hostname.conf" -msgstr "" +msgstr "Nie można zapisać %s/main/hostname.conf"
#: misc.c:71 msgid "Unable to open main hosts file." -msgstr "" +msgstr "Nie można otworzyc głównego pliku hosts."
#: misc.c:76 msgid "Unable to write /etc/hosts." -msgstr "" +msgstr "Nie można zapisać /etc/hosts"
#: misc.c:117 msgid "Unable to write /etc/hosts.deny." -msgstr "" +msgstr "Nie można zapisać /etc/hosts.deny"
#: misc.c:125 msgid "Unable to write /etc/hosts.allow." -msgstr "" +msgstr "Nie można zapisać /etc/hosts.allow"
#: misc.c:136 msgid "Unable to set hostname." -msgstr "" +msgstr "Ustawienie nazwy hosta niemożliwe."
#: misc.c:147 msgid "Scanning and configuring ISDN devices." -msgstr "" +msgstr "Wykrywanie i konfiguracja urządzeń ISDN."
#: misc.c:148 msgid "Unable to scan for ISDN devices." -msgstr "" +msgstr "Wykrywanie urządzeń ISDN jest niemożliwe."
#: netstuff.c:86 #, c-format msgid "Interface - %s" -msgstr "" +msgstr "Interfejs - %s"
#: netstuff.c:91 #, c-format msgid "Enter the IP address information for the %s interface." -msgstr "" +msgstr "Wprowadź ustawienia adresu IP dla interfejsu %s."
#: netstuff.c:103 msgid "Static" -msgstr "" +msgstr "Statyczny"
#: netstuff.c:104 msgid "DHCP" -msgstr "" +msgstr "DHCP"
#: netstuff.c:105 msgid "PPP DIALUP (PPPoE, modem, ATM ...)" -msgstr "" +msgstr "PPP DIALUP (PPPoE, modem, ATM ...)"
#: netstuff.c:113 msgid "DHCP Hostname:" -msgstr "" +msgstr "Nazwa hosta DHCP:"
#: netstuff.c:115 msgid "Force DHCP MTU:" -msgstr "" +msgstr "Wymuś DHCP MTU:"
#: netstuff.c:134 msgid "IP address:" -msgstr "" +msgstr "IP address:"
#: netstuff.c:146 msgid "Network mask:" -msgstr "" +msgstr "Maska podsieci:"
#: netstuff.c:173 networking.c:749 msgid "The following fields are invalid:" -msgstr "" +msgstr "Następujące pola są nieprawidłowe:"
#: netstuff.c:183 msgid "IP address" -msgstr "" +msgstr "IP address"
#: netstuff.c:189 msgid "Network mask" -msgstr "" +msgstr "Maska podsieci"
#: netstuff.c:198 msgid "DHCP hostname" -msgstr "" +msgstr "Nazwa hosta DHCP"
#: netstuff.c:396 netstuff.c:709 msgid "Unset" -msgstr "" +msgstr "Wyłącz"
#: netstuff.c:669 #, c-format msgid "Please choose a networkcard for the following interface - %s." -msgstr "" +msgstr "Proszę wybrać kartę sieciową dla następującego interfejsu - %s"
#: netstuff.c:672 msgid "Extended Network Menu" -msgstr "" +msgstr "Rozszerzone Menu Sieci"
#: netstuff.c:673 networking.c:520 msgid "Select" -msgstr "" +msgstr "Wybierz"
#: netstuff.c:673 msgid "Identify" -msgstr "" +msgstr "Zidentyfikuj"
#: netstuff.c:678 msgid "Device Identification" -msgstr "" +msgstr "Identyfikacja urządzenia"
#: netstuff.c:678 msgid "The lights on the selected port should flash now for 10 seconds..." -msgstr "" +msgstr "Kontrolki na wybranym porcie powinny migotać przez następne 10 sekund..."
#: netstuff.c:679 msgid "Identification is not supported by this interface." -msgstr "" +msgstr "Ten interfejs nie wspiera identyfikacji."
#: netstuff.c:691 msgid "There are no unassigned interfaces on your system." -msgstr "" +msgstr "Nie ma już nieprzydzielonych interfejsów w systemie."
#: netstuff.c:732 #, c-format msgid "Do you really want to remove the assigned %s interface?" -msgstr "" +msgstr "Na pewno chcesz usunąć przydzielony interfejs %s ?"
#: netstuff.c:755 msgid "Select network driver" -msgstr "" +msgstr "Wybierz sterownik karty sieciowej"
#: netstuff.c:755 msgid "Set additional module parameters" -msgstr "" +msgstr "Ustaw dodatkowe parametry modułu"
#: netstuff.c:762 msgid "Loading module..." -msgstr "" +msgstr "Wczytywanie modułu..."
#: netstuff.c:777 msgid "Unable to load driver module." -msgstr "" +msgstr "Nie da się wczytać modułu."
#: netstuff.c:780 msgid "Module name cannot be blank." -msgstr "" +msgstr "Nazwa modułu nie może być pusta."
#: networking.c:110 msgid "Stopping network..." -msgstr "" +msgstr "Zatrzymywanie sieci..."
#: networking.c:115 msgid "Restarting network..." -msgstr "" +msgstr "Ponowne uruchamianie sieci..."
#: networking.c:146 msgid "No GREEN interface assigned." -msgstr "" +msgstr "Interfejs GREEN nie został przypisany."
#: networking.c:152 msgid "Missing an IP address on GREEN." -msgstr "" +msgstr "Brak adresu IP na GREEN."
#: networking.c:163 msgid "Error" -msgstr "" +msgstr "Błąd"
#: networking.c:163 msgid "Ignore" -msgstr "" +msgstr "Ignoruj"
#: networking.c:164 msgid "No RED interface assigned." -msgstr "" +msgstr "Interfejs RED nie został przypisany."
#: networking.c:173 msgid "Missing an IP address on RED." -msgstr "" +msgstr "Brak adresu IP na RED."
#: networking.c:183 msgid "No ORANGE interface assigned." -msgstr "" +msgstr "Interfejs ORANGE nie został przypisany."
#: networking.c:189 msgid "Missing an IP address on ORANGE." -msgstr "" +msgstr "Brak adresu IP na ORANGE."
#: networking.c:199 msgid "No BLUE interface assigned." -msgstr "" +msgstr "Interfejs BLUE nie został przypisany."
#: networking.c:205 msgid "Missing an IP address on BLUE." -msgstr "" +msgstr "Brak adresu IP na BLUE."
#: networking.c:217 msgid "Misssing DNS." -msgstr "" +msgstr "Brakuje DNS."
#: networking.c:224 msgid "Missing Default Gateway." -msgstr "" +msgstr "Brakuje Bramy Domyślnej."
#: networking.c:237 networking.c:304 msgid "Network configuration type" -msgstr "" +msgstr "Rodzaj konfiguracji sieci"
#: networking.c:238 networking.c:409 msgid "Drivers and card assignments" -msgstr "" +msgstr "Przydziały sterowników i kart"
#: networking.c:239 networking.c:640 msgid "Address settings" -msgstr "" +msgstr "Ustawienia adresu"
#: networking.c:240 networking.c:743 msgid "DNS and Gateway settings" -msgstr "" +msgstr "Ustawienia DNS i Bramy"
#: networking.c:260 msgid "When configuration is complete, a network restart will be required." -msgstr "" +msgstr "Po ukończeniu konfiguracji wymagane będzie ponowne uruchomienie sieci."
#: networking.c:267 #, c-format @@ -439,15 +441,15 @@ msgid "" "Current config: %s\n" "\n" "%s" -msgstr "" +msgstr "Obecna konfiguracja: %s\n\n%s"
#: networking.c:268 msgid "Network configuration menu" -msgstr "" +msgstr "Menu konfiguracji sieci"
#: networking.c:269 networking.c:520 networking.c:642 msgid "Done" -msgstr "" +msgstr "Zrobione"
#: networking.c:300 #, c-format @@ -456,7 +458,7 @@ msgid "" "list those interfaces which have ethernet attached. If you change this " "setting, a network restart will be required, and you will have to " "reconfigure the network driver assignments." -msgstr "" +msgstr "Wybierz konfigurację sieci dla %s. Poniższe typy konfiguracji wyświetlają interfejsy z przyłączonym ethernetem. Jeśli zmienisz te ustawienia, wymagany będzie restart sieci, i trzeba będzie zrekonfigurować przydziały sterowników kart sieciowych. "
#: networking.c:307 #, c-format @@ -464,35 +466,35 @@ msgid "" "Not enough netcards for your choice.\n" "\n" "Needed: %d - Available: %d\n" -msgstr "" +msgstr "Niewystarczająca liczba kart sieciowych.\n\nPotrzebne: %d - Dostępne: %d\n"
#: networking.c:359 msgid "" "Configure network drivers, and which interface each card is assigned to. The current configuration is as follows:\n" "\n" -msgstr "" +msgstr "Skonfiguruj sterowniki kart sieciowych, i przydziel karty do odpowiednich interfejsów. Obecna konfiguracja wygląda tak:\n\n"
#: networking.c:408 msgid "Do you wish to change these settings?" -msgstr "" +msgstr "Czy chcesz zmienić te ustawienia ?"
#: networking.c:447 msgid "Restarting non-local network..." -msgstr "" +msgstr "Ponowne uruchamianie sieci innych, niż lokalna..."
#: networking.c:464 msgid "" "Please choose the interface you wish to change.\n" "\n" -msgstr "" +msgstr "Wybierz interfejs, który chcesz zmienić.\n\n"
#: networking.c:519 msgid "Assigned Cards" -msgstr "" +msgstr "Przypisane Karty"
#: networking.c:520 msgid "Remove" -msgstr "" +msgstr "Usuń"
#: networking.c:556 networking.c:649 #, c-format @@ -501,84 +503,84 @@ msgid "" "connection to the %s machine will be broken, and you will have to reconnect " "on the new IP. This is a risky operation, and should only be attempted if " "you have physical access to the machine, should something go wrong." -msgstr "" +msgstr "Jeśli zmienisz ten adres IP, a jesteś zalogowany zdalnie, Twoje połączenie do maszyny %s zostanie zerwane, i trzeba będzie połączyć się ponownie na nowy adres IP. To ryzykowna operacja, która powinna byc podejmowana tylko w przypadku posiadania bezpośredniego, fizycznego dostępu do maszyny na wypadek, gdyby coś poszło źle."
#: networking.c:641 msgid "Select the interface you wish to reconfigure." -msgstr "" +msgstr "Zaznacz interfejs, który chcesz zrekonfigurować."
#: networking.c:729 msgid "Default gateway:" -msgstr "" +msgstr "Brama domyślna:"
#: networking.c:744 msgid "" "Enter the DNS and gateway information. These settings are used only with " "Static IP (and DHCP if DNS set) on the RED interface." -msgstr "" +msgstr "Wprowadź informacje o serwerze DNS i bramie. Te ustawienia stosuje się tylko do statycznego IP (i DHCP, gdzie DNS ustawia się ręcznie) na interfejsie RED."
#: networking.c:773 msgid "Default gateway" -msgstr "" +msgstr "Brama domyślna"
#: networking.c:780 msgid "Secondary DNS specified without a Primary DNS" -msgstr "" +msgstr "Podano adres Zapasowego DNS bez podania adresu Podstawowego DNS."
#: passwords.c:33 msgid "" "Enter the 'root' user password. Login as this user for commandline access." -msgstr "" +msgstr "Wprowadź hasło użytkownika 'root'. Zaloguj się jako ten użytkownik, aby uzyskać dostęp do linii poleceń."
#: passwords.c:38 passwords.c:61 msgid "Setting password" -msgstr "" +msgstr "Ustawienie hasła"
#: passwords.c:38 msgid "Setting 'root' password...." -msgstr "" +msgstr "Ustawianie hasła użytkownika 'root'...."
#: passwords.c:39 msgid "Problem setting 'root' password." -msgstr "" +msgstr "Problem z ustawieniem hasła użytkownika 'root'."
#: passwords.c:53 #, c-format msgid "" "Enter %s 'admin' user password. This is the user to use for logging into the" " %s web administration pages." -msgstr "" +msgstr "Wprowadź haslo użytkownika 'admin' systemu %s. Zalogowanie się na tego użytkownika umożliwi dostęp do administracyjnej strony WWW %s."
#: passwords.c:60 #, c-format msgid "Setting %s 'admin' user password..." -msgstr "" +msgstr "Ustawianie hasła użytkownika 'admin' systemu %s..."
#: passwords.c:62 #, c-format msgid "Problem setting %s 'admin' user password." -msgstr "" +msgstr "Problem z ustawieniem hasła użytkownika 'admin' systemu %s."
#: passwords.c:76 msgid "Password:" -msgstr "" +msgstr "Hasło:"
#: passwords.c:77 msgid "Again:" -msgstr "" +msgstr "Ponownie:"
#: passwords.c:95 msgid "Password cannot be blank." -msgstr "" +msgstr "Hasło nie może być puste."
#: passwords.c:102 msgid "Passwords do not match." -msgstr "" +msgstr "Hasła nie są zgodne."
#: passwords.c:109 msgid "Password cannot contain spaces." -msgstr "" +msgstr "Hasło nie może zawierać spacji."
#: timezone.c:77 msgid "Choose the timezone you are in from the list below." -msgstr "" +msgstr "Wybierz strefę czasową w której się znajdujesz z listy poniżej." diff --git a/src/setup/po/ru.po b/src/setup/po/ru.po index 34b1ac4..1a03f0b 100644 --- a/src/setup/po/ru.po +++ b/src/setup/po/ru.po @@ -3,14 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Andrei Skipin skian2007@yandex.ru, 2014 # bubnov_pi ipfire@bubnov.su, 2014 msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-08-21 15:12+0000\n" -"PO-Revision-Date: 2014-08-21 15:13+0000\n" -"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"PO-Revision-Date: 2014-12-10 10:22+0000\n" +"Last-Translator: Andrei Skipin skian2007@yandex.ru\n" "Language-Team: Russian (http://www.transifex.com/projects/p/ipfire/language/ru/)%5Cn" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -189,19 +190,19 @@ msgstr ""
#: main.c:98 msgid "Select the item you wish to configure." -msgstr "" +msgstr "Выберите пункт меню для настройки"
#: main.c:99 msgid "Quit" -msgstr "" +msgstr "Выход"
#: main.c:172 msgid "Setup is complete." -msgstr "" +msgstr "Установка завершена"
#: main.c:174 netstuff.c:733 networking.c:560 networking.c:653 msgid "Warning" -msgstr "" +msgstr "Предупреждение"
#: main.c:175 msgid "" @@ -220,15 +221,15 @@ msgstr ""
#: misc.c:76 msgid "Unable to write /etc/hosts." -msgstr "" +msgstr "Недоступна запись в /etc/hosts."
#: misc.c:117 msgid "Unable to write /etc/hosts.deny." -msgstr "" +msgstr "Недоступна запись в /etc/hosts.deny."
#: misc.c:125 msgid "Unable to write /etc/hosts.allow." -msgstr "" +msgstr "Недоступна запись в /etc/hosts.allow."
#: misc.c:136 msgid "Unable to set hostname." @@ -236,7 +237,7 @@ msgstr ""
#: misc.c:147 msgid "Scanning and configuring ISDN devices." -msgstr "" +msgstr "Сканирование и конфигурирование ISDN устройств."
#: misc.c:148 msgid "Unable to scan for ISDN devices." @@ -245,7 +246,7 @@ msgstr "" #: netstuff.c:86 #, c-format msgid "Interface - %s" -msgstr "" +msgstr "Интерфейс - %s"
#: netstuff.c:91 #, c-format @@ -254,7 +255,7 @@ msgstr ""
#: netstuff.c:103 msgid "Static" -msgstr "" +msgstr "Статический"
#: netstuff.c:104 msgid "DHCP" @@ -266,7 +267,7 @@ msgstr ""
#: netstuff.c:113 msgid "DHCP Hostname:" -msgstr "" +msgstr "Имя хоста DHCP:"
#: netstuff.c:115 msgid "Force DHCP MTU:" @@ -274,11 +275,11 @@ msgstr ""
#: netstuff.c:134 msgid "IP address:" -msgstr "" +msgstr "IP-адрес:"
#: netstuff.c:146 msgid "Network mask:" -msgstr "" +msgstr "Сетевая маска:"
#: netstuff.c:173 networking.c:749 msgid "The following fields are invalid:" @@ -286,15 +287,15 @@ msgstr ""
#: netstuff.c:183 msgid "IP address" -msgstr "" +msgstr "IP-адрес"
#: netstuff.c:189 msgid "Network mask" -msgstr "" +msgstr "Сетевая маска"
#: netstuff.c:198 msgid "DHCP hostname" -msgstr "" +msgstr "Имя хоста DHCP"
#: netstuff.c:396 netstuff.c:709 msgid "Unset" @@ -307,11 +308,11 @@ msgstr ""
#: netstuff.c:672 msgid "Extended Network Menu" -msgstr "" +msgstr "Расширенное сетевое меню"
#: netstuff.c:673 networking.c:520 msgid "Select" -msgstr "" +msgstr "Выберите"
#: netstuff.c:673 msgid "Identify" @@ -340,7 +341,7 @@ msgstr ""
#: netstuff.c:755 msgid "Select network driver" -msgstr "" +msgstr "Выберите сетевой драйвер"
#: netstuff.c:755 msgid "Set additional module parameters" @@ -348,11 +349,11 @@ msgstr ""
#: netstuff.c:762 msgid "Loading module..." -msgstr "" +msgstr "Модуль загружается..."
#: netstuff.c:777 msgid "Unable to load driver module." -msgstr "" +msgstr "Невозможно загрузить драйвер модуля."
#: netstuff.c:780 msgid "Module name cannot be blank." @@ -360,11 +361,11 @@ msgstr ""
#: networking.c:110 msgid "Stopping network..." -msgstr "" +msgstr "Остановка сети.."
#: networking.c:115 msgid "Restarting network..." -msgstr "" +msgstr "Перезапуск сети..."
#: networking.c:146 msgid "No GREEN interface assigned." @@ -408,11 +409,11 @@ msgstr ""
#: networking.c:217 msgid "Misssing DNS." -msgstr "" +msgstr "Отсутствует DNS."
#: networking.c:224 msgid "Missing Default Gateway." -msgstr "" +msgstr "Отсутствует шлюз по умолчанию."
#: networking.c:237 networking.c:304 msgid "Network configuration type" @@ -444,11 +445,11 @@ msgstr ""
#: networking.c:268 msgid "Network configuration menu" -msgstr "" +msgstr "Меню настройки сети"
#: networking.c:269 networking.c:520 networking.c:642 msgid "Done" -msgstr "" +msgstr "Успешно завершено."
#: networking.c:300 #, c-format @@ -493,7 +494,7 @@ msgstr ""
#: networking.c:520 msgid "Remove" -msgstr "" +msgstr "Удалить"
#: networking.c:556 networking.c:649 #, c-format @@ -510,7 +511,7 @@ msgstr ""
#: networking.c:729 msgid "Default gateway:" -msgstr "" +msgstr "Шлюз по умолчанию:"
#: networking.c:744 msgid "" @@ -520,7 +521,7 @@ msgstr ""
#: networking.c:773 msgid "Default gateway" -msgstr "" +msgstr "Шлюз по умолчанию"
#: networking.c:780 msgid "Secondary DNS specified without a Primary DNS" @@ -533,11 +534,11 @@ msgstr ""
#: passwords.c:38 passwords.c:61 msgid "Setting password" -msgstr "" +msgstr "Установка пароля"
#: passwords.c:38 msgid "Setting 'root' password...." -msgstr "" +msgstr "Установка 'root' пароля..."
#: passwords.c:39 msgid "Problem setting 'root' password." @@ -562,23 +563,23 @@ msgstr ""
#: passwords.c:76 msgid "Password:" -msgstr "" +msgstr "Пароль:"
#: passwords.c:77 msgid "Again:" -msgstr "" +msgstr "Повторите пароль:"
#: passwords.c:95 msgid "Password cannot be blank." -msgstr "" +msgstr "Пароль не может быть пустым."
#: passwords.c:102 msgid "Passwords do not match." -msgstr "" +msgstr "Пароли не совпадают"
#: passwords.c:109 msgid "Password cannot contain spaces." -msgstr "" +msgstr "Пароль не может содержать пробелы"
#: timezone.c:77 msgid "Choose the timezone you are in from the list below." diff --git a/src/setup/po/rw.po b/src/setup/po/rw.po new file mode 100644 index 0000000..0bd98ee --- /dev/null +++ b/src/setup/po/rw.po @@ -0,0 +1,584 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR The IPFire Project (www.ipfire.org) +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: IPFire Project\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-08-21 15:12+0000\n" +"PO-Revision-Date: 2014-08-12 10:08+0000\n" +"Last-Translator: FULL NAME EMAIL@ADDRESS\n" +"Language-Team: Kinyarwanda (http://www.transifex.com/projects/p/ipfire/language/rw/)%5Cn" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: rw\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: dhcp.c:50 +msgid "Start address:" +msgstr "" + +#: dhcp.c:51 +msgid "End address:" +msgstr "" + +#: dhcp.c:52 networking.c:717 +msgid "Primary DNS:" +msgstr "" + +#: dhcp.c:53 networking.c:723 +msgid "Secondary DNS:" +msgstr "" + +#: dhcp.c:54 +msgid "Default lease (mins):" +msgstr "" + +#: dhcp.c:55 +msgid "Max lease (mins):" +msgstr "" + +#: dhcp.c:56 +msgid "Domain name suffix:" +msgstr "" + +#: dhcp.c:86 dhcp.c:93 dhcp.c:101 domainname.c:34 hostname.c:37 keymap.c:70 +#: misc.c:40 misc.c:52 netstuff.c:377 netstuff.c:566 netstuff.c:704 +#: networking.c:134 networking.c:255 networking.c:291 networking.c:346 +#: networking.c:442 networking.c:552 networking.c:603 networking.c:610 +#: networking.c:713 timezone.c:63 +msgid "Unable to open settings file" +msgstr "" + +#: dhcp.c:111 +msgid "DHCP server configuration" +msgstr "" + +#: dhcp.c:116 +msgid "Configure the DHCP server by entering the settings information." +msgstr "" + +#: dhcp.c:125 +msgid "Enabled" +msgstr "" + +#: dhcp.c:142 domainname.c:43 hostname.c:47 keymap.c:86 main.c:99 main.c:172 +#: main.c:174 netstuff.c:157 netstuff.c:733 netstuff.c:756 networking.c:163 +#: networking.c:269 networking.c:305 networking.c:409 networking.c:560 +#: networking.c:642 networking.c:653 networking.c:746 passwords.c:89 +#: timezone.c:78 +msgid "OK" +msgstr "" + +#: dhcp.c:143 domainname.c:43 hostname.c:47 keymap.c:86 netstuff.c:158 +#: netstuff.c:673 netstuff.c:733 netstuff.c:756 networking.c:305 +#: networking.c:410 networking.c:560 networking.c:653 networking.c:746 +#: passwords.c:89 timezone.c:78 +msgid "Cancel" +msgstr "" + +#: dhcp.c:156 +msgid "" +"The following fields are invalid:\n" +"\n" +msgstr "" + +#: dhcp.c:159 +msgid "Start address" +msgstr "" + +#: dhcp.c:165 +msgid "End address" +msgstr "" + +#: dhcp.c:173 networking.c:755 +msgid "Primary DNS" +msgstr "" + +#: dhcp.c:182 networking.c:764 +msgid "Secondary DNS" +msgstr "" + +#: dhcp.c:189 +msgid "Default lease time" +msgstr "" + +#: dhcp.c:195 +msgid "Max. lease time" +msgstr "" + +#: domainname.c:42 main.c:70 +msgid "Domain name" +msgstr "" + +#: domainname.c:42 +msgid "Enter Domain name" +msgstr "" + +#: domainname.c:48 +msgid "Domain name cannot be empty." +msgstr "" + +#: domainname.c:50 +msgid "Domain name cannot contain spaces." +msgstr "" + +#: domainname.c:53 +msgid "Domain name may only contain letters, numbers, hyphens and periods." +msgstr "" + +#: hostname.c:46 main.c:69 +msgid "Hostname" +msgstr "" + +#: hostname.c:46 +msgid "Enter the machine's hostname." +msgstr "" + +#: hostname.c:53 +msgid "Hostname cannot be empty." +msgstr "" + +#: hostname.c:55 +msgid "Hostname cannot contain spaces." +msgstr "" + +#: hostname.c:58 +msgid "Hostname may only contain letters, numbers and hyphens." +msgstr "" + +#: keymap.c:84 main.c:67 +msgid "Keyboard mapping" +msgstr "" + +#: keymap.c:85 +msgid "Choose the type of keyboard you are using from the list below." +msgstr "" + +#: main.c:68 timezone.c:77 +msgid "Timezone" +msgstr "" + +#: main.c:71 networking.c:110 networking.c:115 networking.c:447 +msgid "Networking" +msgstr "" + +#: main.c:72 misc.c:147 +msgid "ISDN" +msgstr "" + +#: main.c:73 +msgid "'root' password" +msgstr "" + +#: main.c:74 +msgid "'admin' password" +msgstr "" + +#: main.c:90 +msgid " <Tab>/<Alt-Tab> between elements | <Space> selects" +msgstr "" + +#: main.c:97 +msgid "Section menu" +msgstr "" + +#: main.c:98 +msgid "Select the item you wish to configure." +msgstr "" + +#: main.c:99 +msgid "Quit" +msgstr "" + +#: main.c:172 +msgid "Setup is complete." +msgstr "" + +#: main.c:174 netstuff.c:733 networking.c:560 networking.c:653 +msgid "Warning" +msgstr "" + +#: main.c:175 +msgid "" +"Initial setup was not entirely complete. You must ensure that Setup is " +"properly finished by running setup again at the shell." +msgstr "" + +#: misc.c:62 +#, c-format +msgid "Unable to write %s/main/hostname.conf" +msgstr "" + +#: misc.c:71 +msgid "Unable to open main hosts file." +msgstr "" + +#: misc.c:76 +msgid "Unable to write /etc/hosts." +msgstr "" + +#: misc.c:117 +msgid "Unable to write /etc/hosts.deny." +msgstr "" + +#: misc.c:125 +msgid "Unable to write /etc/hosts.allow." +msgstr "" + +#: misc.c:136 +msgid "Unable to set hostname." +msgstr "" + +#: misc.c:147 +msgid "Scanning and configuring ISDN devices." +msgstr "" + +#: misc.c:148 +msgid "Unable to scan for ISDN devices." +msgstr "" + +#: netstuff.c:86 +#, c-format +msgid "Interface - %s" +msgstr "" + +#: netstuff.c:91 +#, c-format +msgid "Enter the IP address information for the %s interface." +msgstr "" + +#: netstuff.c:103 +msgid "Static" +msgstr "" + +#: netstuff.c:104 +msgid "DHCP" +msgstr "" + +#: netstuff.c:105 +msgid "PPP DIALUP (PPPoE, modem, ATM ...)" +msgstr "" + +#: netstuff.c:113 +msgid "DHCP Hostname:" +msgstr "" + +#: netstuff.c:115 +msgid "Force DHCP MTU:" +msgstr "" + +#: netstuff.c:134 +msgid "IP address:" +msgstr "" + +#: netstuff.c:146 +msgid "Network mask:" +msgstr "" + +#: netstuff.c:173 networking.c:749 +msgid "The following fields are invalid:" +msgstr "" + +#: netstuff.c:183 +msgid "IP address" +msgstr "" + +#: netstuff.c:189 +msgid "Network mask" +msgstr "" + +#: netstuff.c:198 +msgid "DHCP hostname" +msgstr "" + +#: netstuff.c:396 netstuff.c:709 +msgid "Unset" +msgstr "" + +#: netstuff.c:669 +#, c-format +msgid "Please choose a networkcard for the following interface - %s." +msgstr "" + +#: netstuff.c:672 +msgid "Extended Network Menu" +msgstr "" + +#: netstuff.c:673 networking.c:520 +msgid "Select" +msgstr "" + +#: netstuff.c:673 +msgid "Identify" +msgstr "" + +#: netstuff.c:678 +msgid "Device Identification" +msgstr "" + +#: netstuff.c:678 +msgid "The lights on the selected port should flash now for 10 seconds..." +msgstr "" + +#: netstuff.c:679 +msgid "Identification is not supported by this interface." +msgstr "" + +#: netstuff.c:691 +msgid "There are no unassigned interfaces on your system." +msgstr "" + +#: netstuff.c:732 +#, c-format +msgid "Do you really want to remove the assigned %s interface?" +msgstr "" + +#: netstuff.c:755 +msgid "Select network driver" +msgstr "" + +#: netstuff.c:755 +msgid "Set additional module parameters" +msgstr "" + +#: netstuff.c:762 +msgid "Loading module..." +msgstr "" + +#: netstuff.c:777 +msgid "Unable to load driver module." +msgstr "" + +#: netstuff.c:780 +msgid "Module name cannot be blank." +msgstr "" + +#: networking.c:110 +msgid "Stopping network..." +msgstr "" + +#: networking.c:115 +msgid "Restarting network..." +msgstr "" + +#: networking.c:146 +msgid "No GREEN interface assigned." +msgstr "" + +#: networking.c:152 +msgid "Missing an IP address on GREEN." +msgstr "" + +#: networking.c:163 +msgid "Error" +msgstr "" + +#: networking.c:163 +msgid "Ignore" +msgstr "" + +#: networking.c:164 +msgid "No RED interface assigned." +msgstr "" + +#: networking.c:173 +msgid "Missing an IP address on RED." +msgstr "" + +#: networking.c:183 +msgid "No ORANGE interface assigned." +msgstr "" + +#: networking.c:189 +msgid "Missing an IP address on ORANGE." +msgstr "" + +#: networking.c:199 +msgid "No BLUE interface assigned." +msgstr "" + +#: networking.c:205 +msgid "Missing an IP address on BLUE." +msgstr "" + +#: networking.c:217 +msgid "Misssing DNS." +msgstr "" + +#: networking.c:224 +msgid "Missing Default Gateway." +msgstr "" + +#: networking.c:237 networking.c:304 +msgid "Network configuration type" +msgstr "" + +#: networking.c:238 networking.c:409 +msgid "Drivers and card assignments" +msgstr "" + +#: networking.c:239 networking.c:640 +msgid "Address settings" +msgstr "" + +#: networking.c:240 networking.c:743 +msgid "DNS and Gateway settings" +msgstr "" + +#: networking.c:260 +msgid "When configuration is complete, a network restart will be required." +msgstr "" + +#: networking.c:267 +#, c-format +msgid "" +"Current config: %s\n" +"\n" +"%s" +msgstr "" + +#: networking.c:268 +msgid "Network configuration menu" +msgstr "" + +#: networking.c:269 networking.c:520 networking.c:642 +msgid "Done" +msgstr "" + +#: networking.c:300 +#, c-format +msgid "" +"Select the network configuration for %s. The following configuration types " +"list those interfaces which have ethernet attached. If you change this " +"setting, a network restart will be required, and you will have to " +"reconfigure the network driver assignments." +msgstr "" + +#: networking.c:307 +#, c-format +msgid "" +"Not enough netcards for your choice.\n" +"\n" +"Needed: %d - Available: %d\n" +msgstr "" + +#: networking.c:359 +msgid "" +"Configure network drivers, and which interface each card is assigned to. The current configuration is as follows:\n" +"\n" +msgstr "" + +#: networking.c:408 +msgid "Do you wish to change these settings?" +msgstr "" + +#: networking.c:447 +msgid "Restarting non-local network..." +msgstr "" + +#: networking.c:464 +msgid "" +"Please choose the interface you wish to change.\n" +"\n" +msgstr "" + +#: networking.c:519 +msgid "Assigned Cards" +msgstr "" + +#: networking.c:520 +msgid "Remove" +msgstr "" + +#: networking.c:556 networking.c:649 +#, c-format +msgid "" +"If you change this IP address, and you are logged in remotely, your " +"connection to the %s machine will be broken, and you will have to reconnect " +"on the new IP. This is a risky operation, and should only be attempted if " +"you have physical access to the machine, should something go wrong." +msgstr "" + +#: networking.c:641 +msgid "Select the interface you wish to reconfigure." +msgstr "" + +#: networking.c:729 +msgid "Default gateway:" +msgstr "" + +#: networking.c:744 +msgid "" +"Enter the DNS and gateway information. These settings are used only with " +"Static IP (and DHCP if DNS set) on the RED interface." +msgstr "" + +#: networking.c:773 +msgid "Default gateway" +msgstr "" + +#: networking.c:780 +msgid "Secondary DNS specified without a Primary DNS" +msgstr "" + +#: passwords.c:33 +msgid "" +"Enter the 'root' user password. Login as this user for commandline access." +msgstr "" + +#: passwords.c:38 passwords.c:61 +msgid "Setting password" +msgstr "" + +#: passwords.c:38 +msgid "Setting 'root' password...." +msgstr "" + +#: passwords.c:39 +msgid "Problem setting 'root' password." +msgstr "" + +#: passwords.c:53 +#, c-format +msgid "" +"Enter %s 'admin' user password. This is the user to use for logging into the" +" %s web administration pages." +msgstr "" + +#: passwords.c:60 +#, c-format +msgid "Setting %s 'admin' user password..." +msgstr "" + +#: passwords.c:62 +#, c-format +msgid "Problem setting %s 'admin' user password." +msgstr "" + +#: passwords.c:76 +msgid "Password:" +msgstr "" + +#: passwords.c:77 +msgid "Again:" +msgstr "" + +#: passwords.c:95 +msgid "Password cannot be blank." +msgstr "" + +#: passwords.c:102 +msgid "Passwords do not match." +msgstr "" + +#: passwords.c:109 +msgid "Password cannot contain spaces." +msgstr "" + +#: timezone.c:77 +msgid "Choose the timezone you are in from the list below." +msgstr "" diff --git a/src/setup/po/sr.po b/src/setup/po/sr.po new file mode 100644 index 0000000..7c71314 --- /dev/null +++ b/src/setup/po/sr.po @@ -0,0 +1,584 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR The IPFire Project (www.ipfire.org) +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: IPFire Project\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-08-21 15:12+0000\n" +"PO-Revision-Date: 2014-08-12 10:08+0000\n" +"Last-Translator: FULL NAME EMAIL@ADDRESS\n" +"Language-Team: Serbian (http://www.transifex.com/projects/p/ipfire/language/sr/)%5Cn" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sr\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: dhcp.c:50 +msgid "Start address:" +msgstr "" + +#: dhcp.c:51 +msgid "End address:" +msgstr "" + +#: dhcp.c:52 networking.c:717 +msgid "Primary DNS:" +msgstr "" + +#: dhcp.c:53 networking.c:723 +msgid "Secondary DNS:" +msgstr "" + +#: dhcp.c:54 +msgid "Default lease (mins):" +msgstr "" + +#: dhcp.c:55 +msgid "Max lease (mins):" +msgstr "" + +#: dhcp.c:56 +msgid "Domain name suffix:" +msgstr "" + +#: dhcp.c:86 dhcp.c:93 dhcp.c:101 domainname.c:34 hostname.c:37 keymap.c:70 +#: misc.c:40 misc.c:52 netstuff.c:377 netstuff.c:566 netstuff.c:704 +#: networking.c:134 networking.c:255 networking.c:291 networking.c:346 +#: networking.c:442 networking.c:552 networking.c:603 networking.c:610 +#: networking.c:713 timezone.c:63 +msgid "Unable to open settings file" +msgstr "" + +#: dhcp.c:111 +msgid "DHCP server configuration" +msgstr "" + +#: dhcp.c:116 +msgid "Configure the DHCP server by entering the settings information." +msgstr "" + +#: dhcp.c:125 +msgid "Enabled" +msgstr "" + +#: dhcp.c:142 domainname.c:43 hostname.c:47 keymap.c:86 main.c:99 main.c:172 +#: main.c:174 netstuff.c:157 netstuff.c:733 netstuff.c:756 networking.c:163 +#: networking.c:269 networking.c:305 networking.c:409 networking.c:560 +#: networking.c:642 networking.c:653 networking.c:746 passwords.c:89 +#: timezone.c:78 +msgid "OK" +msgstr "" + +#: dhcp.c:143 domainname.c:43 hostname.c:47 keymap.c:86 netstuff.c:158 +#: netstuff.c:673 netstuff.c:733 netstuff.c:756 networking.c:305 +#: networking.c:410 networking.c:560 networking.c:653 networking.c:746 +#: passwords.c:89 timezone.c:78 +msgid "Cancel" +msgstr "" + +#: dhcp.c:156 +msgid "" +"The following fields are invalid:\n" +"\n" +msgstr "" + +#: dhcp.c:159 +msgid "Start address" +msgstr "" + +#: dhcp.c:165 +msgid "End address" +msgstr "" + +#: dhcp.c:173 networking.c:755 +msgid "Primary DNS" +msgstr "" + +#: dhcp.c:182 networking.c:764 +msgid "Secondary DNS" +msgstr "" + +#: dhcp.c:189 +msgid "Default lease time" +msgstr "" + +#: dhcp.c:195 +msgid "Max. lease time" +msgstr "" + +#: domainname.c:42 main.c:70 +msgid "Domain name" +msgstr "" + +#: domainname.c:42 +msgid "Enter Domain name" +msgstr "" + +#: domainname.c:48 +msgid "Domain name cannot be empty." +msgstr "" + +#: domainname.c:50 +msgid "Domain name cannot contain spaces." +msgstr "" + +#: domainname.c:53 +msgid "Domain name may only contain letters, numbers, hyphens and periods." +msgstr "" + +#: hostname.c:46 main.c:69 +msgid "Hostname" +msgstr "" + +#: hostname.c:46 +msgid "Enter the machine's hostname." +msgstr "" + +#: hostname.c:53 +msgid "Hostname cannot be empty." +msgstr "" + +#: hostname.c:55 +msgid "Hostname cannot contain spaces." +msgstr "" + +#: hostname.c:58 +msgid "Hostname may only contain letters, numbers and hyphens." +msgstr "" + +#: keymap.c:84 main.c:67 +msgid "Keyboard mapping" +msgstr "" + +#: keymap.c:85 +msgid "Choose the type of keyboard you are using from the list below." +msgstr "" + +#: main.c:68 timezone.c:77 +msgid "Timezone" +msgstr "" + +#: main.c:71 networking.c:110 networking.c:115 networking.c:447 +msgid "Networking" +msgstr "" + +#: main.c:72 misc.c:147 +msgid "ISDN" +msgstr "" + +#: main.c:73 +msgid "'root' password" +msgstr "" + +#: main.c:74 +msgid "'admin' password" +msgstr "" + +#: main.c:90 +msgid " <Tab>/<Alt-Tab> between elements | <Space> selects" +msgstr "" + +#: main.c:97 +msgid "Section menu" +msgstr "" + +#: main.c:98 +msgid "Select the item you wish to configure." +msgstr "" + +#: main.c:99 +msgid "Quit" +msgstr "" + +#: main.c:172 +msgid "Setup is complete." +msgstr "" + +#: main.c:174 netstuff.c:733 networking.c:560 networking.c:653 +msgid "Warning" +msgstr "" + +#: main.c:175 +msgid "" +"Initial setup was not entirely complete. You must ensure that Setup is " +"properly finished by running setup again at the shell." +msgstr "" + +#: misc.c:62 +#, c-format +msgid "Unable to write %s/main/hostname.conf" +msgstr "" + +#: misc.c:71 +msgid "Unable to open main hosts file." +msgstr "" + +#: misc.c:76 +msgid "Unable to write /etc/hosts." +msgstr "" + +#: misc.c:117 +msgid "Unable to write /etc/hosts.deny." +msgstr "" + +#: misc.c:125 +msgid "Unable to write /etc/hosts.allow." +msgstr "" + +#: misc.c:136 +msgid "Unable to set hostname." +msgstr "" + +#: misc.c:147 +msgid "Scanning and configuring ISDN devices." +msgstr "" + +#: misc.c:148 +msgid "Unable to scan for ISDN devices." +msgstr "" + +#: netstuff.c:86 +#, c-format +msgid "Interface - %s" +msgstr "" + +#: netstuff.c:91 +#, c-format +msgid "Enter the IP address information for the %s interface." +msgstr "" + +#: netstuff.c:103 +msgid "Static" +msgstr "" + +#: netstuff.c:104 +msgid "DHCP" +msgstr "" + +#: netstuff.c:105 +msgid "PPP DIALUP (PPPoE, modem, ATM ...)" +msgstr "" + +#: netstuff.c:113 +msgid "DHCP Hostname:" +msgstr "" + +#: netstuff.c:115 +msgid "Force DHCP MTU:" +msgstr "" + +#: netstuff.c:134 +msgid "IP address:" +msgstr "" + +#: netstuff.c:146 +msgid "Network mask:" +msgstr "" + +#: netstuff.c:173 networking.c:749 +msgid "The following fields are invalid:" +msgstr "" + +#: netstuff.c:183 +msgid "IP address" +msgstr "" + +#: netstuff.c:189 +msgid "Network mask" +msgstr "" + +#: netstuff.c:198 +msgid "DHCP hostname" +msgstr "" + +#: netstuff.c:396 netstuff.c:709 +msgid "Unset" +msgstr "" + +#: netstuff.c:669 +#, c-format +msgid "Please choose a networkcard for the following interface - %s." +msgstr "" + +#: netstuff.c:672 +msgid "Extended Network Menu" +msgstr "" + +#: netstuff.c:673 networking.c:520 +msgid "Select" +msgstr "" + +#: netstuff.c:673 +msgid "Identify" +msgstr "" + +#: netstuff.c:678 +msgid "Device Identification" +msgstr "" + +#: netstuff.c:678 +msgid "The lights on the selected port should flash now for 10 seconds..." +msgstr "" + +#: netstuff.c:679 +msgid "Identification is not supported by this interface." +msgstr "" + +#: netstuff.c:691 +msgid "There are no unassigned interfaces on your system." +msgstr "" + +#: netstuff.c:732 +#, c-format +msgid "Do you really want to remove the assigned %s interface?" +msgstr "" + +#: netstuff.c:755 +msgid "Select network driver" +msgstr "" + +#: netstuff.c:755 +msgid "Set additional module parameters" +msgstr "" + +#: netstuff.c:762 +msgid "Loading module..." +msgstr "" + +#: netstuff.c:777 +msgid "Unable to load driver module." +msgstr "" + +#: netstuff.c:780 +msgid "Module name cannot be blank." +msgstr "" + +#: networking.c:110 +msgid "Stopping network..." +msgstr "" + +#: networking.c:115 +msgid "Restarting network..." +msgstr "" + +#: networking.c:146 +msgid "No GREEN interface assigned." +msgstr "" + +#: networking.c:152 +msgid "Missing an IP address on GREEN." +msgstr "" + +#: networking.c:163 +msgid "Error" +msgstr "" + +#: networking.c:163 +msgid "Ignore" +msgstr "" + +#: networking.c:164 +msgid "No RED interface assigned." +msgstr "" + +#: networking.c:173 +msgid "Missing an IP address on RED." +msgstr "" + +#: networking.c:183 +msgid "No ORANGE interface assigned." +msgstr "" + +#: networking.c:189 +msgid "Missing an IP address on ORANGE." +msgstr "" + +#: networking.c:199 +msgid "No BLUE interface assigned." +msgstr "" + +#: networking.c:205 +msgid "Missing an IP address on BLUE." +msgstr "" + +#: networking.c:217 +msgid "Misssing DNS." +msgstr "" + +#: networking.c:224 +msgid "Missing Default Gateway." +msgstr "" + +#: networking.c:237 networking.c:304 +msgid "Network configuration type" +msgstr "" + +#: networking.c:238 networking.c:409 +msgid "Drivers and card assignments" +msgstr "" + +#: networking.c:239 networking.c:640 +msgid "Address settings" +msgstr "" + +#: networking.c:240 networking.c:743 +msgid "DNS and Gateway settings" +msgstr "" + +#: networking.c:260 +msgid "When configuration is complete, a network restart will be required." +msgstr "" + +#: networking.c:267 +#, c-format +msgid "" +"Current config: %s\n" +"\n" +"%s" +msgstr "" + +#: networking.c:268 +msgid "Network configuration menu" +msgstr "" + +#: networking.c:269 networking.c:520 networking.c:642 +msgid "Done" +msgstr "" + +#: networking.c:300 +#, c-format +msgid "" +"Select the network configuration for %s. The following configuration types " +"list those interfaces which have ethernet attached. If you change this " +"setting, a network restart will be required, and you will have to " +"reconfigure the network driver assignments." +msgstr "" + +#: networking.c:307 +#, c-format +msgid "" +"Not enough netcards for your choice.\n" +"\n" +"Needed: %d - Available: %d\n" +msgstr "" + +#: networking.c:359 +msgid "" +"Configure network drivers, and which interface each card is assigned to. The current configuration is as follows:\n" +"\n" +msgstr "" + +#: networking.c:408 +msgid "Do you wish to change these settings?" +msgstr "" + +#: networking.c:447 +msgid "Restarting non-local network..." +msgstr "" + +#: networking.c:464 +msgid "" +"Please choose the interface you wish to change.\n" +"\n" +msgstr "" + +#: networking.c:519 +msgid "Assigned Cards" +msgstr "" + +#: networking.c:520 +msgid "Remove" +msgstr "" + +#: networking.c:556 networking.c:649 +#, c-format +msgid "" +"If you change this IP address, and you are logged in remotely, your " +"connection to the %s machine will be broken, and you will have to reconnect " +"on the new IP. This is a risky operation, and should only be attempted if " +"you have physical access to the machine, should something go wrong." +msgstr "" + +#: networking.c:641 +msgid "Select the interface you wish to reconfigure." +msgstr "" + +#: networking.c:729 +msgid "Default gateway:" +msgstr "" + +#: networking.c:744 +msgid "" +"Enter the DNS and gateway information. These settings are used only with " +"Static IP (and DHCP if DNS set) on the RED interface." +msgstr "" + +#: networking.c:773 +msgid "Default gateway" +msgstr "" + +#: networking.c:780 +msgid "Secondary DNS specified without a Primary DNS" +msgstr "" + +#: passwords.c:33 +msgid "" +"Enter the 'root' user password. Login as this user for commandline access." +msgstr "" + +#: passwords.c:38 passwords.c:61 +msgid "Setting password" +msgstr "" + +#: passwords.c:38 +msgid "Setting 'root' password...." +msgstr "" + +#: passwords.c:39 +msgid "Problem setting 'root' password." +msgstr "" + +#: passwords.c:53 +#, c-format +msgid "" +"Enter %s 'admin' user password. This is the user to use for logging into the" +" %s web administration pages." +msgstr "" + +#: passwords.c:60 +#, c-format +msgid "Setting %s 'admin' user password..." +msgstr "" + +#: passwords.c:62 +#, c-format +msgid "Problem setting %s 'admin' user password." +msgstr "" + +#: passwords.c:76 +msgid "Password:" +msgstr "" + +#: passwords.c:77 +msgid "Again:" +msgstr "" + +#: passwords.c:95 +msgid "Password cannot be blank." +msgstr "" + +#: passwords.c:102 +msgid "Passwords do not match." +msgstr "" + +#: passwords.c:109 +msgid "Password cannot contain spaces." +msgstr "" + +#: timezone.c:77 +msgid "Choose the timezone you are in from the list below." +msgstr "" diff --git a/src/setup/po/tr.po b/src/setup/po/tr.po index 758a66e..dcb417d 100644 --- a/src/setup/po/tr.po +++ b/src/setup/po/tr.po @@ -3,13 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Kudret Emre kudretemre@hotmail.com.tr, 2014 msgid "" msgstr "" "Project-Id-Version: IPFire Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-08-21 15:12+0000\n" -"PO-Revision-Date: 2014-08-21 15:13+0000\n" -"Last-Translator: Michael Tremer michael.tremer@ipfire.org\n" +"PO-Revision-Date: 2014-09-30 20:41+0000\n" +"Last-Translator: Kudret Emre kudretemre@hotmail.com.tr\n" "Language-Team: Turkish (http://www.transifex.com/projects/p/ipfire/language/tr/)%5Cn" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,31 +20,31 @@ msgstr ""
#: dhcp.c:50 msgid "Start address:" -msgstr "" +msgstr "Başlangıç adresi:"
#: dhcp.c:51 msgid "End address:" -msgstr "" +msgstr "Bitiş adresi:"
#: dhcp.c:52 networking.c:717 msgid "Primary DNS:" -msgstr "" +msgstr "Birincil DNS:"
#: dhcp.c:53 networking.c:723 msgid "Secondary DNS:" -msgstr "" +msgstr "İkincil DNS:"
#: dhcp.c:54 msgid "Default lease (mins):" -msgstr "" +msgstr "Varsayılan kira (dakika):"
#: dhcp.c:55 msgid "Max lease (mins):" -msgstr "" +msgstr "En fazla kira (dakika):"
#: dhcp.c:56 msgid "Domain name suffix:" -msgstr "" +msgstr "Etki alanı adı son eki:"
#: dhcp.c:86 dhcp.c:93 dhcp.c:101 domainname.c:34 hostname.c:37 keymap.c:70 #: misc.c:40 misc.c:52 netstuff.c:377 netstuff.c:566 netstuff.c:704 @@ -51,19 +52,19 @@ msgstr "" #: networking.c:442 networking.c:552 networking.c:603 networking.c:610 #: networking.c:713 timezone.c:63 msgid "Unable to open settings file" -msgstr "" +msgstr "Ayar dosyası açılamıyor"
#: dhcp.c:111 msgid "DHCP server configuration" -msgstr "" +msgstr "DHCP sunucu yapılandırması"
#: dhcp.c:116 msgid "Configure the DHCP server by entering the settings information." -msgstr "" +msgstr "Ayarlar bilgisini girerek DHCP sunucusunu yapılandırın."
#: dhcp.c:125 msgid "Enabled" -msgstr "" +msgstr "Etkin"
#: dhcp.c:142 domainname.c:43 hostname.c:47 keymap.c:86 main.c:99 main.c:172 #: main.c:174 netstuff.c:157 netstuff.c:733 netstuff.c:756 networking.c:163 @@ -71,367 +72,367 @@ msgstr "" #: networking.c:642 networking.c:653 networking.c:746 passwords.c:89 #: timezone.c:78 msgid "OK" -msgstr "" +msgstr "Tamam"
#: dhcp.c:143 domainname.c:43 hostname.c:47 keymap.c:86 netstuff.c:158 #: netstuff.c:673 netstuff.c:733 netstuff.c:756 networking.c:305 #: networking.c:410 networking.c:560 networking.c:653 networking.c:746 #: passwords.c:89 timezone.c:78 msgid "Cancel" -msgstr "" +msgstr "İptal"
#: dhcp.c:156 msgid "" "The following fields are invalid:\n" "\n" -msgstr "" +msgstr "Aşağıdaki alanlar geçersiz:\n\n"
#: dhcp.c:159 msgid "Start address" -msgstr "" +msgstr "Başlangış adresi"
#: dhcp.c:165 msgid "End address" -msgstr "" +msgstr "Bitiş adresi"
#: dhcp.c:173 networking.c:755 msgid "Primary DNS" -msgstr "" +msgstr "Birincil DNS"
#: dhcp.c:182 networking.c:764 msgid "Secondary DNS" -msgstr "" +msgstr "İkincil DNS"
#: dhcp.c:189 msgid "Default lease time" -msgstr "" +msgstr "Varsayılan kira süresi"
#: dhcp.c:195 msgid "Max. lease time" -msgstr "" +msgstr "En fazla kira süresi"
#: domainname.c:42 main.c:70 msgid "Domain name" -msgstr "" +msgstr "Etki alanı adı"
#: domainname.c:42 msgid "Enter Domain name" -msgstr "" +msgstr "Etki alanı adını girin"
#: domainname.c:48 msgid "Domain name cannot be empty." -msgstr "" +msgstr "Etki alanı adı boş olamaz."
#: domainname.c:50 msgid "Domain name cannot contain spaces." -msgstr "" +msgstr "Etki alanı adı boşluk içeremez."
#: domainname.c:53 msgid "Domain name may only contain letters, numbers, hyphens and periods." -msgstr "" +msgstr "Etki alanı adı sadece harf, sayı, tire ve nokta içerebilir."
#: hostname.c:46 main.c:69 msgid "Hostname" -msgstr "" +msgstr "Ana bilgisayar adı"
#: hostname.c:46 msgid "Enter the machine's hostname." -msgstr "" +msgstr "Makinanın ana bilgisayar adını girin."
#: hostname.c:53 msgid "Hostname cannot be empty." -msgstr "" +msgstr "Ana bilgisaya adı boş olamaz."
#: hostname.c:55 msgid "Hostname cannot contain spaces." -msgstr "" +msgstr "Ana bilgisayaradı boşluk içeremez."
#: hostname.c:58 msgid "Hostname may only contain letters, numbers and hyphens." -msgstr "" +msgstr "Ana bilgisayar adı sadece harf, sayı ve tire içerebilir."
#: keymap.c:84 main.c:67 msgid "Keyboard mapping" -msgstr "" +msgstr "Klavye eşlemesi"
#: keymap.c:85 msgid "Choose the type of keyboard you are using from the list below." -msgstr "" +msgstr "Aşağıdaki listeden kullandığınız klavye tipini seçin."
#: main.c:68 timezone.c:77 msgid "Timezone" -msgstr "" +msgstr "Zaman dilimi"
#: main.c:71 networking.c:110 networking.c:115 networking.c:447 msgid "Networking" -msgstr "" +msgstr "Ağ"
#: main.c:72 misc.c:147 msgid "ISDN" -msgstr "" +msgstr "ISDN"
#: main.c:73 msgid "'root' password" -msgstr "" +msgstr "'root' şifresi"
#: main.c:74 msgid "'admin' password" -msgstr "" +msgstr "'admin' şifresi"
#: main.c:90 msgid " <Tab>/<Alt-Tab> between elements | <Space> selects" -msgstr "" +msgstr " <Tab>/<Alt-Tab> elementler arası geçiş | <Space> seç"
#: main.c:97 msgid "Section menu" -msgstr "" +msgstr "Bölüm menüsü"
#: main.c:98 msgid "Select the item you wish to configure." -msgstr "" +msgstr "Yapılandırmak istediğiniz öğeyi seçin"
#: main.c:99 msgid "Quit" -msgstr "" +msgstr "Çıkış"
#: main.c:172 msgid "Setup is complete." -msgstr "" +msgstr "Kurulum tamamlandı."
#: main.c:174 netstuff.c:733 networking.c:560 networking.c:653 msgid "Warning" -msgstr "" +msgstr "Uyarı"
#: main.c:175 msgid "" "Initial setup was not entirely complete. You must ensure that Setup is " "properly finished by running setup again at the shell." -msgstr "" +msgstr "İlk kurulum tamamen yapılamadı. Kurulumun kabuktan yeniden başlatılıp düzgünce bitirildiğinden emin olmalısınız."
#: misc.c:62 #, c-format msgid "Unable to write %s/main/hostname.conf" -msgstr "" +msgstr "%s/main/hostname.conf yazılamıyor"
#: misc.c:71 msgid "Unable to open main hosts file." -msgstr "" +msgstr "Ana hosts dosyası açılamıyor."
#: misc.c:76 msgid "Unable to write /etc/hosts." -msgstr "" +msgstr "/etc/hosts yazılamıyor."
#: misc.c:117 msgid "Unable to write /etc/hosts.deny." -msgstr "" +msgstr " /etc/hosts.deny yazılamıyor."
#: misc.c:125 msgid "Unable to write /etc/hosts.allow." -msgstr "" +msgstr "/etc/hosts.allow yazılamıyor."
#: misc.c:136 msgid "Unable to set hostname." -msgstr "" +msgstr "Ana bilgisayar adı ayarlanamıyor."
#: misc.c:147 msgid "Scanning and configuring ISDN devices." -msgstr "" +msgstr "ISDN cihazları taranıyor ve yapılandırılıyor."
#: misc.c:148 msgid "Unable to scan for ISDN devices." -msgstr "" +msgstr "ISDN cihazları için tarama yapılamıyor."
#: netstuff.c:86 #, c-format msgid "Interface - %s" -msgstr "" +msgstr "Arayüz - %s"
#: netstuff.c:91 #, c-format msgid "Enter the IP address information for the %s interface." -msgstr "" +msgstr "%s arayüzü için IP adresi bilgisini girin."
#: netstuff.c:103 msgid "Static" -msgstr "" +msgstr "Statik"
#: netstuff.c:104 msgid "DHCP" -msgstr "" +msgstr "DHCP"
#: netstuff.c:105 msgid "PPP DIALUP (PPPoE, modem, ATM ...)" -msgstr "" +msgstr "PPP DIALUP (PPPoE, modem, ATM ...)"
#: netstuff.c:113 msgid "DHCP Hostname:" -msgstr "" +msgstr "DHCP Ana bilgisayar adı:"
#: netstuff.c:115 msgid "Force DHCP MTU:" -msgstr "" +msgstr "Force DHCP MTU:"
#: netstuff.c:134 msgid "IP address:" -msgstr "" +msgstr "IP adresi:"
#: netstuff.c:146 msgid "Network mask:" -msgstr "" +msgstr "Ağ maskesi:"
#: netstuff.c:173 networking.c:749 msgid "The following fields are invalid:" -msgstr "" +msgstr "Aşağıdaki alanlar geçersiz:"
#: netstuff.c:183 msgid "IP address" -msgstr "" +msgstr "IP adresi"
#: netstuff.c:189 msgid "Network mask" -msgstr "" +msgstr "Ağ maskesi"
#: netstuff.c:198 msgid "DHCP hostname" -msgstr "" +msgstr "DHCP Ana bilgisayar adı"
#: netstuff.c:396 netstuff.c:709 msgid "Unset" -msgstr "" +msgstr "Unset"
#: netstuff.c:669 #, c-format msgid "Please choose a networkcard for the following interface - %s." -msgstr "" +msgstr "Lütfen %s arayüzü için bit ağ kartı seçin."
#: netstuff.c:672 msgid "Extended Network Menu" -msgstr "" +msgstr "Genişletilmiş Ağ Menüsü"
#: netstuff.c:673 networking.c:520 msgid "Select" -msgstr "" +msgstr "Seç"
#: netstuff.c:673 msgid "Identify" -msgstr "" +msgstr "Tanımla"
#: netstuff.c:678 msgid "Device Identification" -msgstr "" +msgstr "Cihaz Tanımlama"
#: netstuff.c:678 msgid "The lights on the selected port should flash now for 10 seconds..." -msgstr "" +msgstr "Seçilen porttaki ışıklar şimdi 10 saniye boyunca yanıp sönmeli..."
#: netstuff.c:679 msgid "Identification is not supported by this interface." -msgstr "" +msgstr "Bu arayüz kimdik doğrulamayı desteklemiyor."
#: netstuff.c:691 msgid "There are no unassigned interfaces on your system." -msgstr "" +msgstr "Sisteminizde atanmamış arayüz yok."
#: netstuff.c:732 #, c-format msgid "Do you really want to remove the assigned %s interface?" -msgstr "" +msgstr "Atanmış %s arayüzü gerçekten kaldırmak istiyor musunuz?"
#: netstuff.c:755 msgid "Select network driver" -msgstr "" +msgstr "Ağ sürücüsünü seç"
#: netstuff.c:755 msgid "Set additional module parameters" -msgstr "" +msgstr "Ek modül parametrelerini ayarla"
#: netstuff.c:762 msgid "Loading module..." -msgstr "" +msgstr "Modül yükleniyor..."
#: netstuff.c:777 msgid "Unable to load driver module." -msgstr "" +msgstr "Sürücü modülü yüklenemiyor."
#: netstuff.c:780 msgid "Module name cannot be blank." -msgstr "" +msgstr "Modül ismi boş olamaz."
#: networking.c:110 msgid "Stopping network..." -msgstr "" +msgstr "Ağ durduruluyor..."
#: networking.c:115 msgid "Restarting network..." -msgstr "" +msgstr "Ağ yeniden başlatılıyor..."
#: networking.c:146 msgid "No GREEN interface assigned." -msgstr "" +msgstr "Atanmış YEŞİL arayüz yok."
#: networking.c:152 msgid "Missing an IP address on GREEN." -msgstr "" +msgstr "YEŞİL üzerinde kayıp IP adresi."
#: networking.c:163 msgid "Error" -msgstr "" +msgstr "Hata"
#: networking.c:163 msgid "Ignore" -msgstr "" +msgstr "Yoksay"
#: networking.c:164 msgid "No RED interface assigned." -msgstr "" +msgstr "Atanmış KIRMIZI arayüz yok."
#: networking.c:173 msgid "Missing an IP address on RED." -msgstr "" +msgstr "KIRMIZI üzerinde kayıp IP adresi."
#: networking.c:183 msgid "No ORANGE interface assigned." -msgstr "" +msgstr "Atanmış TURUNCU arayüz yok."
#: networking.c:189 msgid "Missing an IP address on ORANGE." -msgstr "" +msgstr "TURUNCU üzerinde kayıp IP adresi."
#: networking.c:199 msgid "No BLUE interface assigned." -msgstr "" +msgstr "Atanmış MAVİ arayüz yok."
#: networking.c:205 msgid "Missing an IP address on BLUE." -msgstr "" +msgstr "MAVİ üzerinde kayıp IP adresi."
#: networking.c:217 msgid "Misssing DNS." -msgstr "" +msgstr "Kayıp DNS."
#: networking.c:224 msgid "Missing Default Gateway." -msgstr "" +msgstr "Kayıp Varsayılan Ağ Geçidi"
#: networking.c:237 networking.c:304 msgid "Network configuration type" -msgstr "" +msgstr "Ağ yapılandırma tipi"
#: networking.c:238 networking.c:409 msgid "Drivers and card assignments" -msgstr "" +msgstr "Sürücüler ve kart atamaları"
#: networking.c:239 networking.c:640 msgid "Address settings" -msgstr "" +msgstr "Adres ayarları"
#: networking.c:240 networking.c:743 msgid "DNS and Gateway settings" -msgstr "" +msgstr "DNS ve Ağ Geçidi ayarları"
#: networking.c:260 msgid "When configuration is complete, a network restart will be required." -msgstr "" +msgstr "Yapılandırma tamamlandığında yeniden başlatma gerekecek."
#: networking.c:267 #, c-format @@ -439,15 +440,15 @@ msgid "" "Current config: %s\n" "\n" "%s" -msgstr "" +msgstr "Geçerli yapılandırma: %s\n\n%s"
#: networking.c:268 msgid "Network configuration menu" -msgstr "" +msgstr "Ağ yapılandırma menüsü"
#: networking.c:269 networking.c:520 networking.c:642 msgid "Done" -msgstr "" +msgstr "Tamam"
#: networking.c:300 #, c-format @@ -456,7 +457,7 @@ msgid "" "list those interfaces which have ethernet attached. If you change this " "setting, a network restart will be required, and you will have to " "reconfigure the network driver assignments." -msgstr "" +msgstr "%s için ağ yapılandırmasını seçin. Aşağıdaki yapılandırma tipi listesi ethernet ayarı yapılmış olan arayüzleri gösterir. Eğer bu ayarları değiştirirseniz, ağın yeniden başlatılması ve ağ sürücüleri atamalarını tekrar yapılandırmanız gerekecektir."
#: networking.c:307 #, c-format @@ -464,35 +465,35 @@ msgid "" "Not enough netcards for your choice.\n" "\n" "Needed: %d - Available: %d\n" -msgstr "" +msgstr "Seçiminiz için yeterli kart yok.\n\nGereken: %d - Kullanılabilir: %d\n"
#: networking.c:359 msgid "" "Configure network drivers, and which interface each card is assigned to. The current configuration is as follows:\n" "\n" -msgstr "" +msgstr "Ağ sürücülerini ve her bir kart için atanmış arayüzleri yapılandırın. Geçerli yapılandırma aşağıdaki gibidir:\n\n"
#: networking.c:408 msgid "Do you wish to change these settings?" -msgstr "" +msgstr "Bu ayarları değiştirmek istiyor musunuz?"
#: networking.c:447 msgid "Restarting non-local network..." -msgstr "" +msgstr "Yerel olmayan ağ yeniden başlatılıyor..."
#: networking.c:464 msgid "" "Please choose the interface you wish to change.\n" "\n" -msgstr "" +msgstr "Lütfen değiştirmek istediğiniz arayüzü seçin.\n\n"
#: networking.c:519 msgid "Assigned Cards" -msgstr "" +msgstr "Atanmış Kartlar"
#: networking.c:520 msgid "Remove" -msgstr "" +msgstr "Kaldır"
#: networking.c:556 networking.c:649 #, c-format @@ -501,84 +502,84 @@ msgid "" "connection to the %s machine will be broken, and you will have to reconnect " "on the new IP. This is a risky operation, and should only be attempted if " "you have physical access to the machine, should something go wrong." -msgstr "" +msgstr "Eğer bu IP adresini değiştirirseniz, ve uzaktan oturum açmışsanız, %s makinesine olan bağlantınız kopacaktır ve yeni IP adresine tekrar bağlanmanız gerekecektir. Bu riskli bir işlemdir ve bir şeylerin ters gitmesi durumunda makineye fiziksel erişiminiz varsa kullanmalısınız."
#: networking.c:641 msgid "Select the interface you wish to reconfigure." -msgstr "" +msgstr "Yeniden yapılandırmak istediğiniz arayüzü seçin."
#: networking.c:729 msgid "Default gateway:" -msgstr "" +msgstr "Varsayılan ağ geçidi:"
#: networking.c:744 msgid "" "Enter the DNS and gateway information. These settings are used only with " "Static IP (and DHCP if DNS set) on the RED interface." -msgstr "" +msgstr "DNS ve ağ geçidi bilgisini girin. Bu ayarlar sadece KIRMIZI arayüzde Statik IP (ve eğer DNS ayarlanmışsa DHCP) ile kullanılacaktır."
#: networking.c:773 msgid "Default gateway" -msgstr "" +msgstr "Varsayılan ağ geçidi"
#: networking.c:780 msgid "Secondary DNS specified without a Primary DNS" -msgstr "" +msgstr "Birincil DNS olmadan İkincil DNS belirtildi."
#: passwords.c:33 msgid "" "Enter the 'root' user password. Login as this user for commandline access." -msgstr "" +msgstr "'root' kullanıcı şifresini girin. Komut satırına erişmek için bu kullanıcıyla oturum açın."
#: passwords.c:38 passwords.c:61 msgid "Setting password" -msgstr "" +msgstr "Şifre ayarlanıyor"
#: passwords.c:38 msgid "Setting 'root' password...." -msgstr "" +msgstr "'root' şifresi ayarlanıyor..."
#: passwords.c:39 msgid "Problem setting 'root' password." -msgstr "" +msgstr "'root' şifresi ayarlama sorunu."
#: passwords.c:53 #, c-format msgid "" "Enter %s 'admin' user password. This is the user to use for logging into the" " %s web administration pages." -msgstr "" +msgstr "%s 'admin' kullanıcısı için şifre girin. Bu kullanıcı, %s web yönetim sayfalarını kullanmak için oturum açılacak kullanıcıdır."
#: passwords.c:60 #, c-format msgid "Setting %s 'admin' user password..." -msgstr "" +msgstr "%s 'admin' kullanıcısının şifresi ayarlanıyor..."
#: passwords.c:62 #, c-format msgid "Problem setting %s 'admin' user password." -msgstr "" +msgstr "%s 'admin' kullanıcı şifresi ayarlama sorunu."
#: passwords.c:76 msgid "Password:" -msgstr "" +msgstr "Şifre:"
#: passwords.c:77 msgid "Again:" -msgstr "" +msgstr "Tekrar:"
#: passwords.c:95 msgid "Password cannot be blank." -msgstr "" +msgstr "Şifre boş olamaz."
#: passwords.c:102 msgid "Passwords do not match." -msgstr "" +msgstr "Şifreler eşleşmiyor."
#: passwords.c:109 msgid "Password cannot contain spaces." -msgstr "" +msgstr "Şifre boşluk içeremez."
#: timezone.c:77 msgid "Choose the timezone you are in from the list below." -msgstr "" +msgstr "Aşağıdaki listeden içinde bulunduğunuz zaman dilimini seçin." diff --git a/src/squid-accounting/acct-lib.pl b/src/squid-accounting/acct-lib.pl index 826be26..7969a50 100644 --- a/src/squid-accounting/acct-lib.pl +++ b/src/squid-accounting/acct-lib.pl @@ -392,6 +392,7 @@ sub pdf2 { my @billar = @{$_[0]}; #DATA from sendbill (just host/values) my $month = $_[1]; $month = '0'.$month if $month < 10; + $month = '12' if $month == 0; my $year = $_[2]; my $mwst = $_[3]; my @address_cust= @{$_[4]}; #Array which contains customer and hoster adresses and some additional info from billgroup diff --git a/src/squid-accounting/acct.pl b/src/squid-accounting/acct.pl index d535901..79fc7ba 100755 --- a/src/squid-accounting/acct.pl +++ b/src/squid-accounting/acct.pl @@ -210,7 +210,9 @@ sub sendbill { my @now = localtime(time); $now[5] = $now[5] + 1900; my $actmonth = $now[4]; - my $month = '0'.$actmonth if $actmonth < 10; + my $month; + $month = '0'.$actmonth if $actmonth < 10; + $month = '12' if $actmonth == 0; my $actyear = $now[5]; my ($from,$till)=&ACCT::getmonth($actmonth,$actyear); #FIXME month and year as variables! my @billar = &ACCT::GetTaValues($from,$till,$rggrp);
hooks/post-receive -- IPFire 2.x development tree