1. 24 Jul, 2008 5 commits
    • Lennert Buytenhek's avatar
      mv643xx_eth: also check TX_IN_PROGRESS when disabling transmit path · ae9ae064
      Lennert Buytenhek authored
      The recommended sequence for waiting for the transmit path to clear
      after disabling all of the transmit queues is to wait for the
      TX_FIFO_EMPTY bit in the Port Status register to become set as well
      as the TX_IN_PROGRESS bit to clear.
      Signed-off-by: default avatarLennert Buytenhek <buytenh@marvell.com>
      ae9ae064
    • Lennert Buytenhek's avatar
      mv643xx_eth: don't fiddle with maximum receive packet size setting · 65193a91
      Lennert Buytenhek authored
      The maximum receive packet size field in the Port Serial Control
      register controls at what size received packets are flagged
      overlength in the receive descriptor, but it doesn't prevent
      overlength packets from being DMAd to memory and signaled to the
      host like other received packets.
      
      mv643xx_eth does not support receiving jumbo frames in 10/100 mode,
      but setting the packet threshold to larger than 1522 bytes in 10/100
      mode won't cause breakage by itself.
      
      If we really want to enforce maximum packet size on the receiving
      end instead of on the sending end where it should be done, we can
      always just add a length check to the software receive handler
      instead of relying on the hardware to do the comparison for us.
      
      What's more, changing the maximum packet size field requires
      temporarily disabling the RX/TX paths.  So once the link comes
      up in 10/100 Mb/s mode or 1000 Mb/s mode, we'd have to disable it
      again just to set the right maximum packet size field (1522 in
      10/100 Mb/s mode or 9700 in 1000 Mb/s mode), just so that we can
      offload one comparison operation to hardware that we might as well
      do in software, assuming that we'd want to do it at all.
      
      Contrary to what the documentation suggests, there is no harm in
      just setting a 9700 byte maximum packet size in 10/100 mode, so use
      the maximum maximum packet size for all modes.
      Signed-off-by: default avatarLennert Buytenhek <buytenh@marvell.com>
      65193a91
    • Lennert Buytenhek's avatar
      mv643xx_eth: fix transmit-reclaim-in-napi-poll · 4dfc1c87
      Lennert Buytenhek authored
      The mv643xx_eth driver allows doing transmit reclaim from within the
      napi poll routine, but after doing reclaim, it would forget to check
      the free transmit descriptor count and wake up the transmit queue if
      the reclaim caused enough descriptors for a new packet to become
      available.  This would cause the netdev watchdog to occasionally kick
      in during certain workloads with combined receive and transmit traffic.
      
      Fix this by adding a wakeup check identical to the one in the
      interrupt handler to the napi poll routine.
      Signed-off-by: default avatarLennert Buytenhek <buytenh@marvell.com>
      4dfc1c87
    • Lennert Buytenhek's avatar
      mv643xx_eth: prevent breakage when link goes down during transmit · 6b368f68
      Lennert Buytenhek authored
      When the ethernet link goes down while mv643xx_eth is transmitting
      data, transmit DMA can stop before all queued transmit descriptors
      have been processed.  But even the descriptors that _have_ been
      processed might not be properly marked as done before the transmit
      DMA unit shuts down.
      
      Then when the link comes up again, the hardware transmit pointer
      might have advanced while not all previous packet descriptors have
      been marked as transmitted, causing software transmit reclaim to
      hang waiting for the hardware to finish transmitting a descriptor
      that it has already skipped.
      
      This patch forcibly reclaims all packets on the transmit ring on a
      link down interrupt, and then resyncs the hardware transmit pointer to
      what the software's idea of the first free descriptor is.  Also, we
      need to prevent re-waking the transmit queue if we get a 'transmit
      done' interrupt at the same time as a 'link down' interrupt, which
      this patch does as well.
      Signed-off-by: default avatarLennert Buytenhek <buytenh@marvell.com>
      6b368f68
    • Lennert Buytenhek's avatar
      mv643xx_eth: fix TX hang erratum workaround · 8fa89bf5
      Lennert Buytenhek authored
      The previously merged TX hang erratum workaround ("mv643xx_eth:
      work around TX hang hardware issue") assumes that TX_END interrupts
      are delivered simultaneously with or after their corresponding TX
      interrupts, but this is not always true in practise.
      
      In particular, it appears that TX_END interrupts are issued as soon
      as descriptor fetch returns an invalid descriptor, which may happen
      before earlier descriptors have been fully transmitted and written
      back to memory as being done.
      
      This hardware behavior can lead to a situation where the current
      driver code mistakenly assumes that the MAC has given up transmitting
      before noticing the packets that it is in fact still currently working
      on, causing the driver to re-kick the transmit queue, which will only
      cause the MAC to re-fetch the invalid head descriptor, and generate
      another TX_END interrupt, et cetera, until the packets in the pipe
      finally finish transmitting and have their descriptors written back
      to memory, which will then finally break the loop.
      
      Fix this by having the erratum workaround not check the 'number of
      unfinished descriptor', but instead, to compare the software's idea
      of what the head descriptor pointer should be to the hardware's head
      descriptor pointer (which is updated on the same conditions as the
      TX_END interupt is generated on, i.e. possibly before all previous
      descriptors have been transmitted and written back).
      Signed-off-by: default avatarLennert Buytenhek <buytenh@marvell.com>
      8fa89bf5
  2. 23 Jul, 2008 9 commits
  3. 22 Jul, 2008 26 commits