eff->id is a 32 bit value. It is not aligned. So, you must always use
{get|set}_unaligned_be32() to manipulate this value.
N.B. on x86 architecture, unaligned access is fine, but some other
architecture may throw a fault. Read this for more details:
https://docs.kernel.org/arm/mem_alignment.html
+static int f81604_set_reset_mode(struct net_device *netdev)Thanks for removing F81604_USB_MAX_RETRY.
+{
+ struct f81604_port_priv *priv = netdev_priv(netdev);
+ int status, i;
+ u8 tmp;
+
+ /* disable interrupts */
+ status = f81604_set_sja1000_register(priv->dev, netdev->dev_id,
+ SJA1000_IER, IRQ_OFF);
+ if (status)
+ return status;
+
+ for (i = 0; i < F81604_SET_DEVICE_RETRY; i++) {
Yet, I still would like to understand why you need one hundred tries?
Is this some paranoiac safenet? Or does the device really need so many
attempts to operate reliably? If those are needed, I would like to
understand the root cause.
+ int status, len;In your driver, you send the CAN frames one at a time and wait for the
+
+ if (can_dropped_invalid_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ netif_stop_queue(netdev);
rx_handler to restart the queue. This approach dramatically degrades
the throughput. Is this a device limitation? Is the device not able to
manage more than one frame at a time?
+static int f81604_set_termination(struct net_device *netdev, u16 term)Did you witness a race condition?
+{
+ struct f81604_port_priv *port_priv = netdev_priv(netdev);
+ struct f81604_priv *priv;
+ u8 mask, data = 0;
+ int r;
+
+ priv = usb_get_intfdata(port_priv->intf);
+
+ if (netdev->dev_id == 0)
+ mask = F81604_CAN0_TERM;
+ else
+ mask = F81604_CAN1_TERM;
+
+ if (term == F81604_TERMINATION_ENABLED)
+ data = mask;
+
+ mutex_lock(&priv->mutex);
As far as I know, this call back is only called while the network
stack big kernel lock (a.k.a. rtnl_lock) is being hold.
If you have doubt, try adding a:
ASSERT_RTNL()
If this assert works, then another mutex is not needed.
+ port_priv->can.do_get_berr_counter = f81604_get_berr_counter;Did you test the CAN_CTRLMODE_CC_LEN8_DLC feature? Did you confirm
+ port_priv->can.ctrlmode_supported =
+ CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_3_SAMPLES |
+ CAN_CTRLMODE_ONE_SHOT | CAN_CTRLMODE_BERR_REPORTING |
+ CAN_CTRLMODE_CC_LEN8_DLC | CAN_CTRLMODE_PRESUME_ACK;
that you can send and receive DLC greater than 8?