Gentoo + HUAWEI E220 HSDPA USB modem

I will explain how to have the HUAWEI E220 HSDPA USB modem working on your Gentoo system.

Hardware configuration:
In order to have the modem functioning you need to have all necessary modules compiled in the Linux kernel. Moreover, you need to have the card properly recognized by these modules. This is not trivial because the HUAWEI E220 modem is in fact a device with a twofold nature: it is a modem but, at the same time, it is a USB storage device. The storage device contains the Windows drivers, so it's pretty useless for our purposes, but the dual nature can generate some trouble. We will deal with this in a later section

Kernel configuration:

zgrep "CONFIG_USB_SERIAL_GENERIC" /proc/config.gz
In recent kernel (at least since version 2.6.20), the HUAWEI E220 modem is supported by the USB generic serial driver (usbserial module). To use it, you also need the support for the PPP protocol and for asynchronous serial ports. To check if these drivers are compiled in the kernel, useand
zgrep "CONFIG_PPP" /proc/config.gz
zgrep "CONFIG_PPP_ASYNC" /proc/config.gz

or check your kernel configuration (if you use genkernel it can be found in /etc/kernels/).

If the options are not set as a module (m) recompile your kernel with the following options activated
Device Drivers ---> USB Support ---> [M] USB Serial Converter support ---> [*] USB Generic Serial Driver

Device Drivers ---> Network device support ---> [M] PPP (point-to-point protocol) support
[M] PPP support for async serial ports
If you say [M] for "USB Serial Converter support" and [*] for "USB Generic Serial Driver", you get the usbserial module.

Udev rules

Once these drivers are available, plug the USB cable and use
lsusb -v
to see if the modem has been properly recognized. You should see something like
...
idVendor 0x12d1
idProduct 0x1003
bcdDevice 0.00
iManufacturer 1 HUAWEI Technologies
iProduct 2 HUAWEI Mobile
...
The idProduct and idVendor should be passed at the module of the USB generic serial driver usbserial when it is loaded. For instance, from the command line, one can do
modprobe usbserial vendor=0x12d1 product=0x1003
In principle one can automatically load the usbserial at boot time with the proper parameter settings inserting a line in /etc/modules.autoload.d/kernel-2.6). We will follow a more sophisticated approach: we create an explicit rule for udev. Create the file /etc/udev/rules.d/50-huawei.rules inserting the line
SUBSYSTEM=="usb", SYSFS{idProduct}=="1003", SYSFS{idVendor}=="12d1", RUN+="/sbin/modprobe usbserial vendor=0x12d1 product=0x1003"
SUBSYSTEM=="usb", SYSFS{idProduct}=="1003", SYSFS{idVendor}=="12d1", RUN+="/sbin/modprobe ppp_generic"
In this way the module is loaded with the proper settings when the device is inserted, together with the ppp module. This approach is particularly suited if you need to use the module usbserial with different devices. Of course, if your idProduct and idVendor codes are different remember to adapt the previous line. Now do
udevcontrol reload_rules
and unplug and plug again the USB cable. You should find at the end of your /var/log/messages something like
... usbserial_generic 3-1:1.0: generic converter detected
... usb 3-1: generic converter now attached to ttyUSB0
...
... usbserial_generic 3-1:1.1: generic converter detected
... usb 3-1: generic converter now attached to ttyUSB1
...
... usbserial_generic 3-1:1.2: generic converter detected
... usb 3-1: generic converter now attached to ttyUSB2
If this is the case, that is if three devices /dev/ttyUSB[0,1,2] have been created, your modem is ready to be used. You can jump to the software configuration section below. If instead you get only the /dev/ttyUSB0, you need some further hacking. Be aware, you may have /dev/sg[0,1,2] instead. See the next section.

Switching to modem mode
As mentioned before, the E220 modem has a dual nature: it is both a communication and a storage device. For some reason, sometimes under Linux the communication part is not fully recognized and the device is activated in its "storage" status. Luckily, however, somebody did already work out the solution. You can find a little program called huaweiAktBbo. This program can be used to switch the E220 from "storage" to "modem" status.

Download the source code, compile it and save the executable in the /usr/local/sbin/ directory

gcc huaweiAktBbo.c -lusb -o huaweiAktBbo
mv huaweiAktBbo /usr/local/sbin/
Now add a couple of lines to the previously prepared udev rule

