• Alexander Aring's avatar
    at86rf230: rework transmit and receive handling · 1d15d6b5
    Alexander Aring authored
    This patch is a complete reimplementation of transmit and receive
    handling for the at86rf230 driver.
    
    It solves also six bugs:
    
    First:
    
    The RX_SAFE_MODE is enabled and the transceiver doesn't leave the
    receive state while the framebuffer isn't read by a CMD_FB command.
    This is useful to read out the frame and don't get into another receive
    or transmit state, otherwise the frame would be overwritten.
    The current driver do twice CMD_FB calls, the first one leaves this
    protection.
    
    Second:
    
    Sometimes the CRC calculation is correct and the length field is greater
    127. The current mac802154 layer and filter of a at86rf2xx doesn't check
    on this and the kernel crashes. In this case the frame is corrupted, we
    send the whole receive buffer to the next layer which can be useful for
    sniffing.
    
    Thrid:
    There is a undocumented race condition. When we are go into the
    RX_AACK_ON state the transceiver could be changed into RX_AACK_BUSY
    state. This is a normal behaviour. In this case the transceiver received
    a SHR while assert wasn't finished.
    
    Fourth:
    It also handle some more "correct" state changes. In aret mode the
    transceiver need to go to TX_ON before the transceiver go into
    RX_AACK_ON.
    
    Fifth:
    The programming model [0] describes also a error handling in ARET mode
    if the trac status is different than zero. This is patch adds support
    for handling this.
    
    Sixth:
    In receive handling the transceiver should also get the trac status
    according [0]. The driver could use the trac status as error statistic
    handling, but the driver doesn't use this currently. There is maybe some
    timing behaviour or the read of this register change some transceiver
    states.
    
    In addition the irqworker is removed. Instead we do async spi calls and
    no scheduling is involved anymore. The transmit function is also
    asynchron but with a wait_for_completion handling. The mac802154 layer
    doesn't support asynchron transmit handling right now.
    
    The state change behaviour is now changes, before it was:
    
    1. assert while(!STATE_TRANSITION_IN_PROGRESS)
    2. state change
    3. assert while(!STATE_TRANSITION_IN_PROGRESS)
    4. assert once(wanted state != current state)
    
    Sometimes a unexcepted state change occurs when 4. assert was violated.
    The new state change behaviour is:
    
    1. assert while(!STATE_TRANSITION_IN_PROGRESS)
    2. state change
    3. wait state change timing according datasheet
    4. assert once(wanted state != current state)
    
    This behaviour is described in the at86rf231 software programming model [0].
    The state change documentation in this programming guide should also valid for
    at86rf212 and at86rf233 chips.
    
    The transceiver don't do a FORCE_TX_ON while we want to transmit a PDU.
    The new behaviour is a TX_ON and wait a receiving time (tFrame + tPAck).
    If we are still in RX_AACK_BUSY then we transmit a FORCE_TX_ON as timeout
    handling. The different is that FORCE_TX_ON aborts receiving and TX_ON
    waits if RX_AACK_BUSY is finished. This should decrease the drop rate of
    packets.
    
    [0] http://www.atmel.com/Images/AVR2022_swpm231-2.0.zipSigned-off-by: default avatarAlexander Aring <alex.aring@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    1d15d6b5
at86rf230.c 38 KB