提交 602de7ea 编写于 作者: D David S. Miller

Merge tag 'linux-can-next-for-3.19-20141207' of git://gitorious.org/linux-can/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2014-12-07

this is a pull request of 8 patches for net-next/master.

Andri Yngvason contributes 4 patches in which the CAN state change
handling is consolidated and unified among the sja1000, mscan and
flexcan driver. The three patches by Jeremiah Mahler fix spelling
mistakes and eliminate the banner[] variable in various parts. And a
patch by me that switches on sparse endianess checking by default.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
......@@ -29,4 +29,5 @@ obj-$(CONFIG_CAN_GRCAN) += grcan.o
obj-$(CONFIG_CAN_RCAR) += rcar_can.o
obj-$(CONFIG_CAN_XILINXCAN) += xilinx_can.o
subdir-ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
subdir-ccflags-y += -D__CHECK_ENDIAN__
subdir-ccflags-$(CONFIG_CAN_DEBUG_DEVICES) += -DDEBUG
......@@ -60,7 +60,7 @@ MODULE_DESCRIPTION(KBUILD_MODNAME "CAN netdevice driver");
*
* The message objects 1..14 can be used for TX and RX while the message
* objects 15 is optimized for RX. It has a shadow register for reliable
* data receiption under heavy bus load. Therefore it makes sense to use
* data reception under heavy bus load. Therefore it makes sense to use
* this message object for the needed use case. The frame type (EFF/SFF)
* for the message object 15 can be defined via kernel module parameter
* "msgobj15_eff". If not equal 0, it will receive 29-bit EFF frames,
......
......@@ -273,6 +273,84 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
return err;
}
static void can_update_state_error_stats(struct net_device *dev,
enum can_state new_state)
{
struct can_priv *priv = netdev_priv(dev);
if (new_state <= priv->state)
return;
switch (new_state) {
case CAN_STATE_ERROR_WARNING:
priv->can_stats.error_warning++;
break;
case CAN_STATE_ERROR_PASSIVE:
priv->can_stats.error_passive++;
break;
case CAN_STATE_BUS_OFF:
default:
break;
};
}
static int can_tx_state_to_frame(struct net_device *dev, enum can_state state)
{
switch (state) {
case CAN_STATE_ERROR_ACTIVE:
return CAN_ERR_CRTL_ACTIVE;
case CAN_STATE_ERROR_WARNING:
return CAN_ERR_CRTL_TX_WARNING;
case CAN_STATE_ERROR_PASSIVE:
return CAN_ERR_CRTL_TX_PASSIVE;
default:
return 0;
}
}
static int can_rx_state_to_frame(struct net_device *dev, enum can_state state)
{
switch (state) {
case CAN_STATE_ERROR_ACTIVE:
return CAN_ERR_CRTL_ACTIVE;
case CAN_STATE_ERROR_WARNING:
return CAN_ERR_CRTL_RX_WARNING;
case CAN_STATE_ERROR_PASSIVE:
return CAN_ERR_CRTL_RX_PASSIVE;
default:
return 0;
}
}
void can_change_state(struct net_device *dev, struct can_frame *cf,
enum can_state tx_state, enum can_state rx_state)
{
struct can_priv *priv = netdev_priv(dev);
enum can_state new_state = max(tx_state, rx_state);
if (unlikely(new_state == priv->state)) {
netdev_warn(dev, "%s: oops, state did not change", __func__);
return;
}
netdev_dbg(dev, "New error state: %d\n", new_state);
can_update_state_error_stats(dev, new_state);
priv->state = new_state;
if (unlikely(new_state == CAN_STATE_BUS_OFF)) {
cf->can_id |= CAN_ERR_BUSOFF;
return;
}
cf->can_id |= CAN_ERR_CRTL;
cf->data[1] |= tx_state >= rx_state ?
can_tx_state_to_frame(dev, tx_state) : 0;
cf->data[1] |= tx_state <= rx_state ?
can_rx_state_to_frame(dev, rx_state) : 0;
}
EXPORT_SYMBOL_GPL(can_change_state);
/*
* Local echo of CAN messages
*
......
......@@ -577,98 +577,30 @@ static int flexcan_poll_bus_err(struct net_device *dev, u32 reg_esr)
return 1;
}
static void do_state(struct net_device *dev,
struct can_frame *cf, enum can_state new_state)
{
struct flexcan_priv *priv = netdev_priv(dev);
struct can_berr_counter bec;
__flexcan_get_berr_counter(dev, &bec);
switch (priv->can.state) {
case CAN_STATE_ERROR_ACTIVE:
/*
* from: ERROR_ACTIVE
* to : ERROR_WARNING, ERROR_PASSIVE, BUS_OFF
* => : there was a warning int
*/
if (new_state >= CAN_STATE_ERROR_WARNING &&
new_state <= CAN_STATE_BUS_OFF) {
netdev_dbg(dev, "Error Warning IRQ\n");
priv->can.can_stats.error_warning++;
cf->can_id |= CAN_ERR_CRTL;
cf->data[1] = (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
}
case CAN_STATE_ERROR_WARNING: /* fallthrough */
/*
* from: ERROR_ACTIVE, ERROR_WARNING
* to : ERROR_PASSIVE, BUS_OFF
* => : error passive int
*/
if (new_state >= CAN_STATE_ERROR_PASSIVE &&
new_state <= CAN_STATE_BUS_OFF) {
netdev_dbg(dev, "Error Passive IRQ\n");
priv->can.can_stats.error_passive++;
cf->can_id |= CAN_ERR_CRTL;
cf->data[1] = (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_PASSIVE :
CAN_ERR_CRTL_RX_PASSIVE;
}
break;
case CAN_STATE_BUS_OFF:
netdev_err(dev, "BUG! "
"hardware recovered automatically from BUS_OFF\n");
break;
default:
break;
}
/* process state changes depending on the new state */
switch (new_state) {
case CAN_STATE_ERROR_WARNING:
netdev_dbg(dev, "Error Warning\n");
cf->can_id |= CAN_ERR_CRTL;
cf->data[1] = (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
break;
case CAN_STATE_ERROR_ACTIVE:
netdev_dbg(dev, "Error Active\n");
cf->can_id |= CAN_ERR_PROT;
cf->data[2] = CAN_ERR_PROT_ACTIVE;
break;
case CAN_STATE_BUS_OFF:
cf->can_id |= CAN_ERR_BUSOFF;
can_bus_off(dev);
break;
default:
break;
}
}
static int flexcan_poll_state(struct net_device *dev, u32 reg_esr)
{
struct flexcan_priv *priv = netdev_priv(dev);
struct sk_buff *skb;
struct can_frame *cf;
enum can_state new_state;
enum can_state new_state = 0, rx_state = 0, tx_state = 0;
int flt;
struct can_berr_counter bec;
flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK;
if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) {
if (likely(!(reg_esr & (FLEXCAN_ESR_TX_WRN |
FLEXCAN_ESR_RX_WRN))))
new_state = CAN_STATE_ERROR_ACTIVE;
else
new_state = CAN_STATE_ERROR_WARNING;
} else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE))
tx_state = unlikely(reg_esr & FLEXCAN_ESR_TX_WRN) ?
CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE;
rx_state = unlikely(reg_esr & FLEXCAN_ESR_RX_WRN) ?
CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE;
new_state = max(tx_state, rx_state);
} else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE)) {
__flexcan_get_berr_counter(dev, &bec);
new_state = CAN_STATE_ERROR_PASSIVE;
else
rx_state = bec.rxerr >= bec.txerr ? new_state : 0;
tx_state = bec.rxerr <= bec.txerr ? new_state : 0;
} else {
new_state = CAN_STATE_BUS_OFF;
}
/* state hasn't changed */
if (likely(new_state == priv->can.state))
......@@ -678,8 +610,11 @@ static int flexcan_poll_state(struct net_device *dev, u32 reg_esr)
if (unlikely(!skb))
return 0;
do_state(dev, cf, new_state);
priv->can.state = new_state;
can_change_state(dev, cf, tx_state, rx_state);
if (unlikely(new_state == CAN_STATE_BUS_OFF))
can_bus_off(dev);
netif_receive_skb(skb);
dev->stats.rx_packets++;
......
......@@ -289,18 +289,15 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
/* This function returns the old state to see where we came from */
static enum can_state check_set_state(struct net_device *dev, u8 canrflg)
static enum can_state get_new_state(struct net_device *dev, u8 canrflg)
{
struct mscan_priv *priv = netdev_priv(dev);
enum can_state state, old_state = priv->can.state;
if (canrflg & MSCAN_CSCIF && old_state <= CAN_STATE_BUS_OFF) {
state = state_map[max(MSCAN_STATE_RX(canrflg),
MSCAN_STATE_TX(canrflg))];
priv->can.state = state;
}
return old_state;
if (unlikely(canrflg & MSCAN_CSCIF))
return state_map[max(MSCAN_STATE_RX(canrflg),
MSCAN_STATE_TX(canrflg))];
return priv->can.state;
}
static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame)
......@@ -349,7 +346,7 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame,
struct mscan_priv *priv = netdev_priv(dev);
struct mscan_regs __iomem *regs = priv->reg_base;
struct net_device_stats *stats = &dev->stats;
enum can_state old_state;
enum can_state new_state;
netdev_dbg(dev, "error interrupt (canrflg=%#x)\n", canrflg);
frame->can_id = CAN_ERR_FLAG;
......@@ -363,27 +360,13 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame,
frame->data[1] = 0;
}
old_state = check_set_state(dev, canrflg);
/* State changed */
if (old_state != priv->can.state) {
switch (priv->can.state) {
case CAN_STATE_ERROR_WARNING:
frame->can_id |= CAN_ERR_CRTL;
priv->can.can_stats.error_warning++;
if ((priv->shadow_statflg & MSCAN_RSTAT_MSK) <
(canrflg & MSCAN_RSTAT_MSK))
frame->data[1] |= CAN_ERR_CRTL_RX_WARNING;
if ((priv->shadow_statflg & MSCAN_TSTAT_MSK) <
(canrflg & MSCAN_TSTAT_MSK))
frame->data[1] |= CAN_ERR_CRTL_TX_WARNING;
break;
case CAN_STATE_ERROR_PASSIVE:
frame->can_id |= CAN_ERR_CRTL;
priv->can.can_stats.error_passive++;
frame->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
break;
case CAN_STATE_BUS_OFF:
frame->can_id |= CAN_ERR_BUSOFF;
new_state = get_new_state(dev, canrflg);
if (new_state != priv->can.state) {
can_change_state(dev, frame,
state_map[MSCAN_STATE_TX(canrflg)],
state_map[MSCAN_STATE_RX(canrflg)]);
if (priv->can.state == CAN_STATE_BUS_OFF) {
/*
* The MSCAN on the MPC5200 does recover from bus-off
* automatically. To avoid that we stop the chip doing
......@@ -396,9 +379,6 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame,
MSCAN_SLPRQ | MSCAN_INITRQ);
}
can_bus_off(dev);
break;
default:
break;
}
}
priv->shadow_statflg = canrflg & MSCAN_STAT_MSK;
......
......@@ -392,12 +392,20 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
struct can_frame *cf;
struct sk_buff *skb;
enum can_state state = priv->can.state;
enum can_state rx_state, tx_state;
unsigned int rxerr, txerr;
uint8_t ecc, alc;
skb = alloc_can_err_skb(dev, &cf);
if (skb == NULL)
return -ENOMEM;
txerr = priv->read_reg(priv, SJA1000_TXERR);
rxerr = priv->read_reg(priv, SJA1000_RXERR);
cf->data[6] = txerr;
cf->data[7] = rxerr;
if (isrc & IRQ_DOI) {
/* data overrun interrupt */
netdev_dbg(dev, "data overrun interrupt\n");
......@@ -412,13 +420,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
/* error warning interrupt */
netdev_dbg(dev, "error warning interrupt\n");
if (status & SR_BS) {
if (status & SR_BS)
state = CAN_STATE_BUS_OFF;
cf->can_id |= CAN_ERR_BUSOFF;
can_bus_off(dev);
} else if (status & SR_ES) {
else if (status & SR_ES)
state = CAN_STATE_ERROR_WARNING;
} else
else
state = CAN_STATE_ERROR_ACTIVE;
}
if (isrc & IRQ_BEI) {
......@@ -452,10 +458,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
if (isrc & IRQ_EPI) {
/* error passive interrupt */
netdev_dbg(dev, "error passive interrupt\n");
if (status & SR_ES)
state = CAN_STATE_ERROR_PASSIVE;
if (state == CAN_STATE_ERROR_PASSIVE)
state = CAN_STATE_ERROR_WARNING;
else
state = CAN_STATE_ERROR_ACTIVE;
state = CAN_STATE_ERROR_PASSIVE;
}
if (isrc & IRQ_ALI) {
/* arbitration lost interrupt */
......@@ -467,27 +474,15 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
cf->data[0] = alc & 0x1f;
}
if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
state == CAN_STATE_ERROR_PASSIVE)) {
uint8_t rxerr = priv->read_reg(priv, SJA1000_RXERR);
uint8_t txerr = priv->read_reg(priv, SJA1000_TXERR);
cf->can_id |= CAN_ERR_CRTL;
if (state == CAN_STATE_ERROR_WARNING) {
priv->can.can_stats.error_warning++;
cf->data[1] = (txerr > rxerr) ?
CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
} else {
priv->can.can_stats.error_passive++;
cf->data[1] = (txerr > rxerr) ?
CAN_ERR_CRTL_TX_PASSIVE :
CAN_ERR_CRTL_RX_PASSIVE;
}
cf->data[6] = txerr;
cf->data[7] = rxerr;
}
if (state != priv->can.state) {
tx_state = txerr >= rxerr ? state : 0;
rx_state = txerr <= rxerr ? state : 0;
priv->can.state = state;
can_change_state(dev, cf, tx_state, rx_state);
if(state == CAN_STATE_BUS_OFF)
can_bus_off(dev);
}
netif_rx(skb);
......
......@@ -56,9 +56,6 @@
#include <linux/can.h>
#include <linux/can/skb.h>
static __initconst const char banner[] =
KERN_INFO "slcan: serial line CAN interface driver\n";
MODULE_ALIAS_LDISC(N_SLCAN);
MODULE_DESCRIPTION("serial line CAN interface");
MODULE_LICENSE("GPL");
......@@ -702,8 +699,8 @@ static int __init slcan_init(void)
if (maxdev < 4)
maxdev = 4; /* Sanity */
printk(banner);
printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev);
pr_info("slcan: serial line CAN interface driver\n");
pr_info("slcan: %d dynamic interface channels.\n", maxdev);
slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL);
if (!slcan_devs)
......
......@@ -50,9 +50,6 @@
#include <linux/slab.h>
#include <net/rtnetlink.h>
static __initconst const char banner[] =
KERN_INFO "vcan: Virtual CAN interface driver\n";
MODULE_DESCRIPTION("virtual CAN interface");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
......@@ -173,7 +170,7 @@ static struct rtnl_link_ops vcan_link_ops __read_mostly = {
static __init int vcan_init_module(void)
{
printk(banner);
pr_info("vcan: Virtual CAN interface driver\n");
if (echo)
printk(KERN_INFO "vcan: enabled echo on driver level.\n");
......
......@@ -127,6 +127,9 @@ void unregister_candev(struct net_device *dev);
int can_restart_now(struct net_device *dev);
void can_bus_off(struct net_device *dev);
void can_change_state(struct net_device *dev, struct can_frame *cf,
enum can_state tx_state, enum can_state rx_state);
void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
unsigned int idx);
unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
......
......@@ -71,6 +71,7 @@
#define CAN_ERR_CRTL_TX_PASSIVE 0x20 /* reached error passive status TX */
/* (at least one error counter exceeds */
/* the protocol-defined level of 127) */
#define CAN_ERR_CRTL_ACTIVE 0x40 /* recovered to error active state */
/* error in CAN protocol (type) / data[2] */
#define CAN_ERR_PROT_UNSPEC 0x00 /* unspecified */
......
......@@ -64,9 +64,6 @@
#include "af_can.h"
static __initconst const char banner[] = KERN_INFO
"can: controller area network core (" CAN_VERSION_STRING ")\n";
MODULE_DESCRIPTION("Controller Area Network PF_CAN core");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>, "
......@@ -524,7 +521,7 @@ static void can_rx_delete_receiver(struct rcu_head *rp)
/**
* can_rx_unregister - unsubscribe CAN frames from a specific interface
* @dev: pointer to netdevice (NULL => unsubcribe from 'all' CAN devices list)
* @dev: pointer to netdevice (NULL => unsubscribe from 'all' CAN devices list)
* @can_id: CAN identifier
* @mask: CAN mask
* @func: callback function on filter match
......@@ -896,7 +893,7 @@ static __init int can_init(void)
offsetof(struct can_frame, data) !=
offsetof(struct canfd_frame, data));
printk(banner);
pr_info("can: controller area network core (" CAN_VERSION_STRING ")\n");
memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list));
......
......@@ -78,8 +78,6 @@
(CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG))
#define CAN_BCM_VERSION CAN_VERSION
static __initconst const char banner[] = KERN_INFO
"can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n";
MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
MODULE_LICENSE("Dual BSD/GPL");
......@@ -441,7 +439,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op,
/* mark as used and throttled by default */
lastdata->can_dlc |= (RX_RECV|RX_THR);
/* throtteling mode inactive ? */
/* throttling mode inactive ? */
if (!op->kt_ival2.tv64) {
/* send RX_CHANGED to the user immediately */
bcm_rx_changed(op, lastdata);
......@@ -452,7 +450,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op,
if (hrtimer_active(&op->thrtimer))
return;
/* first receiption with enabled throttling mode */
/* first reception with enabled throttling mode */
if (!op->kt_lastmsg.tv64)
goto rx_changed_settime;
......@@ -480,7 +478,7 @@ static void bcm_rx_cmp_to_index(struct bcm_op *op, unsigned int index,
const struct can_frame *rxdata)
{
/*
* no one uses the MSBs of can_dlc for comparation,
* no one uses the MSBs of can_dlc for comparison,
* so we use it here to detect the first time of reception
*/
......@@ -510,7 +508,7 @@ static void bcm_rx_cmp_to_index(struct bcm_op *op, unsigned int index,
}
/*
* bcm_rx_starttimer - enable timeout monitoring for CAN frame receiption
* bcm_rx_starttimer - enable timeout monitoring for CAN frame reception
*/
static void bcm_rx_starttimer(struct bcm_op *op)
{
......@@ -539,7 +537,7 @@ static void bcm_rx_timeout_tsklet(unsigned long data)
}
/*
* bcm_rx_timeout_handler - when the (cyclic) CAN frame receiption timed out
* bcm_rx_timeout_handler - when the (cyclic) CAN frame reception timed out
*/
static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer)
{
......@@ -627,7 +625,7 @@ static enum hrtimer_restart bcm_rx_thr_handler(struct hrtimer *hrtimer)
}
/*
* bcm_rx_handler - handle a CAN frame receiption
* bcm_rx_handler - handle a CAN frame reception
*/
static void bcm_rx_handler(struct sk_buff *skb, void *data)
{
......@@ -1612,7 +1610,7 @@ static int __init bcm_module_init(void)
{
int err;
printk(banner);
pr_info("can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n");
err = can_proto_register(&bcm_can_proto);
if (err < 0) {
......
......@@ -361,7 +361,7 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
* The Controller Area Network controllers only accept CAN frames with
* correct CRCs - which are not visible in the controller registers.
* According to skbuff.h documentation the csum_start element for IP
* checksums is undefined/unsued when ip_summed == CHECKSUM_UNNECESSARY.
* checksums is undefined/unused when ip_summed == CHECKSUM_UNNECESSARY.
* Only CAN skbs can be processed here which already have this property.
*/
......
......@@ -56,8 +56,6 @@
#include <net/net_namespace.h>
#define CAN_RAW_VERSION CAN_VERSION
static __initconst const char banner[] =
KERN_INFO "can: raw protocol (rev " CAN_RAW_VERSION ")\n";
MODULE_DESCRIPTION("PF_CAN raw protocol");
MODULE_LICENSE("Dual BSD/GPL");
......@@ -810,7 +808,7 @@ static __init int raw_module_init(void)
{
int err;
printk(banner);
pr_info("can: raw protocol (rev " CAN_RAW_VERSION ")\n");
err = can_proto_register(&raw_can_proto);
if (err < 0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册