Hacer funcionar la 3Com 940 Gigabit (y las sk-98xx) en Linux


Muchas placas base modernas vienen con ethernet Gigabit incorporada, como la ASUS P4C800 Deluxe. El chip está fabricado por SysKonnect, que además fabrica varios modelos. SysKonnect provee drivers libres para Linux (sk98lin) que no están incluidos en los kernels oficiales, así que hay que parchearlo. Pero… resulta que el model 3C940 que me vino en mi placa tiene un bug de generación de checksums por hardware (del ASIC) y hay que tocar una línea en el kernel para que lo haga por software.

Me pasé tres días sin saber que con pasaba, no encontraba nada en Google, y sólo me fallaba la resolución DNS. Probé de todo, hasta que se me ocurrió hacer tcpdump -v en el lado del servidor DNS para que muestre más información (sí, no sé como puñetas no se me ocurrió enseguida, mis neuronas no están como antes ;-). Allí me dí cuenta por el siguiente mensaje del tcpdump:
22:44:16.242393 antoli.gallimedina.net.32770 > ponti.gallimedina.net.domain: [bad udp cksum 707e!] 17971+ [27013n] AAAA? antoli. (24) (DF) (ttl 64, id 5701, len 52).
Ostras!!! probé con el netcat, y sí, me daba error con todos los UDP de tamaño menor a 56 bytes. Pensé que era problema del driver, lo reporté a SysKonnect. Como no tuve respuesta me puse a mirar el código fuente a ver si encontraba algo, y ví el siguiente comentario en el skcsum.c:
There is a bug in the GENESIS ASIC which may lead to wrong checksums.
Cony!, a ver si eso me tocó a mí. Al final comprobé que era éste el problema y luego encontré como solucionarlo.
Instalar el driver
Primero hay que bajarse los drivers de SysKonnect del modelo sk98lin. Luego hay que parchear el kernel correspondiente y seleccionar los modelos de tarjetas que correspondan.

Workaround al problema de hardware (por software, ¡mamón!)
Si tenéis problemas con la resolución DNS, y en general con paquetes UDP de menos de 56 bytes, seguramente tenéis un chip defectuoso como el mío, así que tenéis que hacer una paqueña modificación más. Hay que habilitar la generación de checksum por software.
Lo que explico a continuación está probado con el kernel 2.6.0-test2, pero supongo que es similar a otras versiones.
Si estás en el directorio del kernel, editad el fichero drivers/net/sk98lin/skge.c. Aproximadamente en la línea 426 encontraréis lo siguiente:

#define USE_SK_TX_CHECKSUM

Esa definición se usa para que los checksums de paquetes salientes se haga por hardware, hay que comentarla para que se haga por software:

/***** #define USE_SK_TX_CHECKSUM ******/

Ahora a compilad e instalar vuestro kernel, ya debería funcionar perfectamente.

# dmesg
….
eth0: network connection up using port A
speed: 100
autonegotiation: yes
duplex mode: full
flowctrl: symmetric
tx-checksum: disabled
….

Este post ha sido traido de forma automatica desde https://web.archive.org/web/20140625063149/http:/bulma.net/body.phtml?nIdNoticia=1832 por un robot nigromante, si crees que puede mejorarse, por favor, contactanos.


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.