3
\$\begingroup\$

I've wired up an ENC28J60 module with an SPI interface to a Beaglebone Black development board running Linux 3.8, but I cannot get the device to TX (or RX) anything. Every attempt to TX times out and increments the TX errors.

Originally, the driver that shipped with the Linux kernel would not allow me to bring the link up. After a bunch of debugging, I found that if I waited some amount of time during board initialization, that I could get the link to come up. The patch to the driver was in the enc28j60_check_link_status function and was more or less the following.

  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();                                                                                                                                                                                 
    }

Now, I can reliably load the driver and configure the interface like so.

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

I've customized the ENC28J60's driver to do a bunch of additional printk while I've been searching for the root of the problem. I get the following after bringing the interface up.

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

I've narrowed it down with additional print statements to a call to spi_sync in spi_read_buf. Does anyone with knowledge of Linux network drivers or Microchip's ENC28J60 know what I should be looking into to resolve this problem?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.