Lines Matching +full:single +full:- +full:mux +full:- +full:ctrl

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Janz MODULbus VMOD-ICAN3 CAN Interface Driver
29 /* JANZ ICAN3 "old-style" host interface queue page numbers */
36 /* Janz ICAN3 "old-style" host interface control registers */
52 /* Janz ICAN3 "new-style" host interface queue page numbers */
61 /* Janz ICAN3 "new-style" and "fast" host interface descriptor flags */
174 /* Number of buffers for use in the "new-style" host interface */
191 #define DRV_NAME "janz-ican3"
193 /* DPM Control Registers -- starts at offset 0x100 in the MODULbus registers */
206 /* write-only: reset all hardware on the module */
210 /* write-only: generate an interrupt to the TPU */
227 struct janz_cmodio_onboard_regs __iomem *ctrl; member
295 iowrite8(page, &mod->dpmctrl->window_address); in ican3_set_page()
299 * ICAN3 "old-style" host interface
303 * Receive a message from the ICAN3 "old-style" firmware interface
305 * LOCKING: must hold mod->lock
307 * returns 0 on success, -ENOMEM when no message exists
316 peer = ioread8(mod->dpm + MSYNC_PEER); in ican3_old_recv_msg()
317 locl = ioread8(mod->dpm + MSYNC_LOCL); in ican3_old_recv_msg()
321 netdev_dbg(mod->ndev, "no mbox for reading\n"); in ican3_old_recv_msg()
322 return -ENOMEM; in ican3_old_recv_msg()
334 memcpy_fromio(msg, mod->dpm, sizeof(*msg)); in ican3_old_recv_msg()
343 iowrite8(locl, mod->dpm + MSYNC_LOCL); in ican3_old_recv_msg()
348 * Send a message through the "old-style" firmware interface
350 * LOCKING: must hold mod->lock
352 * returns 0 on success, -ENOMEM when no free space exists
361 peer = ioread8(mod->dpm + MSYNC_PEER); in ican3_old_send_msg()
362 locl = ioread8(mod->dpm + MSYNC_LOCL); in ican3_old_send_msg()
366 netdev_err(mod->ndev, "no mbox for writing\n"); in ican3_old_send_msg()
367 return -ENOMEM; in ican3_old_send_msg()
376 memcpy_toio(mod->dpm, msg, sizeof(*msg)); in ican3_old_send_msg()
383 iowrite8(locl, mod->dpm + MSYNC_LOCL); in ican3_old_send_msg()
388 * ICAN3 "new-style" Host Interface Setup
398 spin_lock_irqsave(&mod->lock, flags); in ican3_init_new_host_interface()
401 mod->rx_num = 0; in ican3_init_new_host_interface()
402 mod->rx_int = 0; in ican3_init_new_host_interface()
406 dst = mod->dpm; in ican3_init_new_host_interface()
408 /* initialize the tohost (rx) queue descriptors: pages 9-24 */ in ican3_init_new_host_interface()
411 desc.pointer = mod->free_page; in ican3_init_new_host_interface()
414 if (i == ICAN3_NEW_BUFFERS - 1) in ican3_init_new_host_interface()
419 mod->free_page++; in ican3_init_new_host_interface()
424 dst = mod->dpm; in ican3_init_new_host_interface()
427 mod->tx_num = 0; in ican3_init_new_host_interface()
429 /* initialize the fromhost mid queue descriptors: pages 25-40 */ in ican3_init_new_host_interface()
432 desc.pointer = mod->free_page; in ican3_init_new_host_interface()
435 if (i == ICAN3_NEW_BUFFERS - 1) in ican3_init_new_host_interface()
440 mod->free_page++; in ican3_init_new_host_interface()
445 dst = mod->dpm; in ican3_init_new_host_interface()
447 /* initialize only a single buffer in the fromhost hi queue (unused) */ in ican3_init_new_host_interface()
449 desc.pointer = mod->free_page; in ican3_init_new_host_interface()
451 mod->free_page++; in ican3_init_new_host_interface()
455 dst = mod->dpm; in ican3_init_new_host_interface()
457 /* initialize only a single buffer in the fromhost low queue (unused) */ in ican3_init_new_host_interface()
459 desc.pointer = mod->free_page; in ican3_init_new_host_interface()
461 mod->free_page++; in ican3_init_new_host_interface()
463 spin_unlock_irqrestore(&mod->lock, flags); in ican3_init_new_host_interface()
478 spin_lock_irqsave(&mod->lock, flags); in ican3_init_fast_host_interface()
481 mod->fastrx_start = mod->free_page; in ican3_init_fast_host_interface()
482 mod->fastrx_num = 0; in ican3_init_fast_host_interface()
484 /* build a single fast tohost queue descriptor */ in ican3_init_fast_host_interface()
494 if (i == ICAN3_RX_BUFFERS - 1) in ican3_init_fast_host_interface()
498 ican3_set_page(mod, mod->free_page); in ican3_init_fast_host_interface()
501 dst = mod->dpm + addr; in ican3_init_fast_host_interface()
508 mod->free_page++; in ican3_init_fast_host_interface()
512 /* make sure we page-align the next queue */ in ican3_init_fast_host_interface()
514 mod->free_page++; in ican3_init_fast_host_interface()
517 mod->fasttx_start = mod->free_page; in ican3_init_fast_host_interface()
518 mod->fasttx_num = 0; in ican3_init_fast_host_interface()
520 /* build a single fast fromhost queue descriptor */ in ican3_init_fast_host_interface()
530 if (i == ICAN3_TX_BUFFERS - 1) in ican3_init_fast_host_interface()
534 ican3_set_page(mod, mod->free_page); in ican3_init_fast_host_interface()
537 dst = mod->dpm + addr; in ican3_init_fast_host_interface()
544 mod->free_page++; in ican3_init_fast_host_interface()
548 spin_unlock_irqrestore(&mod->lock, flags); in ican3_init_fast_host_interface()
552 * ICAN3 "new-style" Host Interface Message Helpers
556 * LOCKING: must hold mod->lock
561 void __iomem *desc_addr = mod->dpm + (mod->tx_num * sizeof(desc)); in ican3_new_send_msg()
568 netdev_dbg(mod->ndev, "%s: no free buffers\n", __func__); in ican3_new_send_msg()
569 return -ENOMEM; in ican3_new_send_msg()
574 memcpy_toio(mod->dpm, msg, sizeof(*msg)); in ican3_new_send_msg()
582 mod->tx_num = (desc.control & DESC_WRAP) ? 0 : (mod->tx_num + 1); in ican3_new_send_msg()
587 * LOCKING: must hold mod->lock
592 void __iomem *desc_addr = mod->dpm + (mod->rx_num * sizeof(desc)); in ican3_new_recv_msg()
599 netdev_dbg(mod->ndev, "%s: no buffers to recv\n", __func__); in ican3_new_recv_msg()
600 return -ENOMEM; in ican3_new_recv_msg()
605 memcpy_fromio(msg, mod->dpm, sizeof(*msg)); in ican3_new_recv_msg()
613 mod->rx_num = (desc.control & DESC_WRAP) ? 0 : (mod->rx_num + 1); in ican3_new_recv_msg()
626 spin_lock_irqsave(&mod->lock, flags); in ican3_send_msg()
628 if (mod->iftype == 0) in ican3_send_msg()
633 spin_unlock_irqrestore(&mod->lock, flags); in ican3_send_msg()
642 spin_lock_irqsave(&mod->lock, flags); in ican3_recv_msg()
644 if (mod->iftype == 0) in ican3_recv_msg()
649 spin_unlock_irqrestore(&mod->lock, flags); in ican3_recv_msg()
654 * Quick Pre-constructed Messages
689 WARN_ON(mod->iftype != 0); in ican3_msg_newhostif()
696 mod->iftype = 1; in ican3_msg_newhostif()
710 addr = DPM_PAGE_ADDR(mod->fastrx_start); in ican3_msg_fasthostif()
717 addr = DPM_PAGE_ADDR(mod->fasttx_start); in ican3_msg_fasthostif()
724 WARN_ON(mod->iftype != 1); in ican3_msg_fasthostif()
758 msg.data[0] = 0; /* MUX = 0 */ in ican3_set_id_filter()
779 struct can_bittiming *bt = &mod->can.bittiming; in ican3_set_bus_state()
787 btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); in ican3_set_bus_state()
788 btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | in ican3_set_bus_state()
789 (((bt->phase_seg2 - 1) & 0x7) << 4); in ican3_set_bus_state()
790 if (mod->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) in ican3_set_bus_state()
793 if (mod->fwtype == ICAN3_FWTYPE_ICANOS) { in ican3_set_bus_state()
809 /* can-on/off request */ in ican3_set_bus_state()
816 } else if (mod->fwtype == ICAN3_FWTYPE_CAL_CANOPEN) { in ican3_set_bus_state()
817 /* bittiming + can-on/off request */ in ican3_set_bus_state()
837 * class 2 (with error capability, see CiA/DS203-1) in ican3_set_bus_state()
853 return -ENOTSUPP; in ican3_set_bus_state()
886 if (mod->fwtype == ICAN3_FWTYPE_ICANOS) { in ican3_set_buserror()
892 } else if (mod->fwtype == ICAN3_FWTYPE_CAL_CANOPEN) { in ican3_set_buserror()
901 return -ENOTSUPP; in ican3_set_buserror()
914 if ((desc->command & ICAN3_CAN_TYPE_MASK) == ICAN3_CAN_TYPE_SFF) { in ican3_to_can_frame()
915 if (desc->data[1] & ICAN3_SFF_RTR) in ican3_to_can_frame()
916 cf->can_id |= CAN_RTR_FLAG; in ican3_to_can_frame()
918 cf->can_id |= desc->data[0] << 3; in ican3_to_can_frame()
919 cf->can_id |= (desc->data[1] & 0xe0) >> 5; in ican3_to_can_frame()
920 cf->len = can_cc_dlc2len(desc->data[1] & ICAN3_CAN_DLC_MASK); in ican3_to_can_frame()
921 memcpy(cf->data, &desc->data[2], cf->len); in ican3_to_can_frame()
923 cf->len = can_cc_dlc2len(desc->data[0] & ICAN3_CAN_DLC_MASK); in ican3_to_can_frame()
924 if (desc->data[0] & ICAN3_EFF_RTR) in ican3_to_can_frame()
925 cf->can_id |= CAN_RTR_FLAG; in ican3_to_can_frame()
927 if (desc->data[0] & ICAN3_EFF) { in ican3_to_can_frame()
928 cf->can_id |= CAN_EFF_FLAG; in ican3_to_can_frame()
929 cf->can_id |= desc->data[2] << 21; /* 28-21 */ in ican3_to_can_frame()
930 cf->can_id |= desc->data[3] << 13; /* 20-13 */ in ican3_to_can_frame()
931 cf->can_id |= desc->data[4] << 5; /* 12-5 */ in ican3_to_can_frame()
932 cf->can_id |= (desc->data[5] & 0xf8) >> 3; in ican3_to_can_frame()
934 cf->can_id |= desc->data[2] << 3; /* 10-3 */ in ican3_to_can_frame()
935 cf->can_id |= desc->data[3] >> 5; /* 2-0 */ in ican3_to_can_frame()
938 memcpy(cf->data, &desc->data[6], cf->len); in ican3_to_can_frame()
947 memset(desc->data, 0, sizeof(desc->data)); in can_frame_to_ican3()
950 desc->command = ICAN3_CAN_TYPE_EFF; in can_frame_to_ican3()
951 desc->data[0] |= cf->len; in can_frame_to_ican3()
952 desc->data[1] |= ICAN3_ECHO; in can_frame_to_ican3()
954 /* support single transmission (no retries) mode */ in can_frame_to_ican3()
955 if (mod->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) in can_frame_to_ican3()
956 desc->data[1] |= ICAN3_SNGL; in can_frame_to_ican3()
958 if (cf->can_id & CAN_RTR_FLAG) in can_frame_to_ican3()
959 desc->data[0] |= ICAN3_EFF_RTR; in can_frame_to_ican3()
962 if (cf->can_id & CAN_EFF_FLAG) { in can_frame_to_ican3()
963 desc->data[0] |= ICAN3_EFF; in can_frame_to_ican3()
964 desc->data[2] = (cf->can_id & 0x1fe00000) >> 21; /* 28-21 */ in can_frame_to_ican3()
965 desc->data[3] = (cf->can_id & 0x001fe000) >> 13; /* 20-13 */ in can_frame_to_ican3()
966 desc->data[4] = (cf->can_id & 0x00001fe0) >> 5; /* 12-5 */ in can_frame_to_ican3()
967 desc->data[5] = (cf->can_id & 0x0000001f) << 3; /* 4-0 */ in can_frame_to_ican3()
969 desc->data[2] = (cf->can_id & 0x7F8) >> 3; /* bits 10-3 */ in can_frame_to_ican3()
970 desc->data[3] = (cf->can_id & 0x007) << 5; /* bits 2-0 */ in can_frame_to_ican3()
974 memcpy(&desc->data[6], cf->data, cf->len); in can_frame_to_ican3()
988 netdev_dbg(mod->ndev, "IDVERS response: %s\n", msg->data); in ican3_handle_idvers()
993 struct net_device *dev = mod->ndev; in ican3_handle_msglost()
994 struct net_device_stats *stats = &dev->stats; in ican3_handle_msglost()
1003 if (msg->spec == MSG_MSGLOST) { in ican3_handle_msglost()
1004 netdev_err(mod->ndev, "lost %d control messages\n", msg->data[0]); in ican3_handle_msglost()
1018 cf->can_id |= CAN_ERR_CRTL; in ican3_handle_msglost()
1019 cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; in ican3_handle_msglost()
1020 stats->rx_over_errors++; in ican3_handle_msglost()
1021 stats->rx_errors++; in ican3_handle_msglost()
1035 struct net_device *dev = mod->ndev; in ican3_handle_cevtind()
1036 struct net_device_stats *stats = &dev->stats; in ican3_handle_cevtind()
1037 enum can_state state = mod->can.state; in ican3_handle_cevtind()
1043 if (msg->data[1] != CEVTIND_CHIP_SJA1000) { in ican3_handle_cevtind()
1044 netdev_err(mod->ndev, "unable to handle errors on non-SJA1000\n"); in ican3_handle_cevtind()
1045 return -ENODEV; in ican3_handle_cevtind()
1049 if (le16_to_cpu(msg->len) < 6) { in ican3_handle_cevtind()
1050 netdev_err(mod->ndev, "error message too short\n"); in ican3_handle_cevtind()
1051 return -EINVAL; in ican3_handle_cevtind()
1054 isrc = msg->data[0]; in ican3_handle_cevtind()
1055 ecc = msg->data[2]; in ican3_handle_cevtind()
1056 status = msg->data[3]; in ican3_handle_cevtind()
1057 rxerr = msg->data[4]; in ican3_handle_cevtind()
1058 txerr = msg->data[5]; in ican3_handle_cevtind()
1072 netdev_dbg(mod->ndev, "bus error interrupt\n"); in ican3_handle_cevtind()
1076 kfree_skb(skb_dequeue(&mod->echoq)); in ican3_handle_cevtind()
1077 stats->tx_errors++; in ican3_handle_cevtind()
1079 stats->rx_errors++; in ican3_handle_cevtind()
1083 * The controller automatically disables bus-error interrupts in ican3_handle_cevtind()
1084 * and therefore we must re-enable them. in ican3_handle_cevtind()
1088 netdev_err(mod->ndev, "unable to re-enable bus-error\n"); in ican3_handle_cevtind()
1093 if (!(mod->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) in ican3_handle_cevtind()
1099 return -ENOMEM; in ican3_handle_cevtind()
1103 netdev_dbg(mod->ndev, "data overrun interrupt\n"); in ican3_handle_cevtind()
1104 cf->can_id |= CAN_ERR_CRTL; in ican3_handle_cevtind()
1105 cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; in ican3_handle_cevtind()
1106 stats->rx_over_errors++; in ican3_handle_cevtind()
1107 stats->rx_errors++; in ican3_handle_cevtind()
1112 netdev_dbg(mod->ndev, "error warning + passive interrupt\n"); in ican3_handle_cevtind()
1115 cf->can_id |= CAN_ERR_BUSOFF; in ican3_handle_cevtind()
1116 mod->can.can_stats.bus_off++; in ican3_handle_cevtind()
1130 mod->can.can_stats.bus_error++; in ican3_handle_cevtind()
1131 cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT; in ican3_handle_cevtind()
1135 cf->data[2] |= CAN_ERR_PROT_BIT; in ican3_handle_cevtind()
1138 cf->data[2] |= CAN_ERR_PROT_FORM; in ican3_handle_cevtind()
1141 cf->data[2] |= CAN_ERR_PROT_STUFF; in ican3_handle_cevtind()
1144 cf->data[3] = ecc & ECC_SEG; in ican3_handle_cevtind()
1149 cf->data[2] |= CAN_ERR_PROT_TX; in ican3_handle_cevtind()
1151 cf->data[6] = txerr; in ican3_handle_cevtind()
1152 cf->data[7] = rxerr; in ican3_handle_cevtind()
1155 if (state != mod->can.state && (state == CAN_STATE_ERROR_WARNING || in ican3_handle_cevtind()
1157 cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT; in ican3_handle_cevtind()
1159 mod->can.can_stats.error_warning++; in ican3_handle_cevtind()
1160 cf->data[1] = (txerr > rxerr) ? in ican3_handle_cevtind()
1164 mod->can.can_stats.error_passive++; in ican3_handle_cevtind()
1165 cf->data[1] = (txerr > rxerr) ? in ican3_handle_cevtind()
1170 cf->data[6] = txerr; in ican3_handle_cevtind()
1171 cf->data[7] = rxerr; in ican3_handle_cevtind()
1174 mod->can.state = state; in ican3_handle_cevtind()
1181 switch (msg->data[0]) { in ican3_handle_inquiry()
1184 mod->bec.rxerr = msg->data[5]; in ican3_handle_inquiry()
1185 mod->bec.txerr = msg->data[6]; in ican3_handle_inquiry()
1186 complete(&mod->buserror_comp); in ican3_handle_inquiry()
1189 mod->termination_enabled = msg->data[6] & HWCONF_TERMINATE_ON; in ican3_handle_inquiry()
1190 complete(&mod->termination_comp); in ican3_handle_inquiry()
1193 netdev_err(mod->ndev, "received an unknown inquiry response\n"); in ican3_handle_inquiry()
1203 subspec = msg->data[0] + msg->data[1] * 0x100; in ican3_handle_nmtsind()
1205 switch (msg->data[2]) { in ican3_handle_nmtsind()
1211 le16_add_cpu(&msg->len, -3); in ican3_handle_nmtsind()
1212 memmove(msg->data, msg->data + 3, le16_to_cpu(msg->len)); in ican3_handle_nmtsind()
1220 netdev_warn(mod->ndev, "unknown NMTS event indication %x\n", in ican3_handle_nmtsind()
1221 msg->data[2]); in ican3_handle_nmtsind()
1227 netdev_warn(mod->ndev, "unhandled NMTS indication %x\n", in ican3_handle_nmtsind()
1236 netdev_warn(mod->ndev, "received unknown message: spec 0x%.2x length %d\n", in ican3_handle_unknown_message()
1237 msg->spec, le16_to_cpu(msg->len)); in ican3_handle_unknown_message()
1245 netdev_dbg(mod->ndev, "%s: modno %d spec 0x%.2x len %d bytes\n", __func__, in ican3_handle_message()
1246 mod->num, msg->spec, le16_to_cpu(msg->len)); in ican3_handle_message()
1248 switch (msg->spec) { in ican3_handle_message()
1284 skb_queue_tail(&mod->echoq, skb); in ican3_put_echo_skb()
1289 struct sk_buff *skb = skb_dequeue(&mod->echoq); in ican3_get_echo_skb()
1295 netdev_err(mod->ndev, "BUG: echo skb not occupied\n"); in ican3_get_echo_skb()
1299 cf = (struct can_frame *)skb->data; in ican3_get_echo_skb()
1300 if (!(cf->can_id & CAN_RTR_FLAG)) in ican3_get_echo_skb()
1301 dlc = cf->len; in ican3_get_echo_skb()
1304 if (skb->pkt_type != PACKET_LOOPBACK) { in ican3_get_echo_skb()
1309 skb->protocol = htons(ETH_P_CAN); in ican3_get_echo_skb()
1310 skb->pkt_type = PACKET_BROADCAST; in ican3_get_echo_skb()
1311 skb->ip_summed = CHECKSUM_UNNECESSARY; in ican3_get_echo_skb()
1312 skb->dev = mod->ndev; in ican3_get_echo_skb()
1328 struct can_frame *cf = (struct can_frame *)skb->data; in ican3_echo_skb_matches()
1329 struct sk_buff *echo_skb = skb_peek(&mod->echoq); in ican3_echo_skb_matches()
1335 echo_cf = (struct can_frame *)echo_skb->data; in ican3_echo_skb_matches()
1336 if (cf->can_id != echo_cf->can_id) in ican3_echo_skb_matches()
1339 if (cf->len != echo_cf->len) in ican3_echo_skb_matches()
1342 return memcmp(cf->data, echo_cf->data, cf->len) == 0; in ican3_echo_skb_matches()
1348 * LOCKING: must hold mod->lock
1356 if (skb_queue_len(&mod->echoq) >= ICAN3_TX_BUFFERS) in ican3_txok()
1360 ican3_set_page(mod, mod->fasttx_start + (mod->fasttx_num / 16)); in ican3_txok()
1361 desc = mod->dpm + ((mod->fasttx_num % 16) * sizeof(*desc)); in ican3_txok()
1362 control = ioread8(&desc->control); in ican3_txok()
1378 struct net_device *ndev = mod->ndev; in ican3_recv_skb()
1379 struct net_device_stats *stats = &ndev->stats; in ican3_recv_skb()
1386 spin_lock_irqsave(&mod->lock, flags); in ican3_recv_skb()
1389 ican3_set_page(mod, mod->fastrx_start + (mod->fastrx_num / 16)); in ican3_recv_skb()
1390 desc_addr = mod->dpm + ((mod->fastrx_num % 16) * sizeof(desc)); in ican3_recv_skb()
1393 spin_unlock_irqrestore(&mod->lock, flags); in ican3_recv_skb()
1397 return -ENOBUFS; in ican3_recv_skb()
1402 stats->rx_dropped++; in ican3_recv_skb()
1420 stats->tx_packets++; in ican3_recv_skb()
1421 stats->tx_bytes += ican3_get_echo_skb(mod); in ican3_recv_skb()
1427 stats->rx_packets++; in ican3_recv_skb()
1428 if (!(cf->can_id & CAN_RTR_FLAG)) in ican3_recv_skb()
1429 stats->rx_bytes += cf->len; in ican3_recv_skb()
1436 spin_lock_irqsave(&mod->lock, flags); in ican3_recv_skb()
1438 ican3_set_page(mod, mod->fastrx_start + (mod->fastrx_num / 16)); in ican3_recv_skb()
1442 mod->fastrx_num = (desc.control & DESC_WRAP) ? 0 in ican3_recv_skb()
1443 : (mod->fastrx_num + 1); in ican3_recv_skb()
1446 spin_unlock_irqrestore(&mod->lock, flags); in ican3_recv_skb()
1481 spin_lock_irqsave(&mod->lock, flags); in ican3_napi()
1484 if (netif_queue_stopped(mod->ndev) && ican3_txok(mod)) in ican3_napi()
1485 netif_wake_queue(mod->ndev); in ican3_napi()
1487 spin_unlock_irqrestore(&mod->lock, flags); in ican3_napi()
1489 /* re-enable interrupt generation */ in ican3_napi()
1490 iowrite8(1 << mod->num, &mod->ctrl->int_enable); in ican3_napi()
1503 stat = ioread8(&mod->ctrl->int_disable) & (1 << mod->num); in ican3_irq()
1504 if (stat == (1 << mod->num)) in ican3_irq()
1508 ioread8(&mod->dpmctrl->interrupt); in ican3_irq()
1511 iowrite8(1 << mod->num, &mod->ctrl->int_disable); in ican3_irq()
1512 napi_schedule(&mod->napi); in ican3_irq()
1521 * Reset an ICAN module to its power-on state
1531 iowrite8(1 << mod->num, &mod->ctrl->int_disable); in ican3_reset_module()
1534 mod->free_page = DPM_FREE_START; in ican3_reset_module()
1537 runold = ioread8(mod->dpm + TARGET_RUNNING); in ican3_reset_module()
1540 iowrite8(0x00, &mod->dpmctrl->hwreset); in ican3_reset_module()
1546 runnew = ioread8(mod->dpm + TARGET_RUNNING); in ican3_reset_module()
1553 netdev_err(mod->ndev, "failed to reset CAN module\n"); in ican3_reset_module()
1554 return -ETIMEDOUT; in ican3_reset_module()
1572 netdev_err(mod->ndev, "unable to reset module\n"); in ican3_startup_module()
1577 memcpy_fromio(mod->fwinfo, mod->dpm + FIRMWARE_STAMP, sizeof(mod->fwinfo) - 1); in ican3_startup_module()
1578 if (strncmp(mod->fwinfo, "JANZ-ICAN3", 10)) { in ican3_startup_module()
1579 netdev_err(mod->ndev, "ICAN3 not detected (found %s)\n", mod->fwinfo); in ican3_startup_module()
1580 return -ENODEV; in ican3_startup_module()
1582 if (strstr(mod->fwinfo, "CAL/CANopen")) in ican3_startup_module()
1583 mod->fwtype = ICAN3_FWTYPE_CAL_CANOPEN; in ican3_startup_module()
1585 mod->fwtype = ICAN3_FWTYPE_ICANOS; in ican3_startup_module()
1587 /* re-enable interrupts so we can send messages */ in ican3_startup_module()
1588 iowrite8(1 << mod->num, &mod->ctrl->int_enable); in ican3_startup_module()
1592 netdev_err(mod->ndev, "unable to connect to module\n"); in ican3_startup_module()
1599 netdev_err(mod->ndev, "unable to switch to new-style interface\n"); in ican3_startup_module()
1606 netdev_err(mod->ndev, "unable to enable termination\n"); in ican3_startup_module()
1613 netdev_err(mod->ndev, "unable to set bus-error\n"); in ican3_startup_module()
1620 netdev_err(mod->ndev, "unable to switch to fast host interface\n"); in ican3_startup_module()
1626 netdev_err(mod->ndev, "unable to set acceptance filter\n"); in ican3_startup_module()
1645 netdev_err(mod->ndev, "unable to start CAN layer\n"); in ican3_open()
1652 netdev_err(mod->ndev, "unable to set bus-on\n"); in ican3_open()
1658 mod->can.state = CAN_STATE_ERROR_ACTIVE; in ican3_open()
1671 mod->can.state = CAN_STATE_STOPPED; in ican3_stop()
1676 netdev_err(mod->ndev, "unable to set bus-off\n"); in ican3_stop()
1681 skb_queue_purge(&mod->echoq); in ican3_stop()
1691 struct can_frame *cf = (struct can_frame *)skb->data; in ican3_xmit()
1699 spin_lock_irqsave(&mod->lock, flags); in ican3_xmit()
1703 netdev_err(mod->ndev, "BUG: no free descriptors\n"); in ican3_xmit()
1704 spin_unlock_irqrestore(&mod->lock, flags); in ican3_xmit()
1709 ican3_set_page(mod, mod->fasttx_start + (mod->fasttx_num / 16)); in ican3_xmit()
1710 desc_addr = mod->dpm + ((mod->fasttx_num % 16) * sizeof(desc)); in ican3_xmit()
1718 * This hardware doesn't have TX-done notifications, so we'll try and in ican3_xmit()
1734 iowrite8(0x01, &mod->dpmctrl->interrupt); in ican3_xmit()
1740 mod->fasttx_num = (desc.control & DESC_WRAP) ? 0 in ican3_xmit()
1741 : (mod->fasttx_num + 1); in ican3_xmit()
1747 spin_unlock_irqrestore(&mod->lock, flags); in ican3_xmit()
1763 * Low-level CAN Device
1785 return -ENOTSUPP; in ican3_set_mode()
1790 netdev_err(ndev, "unable to set bus-on\n"); in ican3_set_mode()
1795 mod->can.state = CAN_STATE_ERROR_ACTIVE; in ican3_set_mode()
1813 if (!wait_for_completion_timeout(&mod->buserror_comp, HZ)) { in ican3_get_berr_counter()
1814 netdev_info(mod->ndev, "%s timed out\n", __func__); in ican3_get_berr_counter()
1815 return -ETIMEDOUT; in ican3_get_berr_counter()
1818 bec->rxerr = mod->bec.rxerr; in ican3_get_berr_counter()
1819 bec->txerr = mod->bec.txerr; in ican3_get_berr_counter()
1838 if (!wait_for_completion_timeout(&mod->termination_comp, HZ)) { in termination_show()
1839 netdev_info(mod->ndev, "%s timed out\n", __func__); in termination_show()
1840 return -ETIMEDOUT; in termination_show()
1843 return sysfs_emit(buf, "%u\n", mod->termination_enabled); in termination_show()
1855 return -EINVAL; in termination_store()
1870 return scnprintf(buf, PAGE_SIZE, "%s\n", mod->fwinfo); in fwinfo_show()
1899 pdata = dev_get_platdata(&pdev->dev); in ican3_probe()
1901 return -ENXIO; in ican3_probe()
1903 dev_dbg(&pdev->dev, "probe: module number %d\n", pdata->modno); in ican3_probe()
1906 dev = &pdev->dev; in ican3_probe()
1912 ret = -ENOMEM; in ican3_probe()
1918 mod->ndev = ndev; in ican3_probe()
1919 mod->num = pdata->modno; in ican3_probe()
1920 netif_napi_add_weight(ndev, &mod->napi, ican3_napi, ICAN3_RX_BUFFERS); in ican3_probe()
1921 skb_queue_head_init(&mod->echoq); in ican3_probe()
1922 spin_lock_init(&mod->lock); in ican3_probe()
1923 init_completion(&mod->termination_comp); in ican3_probe()
1924 init_completion(&mod->buserror_comp); in ican3_probe()
1926 /* setup device-specific sysfs attributes */ in ican3_probe()
1927 ndev->sysfs_groups[0] = &ican3_sysfs_attr_group; in ican3_probe()
1930 mod->free_page = DPM_FREE_START; in ican3_probe()
1932 ndev->netdev_ops = &ican3_netdev_ops; in ican3_probe()
1933 ndev->ethtool_ops = &ican3_ethtool_ops; in ican3_probe()
1934 ndev->flags |= IFF_ECHO; in ican3_probe()
1935 SET_NETDEV_DEV(ndev, &pdev->dev); in ican3_probe()
1937 mod->can.clock.freq = ICAN3_CAN_CLOCK; in ican3_probe()
1938 mod->can.bittiming_const = &ican3_bittiming_const; in ican3_probe()
1939 mod->can.do_set_mode = ican3_set_mode; in ican3_probe()
1940 mod->can.do_get_berr_counter = ican3_get_berr_counter; in ican3_probe()
1941 mod->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES in ican3_probe()
1946 mod->irq = platform_get_irq(pdev, 0); in ican3_probe()
1947 if (mod->irq < 0) { in ican3_probe()
1948 ret = -ENODEV; in ican3_probe()
1952 ndev->irq = mod->irq; in ican3_probe()
1958 ret = -ENODEV; in ican3_probe()
1962 mod->dpm = ioremap(res->start, resource_size(res)); in ican3_probe()
1963 if (!mod->dpm) { in ican3_probe()
1965 ret = -ENOMEM; in ican3_probe()
1969 mod->dpmctrl = mod->dpm + DPM_PAGE_SIZE; in ican3_probe()
1975 ret = -ENODEV; in ican3_probe()
1979 mod->ctrl = ioremap(res->start, resource_size(res)); in ican3_probe()
1980 if (!mod->ctrl) { in ican3_probe()
1982 ret = -ENOMEM; in ican3_probe()
1987 iowrite8(1 << mod->num, &mod->ctrl->int_disable); in ican3_probe()
1988 ret = request_irq(mod->irq, ican3_irq, IRQF_SHARED, DRV_NAME, mod); in ican3_probe()
1995 napi_enable(&mod->napi); in ican3_probe()
2009 netdev_info(mod->ndev, "module %d: registered CAN device\n", pdata->modno); in ican3_probe()
2013 napi_disable(&mod->napi); in ican3_probe()
2014 iowrite8(1 << mod->num, &mod->ctrl->int_disable); in ican3_probe()
2015 free_irq(mod->irq, mod); in ican3_probe()
2017 iounmap(mod->ctrl); in ican3_probe()
2019 iounmap(mod->dpm); in ican3_probe()
2033 napi_disable(&mod->napi); in ican3_remove()
2034 iowrite8(1 << mod->num, &mod->ctrl->int_disable); in ican3_remove()
2035 free_irq(mod->irq, mod); in ican3_remove()
2041 iounmap(mod->ctrl); in ican3_remove()
2042 iounmap(mod->dpm); in ican3_remove()
2058 MODULE_DESCRIPTION("Janz MODULbus VMOD-ICAN3 Driver");
2060 MODULE_ALIAS("platform:janz-ican3");