El controlador enc28j60 de Linux siempre se agota en la transmisión

3

He conectado un módulo ENC28J60 con una interfaz SPI a una placa de desarrollo Beaglebone Black que ejecuta Linux 3.8, pero no puedo llevar el dispositivo a TX (o RX). Cada intento de TX expira e incrementa los errores de TX.

Originalmente, el controlador que venía con el kernel de Linux no me permitía abrir el enlace. Después de un montón de depuración, descubrí que si esperaba un poco de tiempo durante la inicialización de la placa, podría hacer que se abriera el enlace. El parche para el controlador estaba en la función enc28j60_check_link_status y era más o menos el siguiente.

  unsigned long timeout = jiffies + 1*HZ;                                                                                                                                                             
  while ((enc28j60_phy_read(priv, PHSTAT2) & PHSTAT2_LSTAT) == 0) {                                                                                                              
    if (time_after(jiffies, timeout)) {                                                                                                                                                         
      if (netif_msg_drv(priv))                                                                                                                                                            
        dev_dbg(&priv->spi->dev,                                                                                                                                                    
          "reg %02x ready timeout!\n", reg);                                                                                                                                  
        break;                                                                                                                                                                              
      }                                                                                                                                                                                           
      schedule();                                                                                                                                                                                 
    }

Ahora, puedo cargar de manera confiable el controlador y configurar la interfaz como tal.

ifconfig rename3 down
ethtool -s rename3 msglvl 0xffff
ethtool -s rename3 speed 10 duplex full
ifconfig rename3 up

Personalicé el controlador del ENC28J60 para hacer un montón de printk adicional mientras buscaba la raíz del problema. Obtengo lo siguiente después de activar la interfaz.

