static void cc2520_lpl_tx_done(u8 status) { if (lpl_enabled) { spin_lock_irqsave(&state_sl, flags); if (cc2520_packet_requires_ack_wait(cur_tx_buf)) { if (status == CC2520_TX_SUCCESS) { lpl_state = CC2520_LPL_IDLE; spin_unlock_irqrestore(&state_sl, flags); hrtimer_cancel(&lpl_timer); lpl_top->tx_done(status); } else if (lpl_state == CC2520_LPL_TIMER_EXPIRED) { lpl_state = CC2520_LPL_IDLE; spin_unlock_irqrestore(&state_sl, flags); lpl_top->tx_done(-CC2520_TX_FAILED); } else { spin_unlock_irqrestore(&state_sl, flags); DBG((KERN_INFO "[cc2520] - lpl retransmit.\n")); lpl_bottom->tx(cur_tx_buf, cur_tx_len); } } else { if (lpl_state == CC2520_LPL_TIMER_EXPIRED) { lpl_state = CC2520_LPL_IDLE; spin_unlock_irqrestore(&state_sl, flags); lpl_top->tx_done(CC2520_TX_SUCCESS); } else { spin_unlock_irqrestore(&state_sl, flags); lpl_bottom->tx(cur_tx_buf, cur_tx_len); } } } else { lpl_top->tx_done(status); } // if packet requires ack, examine status. // if success terminate LPL window // else if status != TIMER_EXPIRED resend // else resend }
static void cc2520_sack_tx_done(u8 status) { spin_lock(&sack_sl); if (sack_state == CC2520_SACK_TX) { if (cc2520_packet_requires_ack_wait(cur_tx_buf)) { DBG((KERN_INFO "[cc2520] - Entering TX wait state.\n")); sack_state = CC2520_SACK_TX_WAIT; cc2520_sack_start_timer(); spin_unlock(&sack_sl); } else { sack_state = CC2520_SACK_IDLE; spin_unlock(&sack_sl); sack_top->tx_done(status); } } else if (sack_state == CC2520_SACK_TX_ACK) { sack_state = CC2520_SACK_IDLE; spin_unlock(&sack_sl); } else { ERR((KERN_ALERT "[cc2520] - ERROR: tx_done state engine in impossible state.\n")); } }