#define MSCAN_INIT_MODE (MSCAN_INITRQ | MSCAN_SLPRQ)
#define MSCAN_POWEROFF_MODE (MSCAN_CSWAI | MSCAN_SLPRQ)
#define MSCAN_SET_MODE_RETRIES 255
+#define MSCAN_ECHO_SKB_MAX 3
#define BTR0_BRP_MASK 0x3f
#define BTR0_SJW_SHIFT 6
u8 shadow_statflg;
u8 shadow_canrier;
u8 cur_pri;
+ u8 prev_buf_id;
u8 tx_active;
struct list_head tx_head;
out_8(®s->canrier, 0);
INIT_LIST_HEAD(&priv->tx_head);
+ priv->prev_buf_id = 0;
priv->cur_pri = 0;
priv->tx_active = 0;
priv->shadow_canrier = 0;
return 0;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
static int mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
+#else
+static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
+#endif
{
struct can_frame *frame = (struct can_frame *)skb->data;
struct mscan_regs *regs = (struct mscan_regs *)dev->base_addr;
case 1:
/* if buf_id < 3, then current frame will be send out of order,
since buffer with lower id have higher priority (hell..) */
- if (buf_id < 3)
- priv->cur_pri++;
- if (priv->cur_pri == 0xff)
- set_bit(F_TX_WAIT_ALL, &priv->flags);
netif_stop_queue(dev);
case 2:
+ if (buf_id < priv->prev_buf_id) {
+ priv->cur_pri++;
+ if (priv->cur_pri == 0xff) {
+ set_bit(F_TX_WAIT_ALL, &priv->flags);
+ netif_stop_queue(dev);
+ }
+ }
set_bit(F_TX_PROGRESS, &priv->flags);
+ break;
}
+ priv->prev_buf_id = buf_id;
out_8(®s->cantbsel, i);
rtr = frame->can_id & CAN_RTR_FLAG;
while (npackets < quota && ((canrflg = in_8(®s->canrflg)) &
(MSCAN_RXF | MSCAN_ERR_IF))) {
- skb = dev_alloc_skb(sizeof(struct can_frame));
+ skb = alloc_can_skb(dev, &frame);
if (!skb) {
if (printk_ratelimit())
dev_notice(ND2D(dev), "packet dropped\n");
continue;
}
- frame = (struct can_frame *)skb_put(skb, sizeof(*frame));
- memset(frame, 0, sizeof(*frame));
-
if (canrflg & MSCAN_RXF) {
can_id = in_be16(®s->rx.idr1_0);
if (can_id & (1 << 3)) {
}
out_8(®s->canrflg, MSCAN_RXF);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
dev->last_rx = jiffies;
+#endif
stats->rx_packets++;
stats->rx_bytes += frame->can_dlc;
} else if (canrflg & MSCAN_ERR_IF) {
}
npackets++;
- skb->dev = dev;
- skb->protocol = __constant_htons(ETH_P_CAN);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_receive_skb(skb);
}
struct mscan_priv *priv;
int i;
- dev = alloc_candev(sizeof(struct mscan_priv));
+ dev = alloc_candev(sizeof(struct mscan_priv), MSCAN_ECHO_SKB_MAX);
if (!dev)
return NULL;
priv = netdev_priv(dev);