Feb  1 00:22:48 arm kernel: [  100.001942] enc28j60: HELLO WORLD
Feb  1 00:22:48 arm kernel: [  100.002092] enc28j60: enc28j60_net_open() enter
Feb  1 00:22:48 arm kernel: [  100.002119] enc28j60: enc28j60_hw_disable() enter
Feb  1 00:22:48 arm kernel: [  100.002315] enc28j60: enc28j60_hw_init() enter
Feb  1 00:22:48 arm kernel: [  100.002342] enc28j60: enc28j60_hw_init() - FullDuplex
Feb  1 00:22:48 arm kernel: [  100.002366] enc28j60: enc28j60_soft_reset() enter
Feb  1 00:22:48 arm kernel: [  100.006957] enc28j60: nolock_rxfifo_init() enter
Feb  1 00:22:48 arm kernel: [  100.007117] enc28j60: erxrdpt_workaround() enter
Feb  1 00:22:48 arm kernel: [  100.007373] enc28j60: nolock_txfifo_init() enter
Feb  1 00:22:48 arm kernel: [  100.007807] enc28j60: chip RevID: 0x06
Feb  1 00:22:48 arm kernel: [  100.009680] enc28j60: enc28j60_phy_write() enter
Feb  1 00:22:48 arm kernel: [  100.010950] enc28j60: enc28j60_phy_write() enter
Feb  1 00:22:48 arm kernel: [  100.011335] enc28j60: enc28j60_phy_write() enter
Feb  1 00:22:48 arm kernel: [  100.014973] enc28j60 Hw initialized.
Feb  1 00:22:48 arm kernel: [  100.014973] HwRevID: 0x06
Feb  1 00:22:48 arm kernel: [  100.014973] Cntrl: ECON1 ECON2 ESTAT  EIR  EIE
Feb  1 00:22:48 arm kernel: [  100.014973]        0x03  0x80  0x01  0x00  0x00
Feb  1 00:22:48 arm kernel: [  100.014973] MAC  : MACON1 MACON3 MACON4
Feb  1 00:22:48 arm kernel: [  100.014973]        0x0d   0x33   0x00
Feb  1 00:22:48 arm kernel: [  100.014973] Rx   : ERXST  ERXND  ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL
Feb  1 00:22:48 arm kernel: [  100.014973]        0x0000 0x19ff 0x0000  0x19ff  0xa1    0x00    0x05ee
Feb  1 00:22:48 arm kernel: [  100.014973] Tx   : ETXST  ETXND  MACLCON1 MACLCON2 MAPHSUP
Feb  1 00:22:48 arm kernel: [  100.014973]        0x1a00 0x1fff 0x0f     0x37     0x10
Feb  1 00:22:48 arm kernel: [  100.015073] enc28j60: enc28j60_set_hw_macaddr() enter
Feb  1 00:22:48 arm kernel: [  100.015105] enc28j60: rename3: Setting MAC address to ee:31:66:60:5a:52
Feb  1 00:22:48 arm kernel: [  100.015530] enc28j60: enc28j60_hw_enable() enter
Feb  1 00:22:48 arm kernel: [  100.015556] enc28j60: enc28j60_hw_enable() enabling interrupts.
Feb  1 00:22:48 arm kernel: [  100.015578] enc28j60: enc28j60_phy_write() enter
Feb  1 00:22:48 arm kernel: [  100.017800] enc28j60: enc28j60_check_link_status() enter
Feb  1 00:22:48 arm kernel: [  100.020726] enc28j60: enc28j60_check_link_status() PHSTAT1: 1800, PHSTAT2: 0200
Feb  1 00:22:48 arm kernel: [  100.020760] enc28j60:enc28j60_check_link_status() polling PHSTAT2_LSTAT != 0
Feb  1 00:22:48 arm kernel: [  100.069286] enc28j60:enc28j60_check_link_status() reg/link now 1536/1024
Feb  1 00:22:48 arm kernel: [  100.069319] enc28j60:enc28j60_check_link_status() have link! setting carrier on
Feb  1 00:22:48 arm kernel: [  100.069362] net rename3: link up - Full duplex
Feb  1 00:22:58 arm kernel: [  109.989281] enc28j60: enc28j60_send_packet() enter
Feb  1 00:22:58 arm kernel: [  109.989329] enc28j60: enc28j60_send_packet() enter
Feb  1 00:22:58 arm kernel: [  109.989411] enc28j60: enc28j60_tx_work_handler() enter
Feb  1 00:22:58 arm kernel: [  109.989437] enc28j60: enc28j60_hw_tx() enter
Feb  1 00:22:58 arm kernel: [  109.989459] enc28j60: Tx Packet Len:70
Feb  1 00:22:58 arm kernel: [  109.989481] enc28j60: enc28j60_hw_tx - packet len:70
Feb  1 00:22:58 arm kernel: [  109.989517] pk data: 00000000: 33 33 00 00 00 02 ee 31 66 60 5a 52 86 dd 60 00  33.....1f'ZR..'.
Feb  1 00:22:58 arm kernel: [  109.989548] pk data: 00000010: 00 00 00 10 3a ff fe 80 00 00 00 00 00 00 ec 31  ....:..........1
Feb  1 00:22:58 arm kernel: [  109.989576] pk data: 00000020: 66 ff fe 60 5a 52 ff 02 00 00 00 00 00 00 00 00  f..'ZR..........
Feb  1 00:22:58 arm kernel: [  109.989605] pk data: 00000030: 00 00 00 00 00 02 85 00 21 65 00 00 00 00 01 01  ........!e......
Feb  1 00:22:58 arm kernel: [  109.989633] pk data: 00000040: ee 31 66 60 5a 52                                .1f'ZR
Feb  1 00:22:58 arm kernel: [  109.989655] enc28j60: enc28j60_packet_write() enter
Feb  1 00:22:58 arm kernel: [  109.990379] enc28j60: enc28j60_packet_write() after control byte ERWPT:0x1a01
Feb  1 00:22:58 arm kernel: [  109.990406] enc28j60: spi_write_buf() enter
Feb  1 00:22:58 arm kernel: [  109.990571] enc28j60: enc28j60_packet_write() spi_write returns 0
Feb  1 00:22:58 arm kernel: [  109.990761] enc28j60: enc28j60_packet_write() after write packet ERWPT:0x1a47, len=70
Feb  1 00:23:18 arm kernel: [  129.979247] enc28j60: enc28j60_tx_timeout() enter
Feb  1 00:23:18 arm kernel: [  129.979313] net rename3: enc28j60 tx timeout

Lo he reducido con declaraciones de impresión adicionales a una llamada a spi_sync en spi_read_buf . ¿Alguien que tenga conocimiento de los controladores de red de Linux o del ENC28J60 de Microchip sabe qué debo investigar para resolver este problema?

    
pregunta sholsapp

0 respuestas

Lea otras preguntas en las etiquetas