Upgrade to 4.4.50-rt62
[kvmfornfv.git] / kernel / drivers / net / can / c_can / c_can.c
index 5d214d1..e3dccd3 100644 (file)
@@ -332,9 +332,23 @@ static void c_can_setup_tx_object(struct net_device *dev, int iface,
 
        priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
 
-       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));
+       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));
+               }
        }
 }
 
@@ -402,10 +416,20 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl)
        } else {
                int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
 
-               for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
-                       data = priv->read_reg(priv, dreg);
-                       frame->data[i] = data;
-                       frame->data[i + 1] = data >> 8;
+               if (priv->type == BOSCH_D_CAN) {
+                       for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
+                               data = priv->read_reg32(priv, dreg);
+                               frame->data[i] = data;
+                               frame->data[i + 1] = data >> 8;
+                               frame->data[i + 2] = data >> 16;
+                               frame->data[i + 3] = data >> 24;
+                       }
+               } else {
+                       for (i = 0; i < frame->can_dlc; i += 2, dreg++) {
+                               data = priv->read_reg(priv, dreg);
+                               frame->data[i] = data;
+                               frame->data[i + 1] = data >> 8;
+                       }
                }
        }
 
@@ -962,7 +986,6 @@ static int c_can_handle_bus_err(struct net_device *dev,
         * type of the last error to occur on the CAN bus
         */
        cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-       cf->data[2] |= CAN_ERR_PROT_UNSPEC;
 
        switch (lec_type) {
        case LEC_STUFF_ERROR:
@@ -975,8 +998,7 @@ static int c_can_handle_bus_err(struct net_device *dev,
                break;
        case LEC_ACK_ERROR:
                netdev_dbg(dev, "ack error\n");
-               cf->data[3] |= (CAN_ERR_PROT_LOC_ACK |
-                               CAN_ERR_PROT_LOC_ACK_DEL);
+               cf->data[3] = CAN_ERR_PROT_LOC_ACK;
                break;
        case LEC_BIT1_ERROR:
                netdev_dbg(dev, "bit1 error\n");
@@ -988,8 +1010,7 @@ static int c_can_handle_bus_err(struct net_device *dev,
                break;
        case LEC_CRC_ERROR:
                netdev_dbg(dev, "CRC error\n");
-               cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
-                               CAN_ERR_PROT_LOC_CRC_DEL);
+               cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
                break;
        default:
                break;