Power to the People of Iran

..and welcome to eeeGadgets! This blog is dedicated to everything associated with the wide (and interesting) field of mobile computing. The main focus is on presenting all the various hardware modifications I made to my eeePC, but I will also give short reviews of other interesting Mobile Internet Devices I come across. Further I want to share some tips and tricks I found out to be helpful in getting the most performance out of Ubuntu linux...
On the right side under "LABELS" you can navigate between various assorted article categories. Also, on the very bottom of the site you will find some useful weblinks, as well as a small broadband connection speed test (which can be very useful sometimes).
If you want to, you can subscribe to my RSS news feed too, to be always up to date about my latest articles - simply click on "subscribe now!" in the little box on the right side. Alternatively, you can subscribe to my simple email newsletter by clicking here.
For questions, feedback, suggestions, criticism and everything else, don't hesitate to contact me:

....have fun reading!

If you like my site and want to support me , you can always donate to my personal "coffee funds" using the PayPal "donate" button further down on the right! :)

Wednesday, March 18, 2009

HowTo: optimize your wireless broadband speed when running Ubuntu

At present time, many 3G/HSDPA modems need the driver module "usbserial.ko" if you want to use them with Ubuntu linux. While this alone doesn't present a problem, it is far more problematic that said "usbserial" driver module wasn't designed for the data throughput rates seen with today's broadband connections, and so has only a very small data buffer for the serial ports it emulates - insufficient for an average HSDPA connection, resulting in not as much bandwidth as you would expect.

As I own a Sierra MC8775 3G modem and am running ubuntu 8.04 on my eeePC, I had exactly this issue, and so went to search for a solution - and found a rather nice one, which requires quite a bit of software hackery but works pretty good (almost 2x the data throughput for me!): a patch that modifies "usbserial.ko" to have a variable buffer size!
It is not easy to pull off for the novice and requires knowledge of basic linux commands for copying, renaming, deleting and moving files and creating directories, as well as extracting archives, basic knowledge about how to compile stuff using "make" - and lastly you should be familiar with adding new driver modules to your system too..
Also of course you need the basic linux packages required for compiling stuff (just apt-get install what is missing if some error occurs during compiling, and if your linux moans about something needed but not installed...)

Here's what I did, explained in ten steps:

1. Become root: "
sudo -s"

2. Download the "linux-source" package and extract it to some folder (I created the folder /usr/src/linux-source-2.6.24/ on my system for this purpose)

3. copy your current kernel config to the new source directory you just made:
cp /boot/config-$(uname -r) /usr/src/linux-source-2.6.24/.config"

4. goto the source directory and create a config file for compiling the module:
cd /usr/src/linux-source-2.6.24/ && make menuconfig" (just press [rightArrow] then [Enter] to exit when the graphical menu pops up)

5. copy the following code and insert + save to some empty file (I used "/root/usbserial.c.patch" to save to):

# diff -Naur usb-serial.c usb-serial-v620.c
--- usb-serial.c        2005-03-01 23:38:37.000000000 -0800
+++ usb-serial-v620.c 2005-07-22 10:09:59.000000000 -0700
@@ -361,6 +361,7 @@
drivers depend on it.
+static ushort maxSize = 0;
static int debug;
static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */
static LIST_HEAD(usb_serial_driver_list);
@@ -1060,7 +1061,7 @@
dev_err(&interface->dev, "No free urbs available\n");
goto probe_error;
- buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+ buffer_size = (endpoint->wMaxPacketSize > maxSize)?endpoint->wMaxPacketSize:maxSize;
port->bulk_in_size = buffer_size;
port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
@@ -1433,3 +1434,5 @@
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
+module_param(maxSize, ushort,0);
+MODULE_PARM_DESC(maxSize,"User specified USB endpoint size");

6. apply your newly created patch file to the source code of "usbserial.c":
"cd /usr/src/linux-source-2.6.24 && patch -Np0 -i /root/usbserial.c.patch"

7. if not all patches were applied successfully (was the case for me), you need to edit usbserial.c manually and replace the line that reads

buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);

with the following lines:

buffer_size = (endpoint->wMaxPacketSize > maxSize)?endpoint->wMaxPacketSize:maxSize; port->bulk_in_size = buffer_size;
port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);

8. compile the module (actually all serial driver modules used for usb devices, but still faster than compiling all kernel modules!):
"make -C /lib/modules/$(uname -r)/build M=/usr/src/linux-source-2.6.24/drivers/usb/serial"

9. make a backup copy of your old "usbserial.ko" by renaming it to something like "usbserial.ko.old", then copy your new patched "usbserial.ko" to /lib/modules/kernel/drivers/usb/serial/ and run "depmod -a".

10. After unloading your old usbserial (modprobe -r), you can now load your new "ubserial" driver module with the additional module option "maxSize=xxxx" (where xxxx can be 2048 for example), I use "modprobe usbserial vendor=0x03f0 product=0x1e1d maxSize=2048" to have it identify my SierraMC8775 modem properly and to give it a big enough data buffer to cope with HSDPA traffic.

You can easily check if you were successful in patching your "usbserial.ko" without having to load/reload it by easily typing "modinfo usbserial" - if everything went well you will see a new module parameter "maxSize" listed....

If everything went well you will have notably higher data transfer/download rates with your wireless 3G/UMTS/HSDPA braodband (you can easily check this with the bandwidth performance check on the bottom of my page).



vivek said...

Hi, when i copy from a pendrive to my ubuntu I do get speeds of around 10 MBps. But my evdo card works very slow on ubuntu 9.10. I don't really understand if this is the problem of the usb-serial driver or something else. please enlighten

Dennis said...

I don't think the usbserial is a problem anymore with 9.10 - more likely that your EVDO card's driver is the reason.. (does your modem card work better with other machines, or other operating systems?)

vivek said...

My evdo card works better with windows. I even experience problem while browsing on karmic. Initially I had problem in getting connected on 9.10. so I installed network manager 0.7 . By this I got connected to the internet, but the speed is slow. I can get a maximum speed on around 30 kBps while I get around 150 kBps in windows vista.

Broadband Connection Test:

Just click on "Speedtest starten" to evaluate your actual downlink in MBit/sec (takes 10 seconds approx.)

(c) dsl-speed-messung.de - DSL Speed Test