Exemple #1
0
static irqreturn_t at86rf230_isr(int irq, void *data)
{
	struct at86rf230_local *lp = data;
	struct at86rf230_state_change *ctx;
	int rc;

	disable_irq_nosync(irq);

	ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC);
	if (!ctx) {
		enable_irq(irq);
		return IRQ_NONE;
	}

	at86rf230_setup_spi_messages(lp, ctx);
	/* tell on error handling to free ctx */
	ctx->free = true;

	ctx->buf[0] = (RG_IRQ_STATUS & CMD_REG_MASK) | CMD_REG;
	ctx->msg.complete = at86rf230_irq_status;
	rc = spi_async(lp->spi, &ctx->msg);
	if (rc) {
		at86rf230_async_error(lp, ctx, rc);
		enable_irq(irq);
		return IRQ_NONE;
	}

	return IRQ_HANDLED;
}
Exemple #2
0
static void
at86rf230_async_write_reg(struct at86rf230_local *lp, u8 reg, u8 val,
			  struct at86rf230_state_change *ctx,
			  void (*complete)(void *context))
{
	int rc;

	ctx->buf[0] = (reg & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
	ctx->buf[1] = val;
	ctx->msg.complete = complete;
	rc = spi_async(lp->spi, &ctx->msg);
	if (rc)
		at86rf230_async_error(lp, ctx, rc);
}
Exemple #3
0
/* Generic function to get some register value in async mode */
static void
at86rf230_async_read_reg(struct at86rf230_local *lp, u8 reg,
			 struct at86rf230_state_change *ctx,
			 void (*complete)(void *context))
{
	int rc;

	u8 *tx_buf = ctx->buf;

	tx_buf[0] = (reg & CMD_REG_MASK) | CMD_REG;
	ctx->msg.complete = complete;
	rc = spi_async(lp->spi, &ctx->msg);
	if (rc)
		at86rf230_async_error(lp, ctx, rc);
}
static void
at86rf230_write_frame_complete(void *context)
{
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;
	u8 *buf = ctx->buf;
	int rc;

	buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
	buf[1] = STATE_BUSY_TX;
	ctx->trx.len = 2;
	ctx->msg.complete = NULL;
	rc = spi_async(lp->spi, &ctx->msg);
	if (rc)
		at86rf230_async_error(lp, ctx, rc);
}
static void
at86rf230_rx_read_frame(struct at86rf230_local *lp)
{
	int rc;

	u8 *buf = lp->irq.buf;

	buf[0] = CMD_FB;
	lp->irq.trx.len = AT86RF2XX_MAX_BUF;
	lp->irq.msg.complete = at86rf230_rx_read_frame_complete;
	rc = spi_async(lp->spi, &lp->irq.msg);
	if (rc) {
		enable_irq(lp->spi->irq);
		at86rf230_async_error(lp, &lp->irq, rc);
	}
}
Exemple #6
0
/* This function do a sync framework above the async state change.
 * Some callbacks of the IEEE 802.15.4 driver interface need to be
 * handled synchronously.
 */
static int
at86rf230_sync_state_change(struct at86rf230_local *lp, unsigned int state)
{
	unsigned long rc;

	at86rf230_async_state_change(lp, &lp->state, state,
				     at86rf230_sync_state_change_complete);

	rc = wait_for_completion_timeout(&lp->state_complete,
					 msecs_to_jiffies(100));
	if (!rc) {
		at86rf230_async_error(lp, &lp->state, -ETIMEDOUT);
		return -ETIMEDOUT;
	}

	return 0;
}
static void
at86rf230_rx_read_frame(void *context)
{
    struct at86rf230_state_change *ctx = context;
    struct at86rf230_local *lp = ctx->lp;
    u8 *buf = ctx->buf;
    int rc;

    buf[0] = CMD_FB;
    ctx->trx.len = AT86RF2XX_MAX_BUF;
    ctx->msg.complete = at86rf230_rx_read_frame_complete;
    rc = spi_async(lp->spi, &ctx->msg);
    if (rc) {
        ctx->trx.len = 2;
        enable_irq(ctx->irq);
        at86rf230_async_error(lp, ctx, rc);
    }
}
static void
at86rf230_async_state_change_start(void *context)
{
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;
	u8 *buf = ctx->buf;
	const u8 trx_state = buf[1] & 0x1f;
	int rc;

	/* Check for "possible" STATE_TRANSITION_IN_PROGRESS */
	if (trx_state == STATE_TRANSITION_IN_PROGRESS) {
		udelay(1);
		at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
					 at86rf230_async_state_change_start,
					 ctx->irq_enable);
		return;
	}

	/* Check if we already are in the state which we change in */
	if (trx_state == ctx->to_state) {
		if (ctx->complete)
			ctx->complete(context);
		return;
	}

	/* Set current state to the context of state change */
	ctx->from_state = trx_state;

	/* Going into the next step for a state change which do a timing
	 * relevant delay.
	 */
	buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
	buf[1] = ctx->to_state;
	ctx->trx.len = 2;
	ctx->msg.complete = at86rf230_async_state_delay;
	rc = spi_async(lp->spi, &ctx->msg);
	if (rc) {
		if (ctx->irq_enable)
			enable_irq(lp->spi->irq);

		at86rf230_async_error(lp, ctx, rc);
	}
}
static irqreturn_t at86rf230_isr(int irq, void *data)
{
    struct at86rf230_local *lp = data;
    struct at86rf230_state_change *ctx = &lp->irq;
    u8 *buf = ctx->buf;
    int rc;

    disable_irq_nosync(irq);

    buf[0] = (RG_IRQ_STATUS & CMD_REG_MASK) | CMD_REG;
    ctx->msg.complete = at86rf230_irq_status;
    rc = spi_async(lp->spi, &ctx->msg);
    if (rc) {
        enable_irq(irq);
        at86rf230_async_error(lp, ctx, rc);
        return IRQ_NONE;
    }

    return IRQ_HANDLED;
}
Exemple #10
0
/* Generic function to get some register value in async mode */
static void
at86rf230_async_read_reg(struct at86rf230_local *lp, const u8 reg,
                         struct at86rf230_state_change *ctx,
                         void (*complete)(void *context),
                         const bool irq_enable)
{
    int rc;

    u8 *tx_buf = ctx->buf;

    tx_buf[0] = (reg & CMD_REG_MASK) | CMD_REG;
    ctx->msg.complete = complete;
    ctx->irq_enable = irq_enable;
    rc = spi_async(lp->spi, &ctx->msg);
    if (rc) {
        if (irq_enable)
            enable_irq(ctx->irq);

        at86rf230_async_error(lp, ctx, rc);
    }
}
static void
at86rf230_write_frame(void *context)
{
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;
	struct sk_buff *skb = lp->tx_skb;
	u8 *buf = lp->tx.buf;
	int rc;

	spin_lock(&lp->lock);
	lp->is_tx = 1;
	spin_unlock(&lp->lock);

	buf[0] = CMD_FB | CMD_WRITE;
	buf[1] = skb->len + 2;
	memcpy(buf + 2, skb->data, skb->len);
	lp->tx.trx.len = skb->len + 2;
	lp->tx.msg.complete = at86rf230_write_frame_complete;
	rc = spi_async(lp->spi, &lp->tx.msg);
	if (rc)
		at86rf230_async_error(lp, ctx, rc);
}
Exemple #12
0
static void
at86rf230_rx_trac_check(void *context)
{
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;
	u8 *buf = ctx->buf;
	int rc;

	if (IS_ENABLED(CONFIG_IEEE802154_AT86RF230_DEBUGFS)) {
		u8 trac = TRAC_MASK(buf[1]);

		switch (trac) {
		case TRAC_SUCCESS:
			lp->trac.success++;
			break;
		case TRAC_SUCCESS_WAIT_FOR_ACK:
			lp->trac.success_wait_for_ack++;
			break;
		case TRAC_INVALID:
			lp->trac.invalid++;
			break;
		default:
			WARN_ONCE(1, "received rx trac status %d\n", trac);
			break;
		}
	}

	buf[0] = CMD_FB;
	ctx->trx.len = AT86RF2XX_MAX_BUF;
	ctx->msg.complete = at86rf230_rx_read_frame_complete;
	rc = spi_async(lp->spi, &ctx->msg);
	if (rc) {
		ctx->trx.len = 2;
		at86rf230_async_error(lp, ctx, rc);
	}
}