Exemple #1
0
/*
 * theory of operation:
 *
 * priv->tx_echo holds the number of the oldest can_frame put for
 * transmission into the hardware, but not yet ACKed by the CAN tx
 * complete IRQ.
 *
 * We iterate from priv->tx_echo to priv->tx_next and check if the
 * packet has been transmitted, echo it back to the CAN framework.
 * If we discover a not yet transmitted packet, stop looking for more.
 */
static void c_can_do_tx(struct net_device *dev)
{
	u32 val;
	u32 msg_obj_no;
	struct c_can_priv *priv = netdev_priv(dev);
	struct net_device_stats *stats = &dev->stats;

	for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) {
		msg_obj_no = get_tx_echo_msg_obj(priv);
		val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG);
		if (!(val & (1 << (msg_obj_no - 1)))) {
			can_get_echo_skb(dev,
					msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
			stats->tx_bytes += priv->read_reg(priv,
					C_CAN_IFACE(MSGCTRL_REG, 0))
					& IF_MCONT_DLC_MASK;
			stats->tx_packets++;
			can_led_event(dev, CAN_LED_EVENT_TX);
			c_can_inval_msg_object(dev, 0, msg_obj_no);
		} else {
			break;
		}
	}

	/* restart queue if wrap-up or if queue stalled on last pkt */
	if (((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) != 0) ||
			((priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) == 0))
		netif_wake_queue(dev);
}
Exemple #2
0
/*
 * theory of operation:
 *
 * priv->tx_echo holds the number of the oldest can_frame put for
 * transmission into the hardware, but not yet ACKed by the CAN tx
 * complete IRQ.
 *
 * We iterate from priv->tx_echo to priv->tx_next and check if the
 * packet has been transmitted, echo it back to the CAN framework.
 * If we discover a not yet transmitted package, stop looking for more.
 */
static void c_can_do_tx(struct net_device *dev)
{
	u32 val;
	u32 msg_obj_no;
	struct c_can_priv *priv = netdev_priv(dev);
	struct net_device_stats *stats = &dev->stats;

	for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) {
		msg_obj_no = get_tx_echo_msg_obj(priv);
		val = c_can_read_reg32(priv, &priv->regs->txrqst1);
		if (!(val & (1 << msg_obj_no))) {
			can_get_echo_skb(dev,
					msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
			stats->tx_bytes += priv->read_reg(priv,
					&priv->regs->ifregs[0].msg_cntrl)
					& IF_MCONT_DLC_MASK;
			stats->tx_packets++;
			c_can_inval_msg_object(dev, 0, msg_obj_no);
		}
	}

	/* restart queue if wrap-up or if queue stalled on last pkt */
	if (((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) != 0) ||
			((priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) == 0))
		netif_wake_queue(dev);
}
Exemple #3
0
static void c_can_setup_tx_object(struct net_device *dev, int iface,
				  struct can_frame *frame, int idx)
{
	struct c_can_priv *priv = netdev_priv(dev);
	u16 ctrl = IF_MCONT_TX | frame->can_dlc;
	bool rtr = frame->can_id & CAN_RTR_FLAG;
	u32 arb = IF_ARB_MSGVAL;
	int i;

	if (frame->can_id & CAN_EFF_FLAG) {
		arb |= frame->can_id & CAN_EFF_MASK;
		arb |= IF_ARB_MSGXTD;
	} else {
		arb |= (frame->can_id & CAN_SFF_MASK) << 18;
	}

	if (!rtr)
		arb |= IF_ARB_TRANSMIT;

	/*
	 * If we change the DIR bit, we need to invalidate the buffer
	 * first, i.e. clear the MSGVAL flag in the arbiter.
	 */
	if (rtr != (bool)test_bit(idx, &priv->tx_dir)) {
		u32 obj = idx + C_CAN_MSG_OBJ_TX_FIRST;

		c_can_inval_msg_object(dev, iface, obj);
		change_bit(idx, &priv->tx_dir);
	}

	priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), arb);

	priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);

	if (priv->type == BOSCH_D_CAN) {
		u32 data = 0, dreg = C_CAN_IFACE(DATA1_REG, iface);

		for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
			data = (u32)frame->data[i];
			data |= (u32)frame->data[i + 1] << 8;
			data |= (u32)frame->data[i + 2] << 16;
			data |= (u32)frame->data[i + 3] << 24;
			priv->write_reg32(priv, dreg, data);
		}
	} else {
		for (i = 0; i < frame->can_dlc; i += 2) {
			priv->write_reg(priv,
					C_CAN_IFACE(DATA1_REG, iface) + i / 2,
					frame->data[i] |
					(frame->data[i + 1] << 8));
		}
	}
}
Exemple #4
0
/*
 * Configure C_CAN message objects for Tx and Rx purposes:
 * C_CAN provides a total of 32 message objects that can be configured
 * either for Tx or Rx purposes. Here the first 16 message objects are used as
 * a reception FIFO. The end of reception FIFO is signified by the EoB bit
 * being SET. The remaining 16 message objects are kept aside for Tx purposes.
 * See user guide document for further details on configuring message
 * objects.
 */
static void c_can_configure_msg_objects(struct net_device *dev)
{
	int i;

	/* first invalidate all message objects */
	for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++)
		c_can_inval_msg_object(dev, IF_RX, i);

	/* setup receive message objects */
	for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++)
		c_can_setup_receive_object(dev, IF_RX, i, 0, 0, IF_MCONT_RCV);

	c_can_setup_receive_object(dev, IF_RX, C_CAN_MSG_OBJ_RX_LAST, 0, 0,
				   IF_MCONT_RCV_EOB);
}