/* * sja1000.c - Philips SJA1000 network device driver * * Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33, * 38106 Braunschweig, GERMANY * * Copyright (c) 2002-2007 Volkswagen Group Electronic Research * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Volkswagen nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * Alternatively, provided that this notice is retained in full, this * software may be distributed under the terms of the GNU General * Public License ("GPL") version 2, in which case the provisions of the * GPL apply INSTEAD OF those given above. * * The provided data structures and external interfaces from this code * are not restricted to be used by modules with a GPL compatible license. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. *
*/
/* * The command register needs some locking and time to settle * the write_reg() operation - especially on SMP systems.
*/
spin_lock_irqsave(&priv->cmdreg_lock, flags);
priv->write_reg(priv, SJA1000_CMR, val);
priv->read_reg(priv, SJA1000_SR);
spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
}
for (i = 0; i < 100; i++) { /* check reset bit */ if ((status & MOD_RM) == 0) {
priv->can.state = CAN_STATE_ERROR_ACTIVE; /* enable interrupts */ if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
priv->write_reg(priv, SJA1000_IER, IRQ_ALL); else
priv->write_reg(priv, SJA1000_IER,
IRQ_ALL & ~IRQ_BEI); return;
}
/* set chip to normal mode */ if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
mod_reg_val |= MOD_LOM; if (priv->can.ctrlmode & CAN_CTRLMODE_PRESUME_ACK)
mod_reg_val |= MOD_STM;
priv->write_reg(priv, SJA1000_MOD, mod_reg_val);
udelay(10);
status = priv->read_reg(priv, SJA1000_MOD);
}
netdev_err(dev, "setting SJA1000 into normal mode failed!\n");
}
if (!(priv->flags & SJA1000_QUIRK_NO_CDR_REG)) /* set clock divider and output control register */
priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
/* enter reset mode */ if (priv->can.state != CAN_STATE_STOPPED)
set_reset_mode(dev);
/* Initialize chip if uninitialized at this stage */ if (!(priv->flags & SJA1000_QUIRK_NO_CDR_REG ||
priv->read_reg(priv, SJA1000_CDR) & CDR_PELICAN))
chipset_init(dev);
/* create zero'ed CAN frame buffer */
skb = alloc_can_skb(dev, &cf); if (skb == NULL) return;
fi = priv->read_reg(priv, SJA1000_FI);
if (fi & SJA1000_FI_FF) { /* extended frame format (EFF) */
dreg = SJA1000_EFF_BUF;
id = (priv->read_reg(priv, SJA1000_ID1) << 21)
| (priv->read_reg(priv, SJA1000_ID2) << 13)
| (priv->read_reg(priv, SJA1000_ID3) << 5)
| (priv->read_reg(priv, SJA1000_ID4) >> 3);
id |= CAN_EFF_FLAG;
} else { /* standard frame format (SFF) */
dreg = SJA1000_SFF_BUF;
id = (priv->read_reg(priv, SJA1000_ID1) << 3)
| (priv->read_reg(priv, SJA1000_ID2) >> 5);
}
can_frame_set_cc_len(cf, fi & 0x0F, priv->can.ctrlmode); if (fi & SJA1000_FI_RTR) {
id |= CAN_RTR_FLAG;
} else { for (i = 0; i < cf->len; i++)
cf->data[i] = priv->read_reg(priv, dreg++);
if (isrc & IRQ_DOI) { /* data overrun interrupt */
netdev_dbg(dev, "data overrun interrupt\n"); if (skb) {
cf->can_id |= CAN_ERR_CRTL;
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
}
stats->rx_over_errors++;
stats->rx_errors++;
sja1000_write_cmdreg(priv, CMD_CDO); /* clear bit */
/* Some controllers needs additional handling upon overrun * condition: the controller may sometimes be totally confused * and refuse any new frame while its buffer is empty. The only * way to re-sync the read vs. write buffer offsets is to * stop any current handling and perform a reset.
*/ if (priv->flags & SJA1000_QUIRK_RESET_ON_OVERRUN)
ret = IRQ_WAKE_THREAD;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.