File: /etc/udev/rules.d/50-huawei.rules
SUBSYSTEM=="usb", SYSFS{idProduct}=="1003", SYSFS{idVendor}=="12d1", RUN+="/sbin/modprobe usbserial vendor=0x12d1 product=0x1003"
SUBSYSTEM=="usb", SYSFS{idProduct}=="1003", SYSFS{idVendor}=="12d1", RUN+="/sbin/modprobe ppp_generic"
SUBSYSTEM=="usb", SYSFS{idProduct}=="1003", SYSFS{idVendor}=="12d1", RUN+="/bin/sleep 10"
SUBSYSTEM=="usb", SYSFS{idProduct}=="1003", SYSFS{idVendor}=="12d1", RUN+="/usr/local/sbin/huaweiAktBbo"
In this way the udev system automatically run the program huaweiAktBbo (after a suitable delay) to set the modem. By unplugging and plugging again the device you can check that all three ttyUSB devices are now created.

Software configuration
The HUAWEI E220 adapter works as a modem and relies on PPP to establish a connection. One can use any PPP management program. Several GUI programs are available for both KDE and Gnome. In what follows I stick with a bare-bone approach.

ppp configuration
Just emerge the relevant software
emerge net-dialup/ppp
and create the following file which defines the connection parameters
File: /etc/ppp/peers/E220
/dev/ttyUSB0
460800
crtscts
modem
noauth
usepeerdns
defaultroute
noipdefault
debug
noccp
nobsdcomp
novj
user "irrelevant"
password "irrelevant"
connect '/usr/sbin/chat -f /etc/ppp/chat-E220-pin || /usr/sbin/chat -f /etc/ppp/chat-E220-nopin'
Notice that we defined both an username and a password. Even if the values of these parameters are irrelevant, they presence seems to make the whole login procedure run smoother. Notice also that the previous file needs two chat scripts. This is due to the fact that the first time that the device is plugged in, one need to provide it the card PIN code. For subsequent connection this generate an error. Then create the needed scripts

File: /etc/ppp/chat-E220-pin
ABORT BUSY
ABORT ERROR
ABORT 'NO CARRIER'
REPORT CONNECT
TIMEOUT 10
"" "ATZ"
OK "AT+CPIN=pin"
OK AT+CGDCONT=1,"ip","internet"
OK "ATE1V1&D2&C1S0=0+IFC=2,2"
OK "AT+IPR=115200"
OK "ATE1"
TIMEOUT 60
"" "ATD*99***1#"
CONNECT \c
and

File: /etc/ppp/chat-E220-nopin
ABORT BUSY
ABORT ERROR
ABORT 'NO CARRIER'
REPORT CONNECT
TIMEOUT 10
"" "ATZ"
OK AT+CGDCONT=1,"ip","internet"
OK "ATE1V1&D2&C1S0=0+IFC=2,2"
OK "AT+IPR=115200"
OK "ATE1"
TIMEOUT 60
"" "ATD*99***1#"
CONNECT \c
where pin is the PIN of your card (typically a four digit code) and internet is the Access Point Name (APN) of the service you use (for instance mine is "web.omnitel.it"). If you don't know the Internet APN, ask your service provider.

At this point you should be able to start the PPP connection using
pon E220
and stop it with
poff E220
DNS problem
I've noticed that The first time it is invoked, the connection script generate wrong names for the DNS servers. The same behaviour is reported here here. If this is the case for you too, probably it is better to realy on some external DNS service. An excellent solution is provided by the Open DNS project. Simply remove from /usr/ppp/peers/E220 the option usepeerdns. Then, edit your /etc/resolv.conf and just add these lines somewhere near the top
#Open DNS server
nameserver 208.67.222.222
nameserver 208.67.220.220
If you have several network device configured, however, it is likely that your /etc/resolv.conf get overwritten by the system. In this case the safest approach is to cinfigure the DNS server in /etc/conf.d/net. Assuming the name of your interface is ppp0 add the following lines at the end of the file
config_ppp0=( "ppp" )
dns_servers_ppp0=( "208.67.222.222" "208.67.220.220")
in this way a correct /etc/resolv.conf is generated automatically when the interface is switched on.