Lines Matching refs:cl

17 int ishtp_cl_get_tx_free_buffer_size(struct ishtp_cl *cl)  in ishtp_cl_get_tx_free_buffer_size()  argument
22 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); in ishtp_cl_get_tx_free_buffer_size()
23 size = cl->tx_ring_free_size * cl->device->fw_client->props.max_msg_length; in ishtp_cl_get_tx_free_buffer_size()
24 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags); in ishtp_cl_get_tx_free_buffer_size()
30 int ishtp_cl_get_tx_free_rings(struct ishtp_cl *cl) in ishtp_cl_get_tx_free_rings() argument
32 return cl->tx_ring_free_size; in ishtp_cl_get_tx_free_rings()
42 static void ishtp_read_list_flush(struct ishtp_cl *cl) in ishtp_read_list_flush() argument
48 spin_lock_irqsave(&cl->dev->read_list_spinlock, flags); in ishtp_read_list_flush()
49 list_for_each_entry_safe(rb, next, &cl->dev->read_list.list, list) in ishtp_read_list_flush()
50 if (rb->cl && ishtp_cl_cmp_id(cl, rb->cl)) { in ishtp_read_list_flush()
54 spin_unlock_irqrestore(&cl->dev->read_list_spinlock, flags); in ishtp_read_list_flush()
66 int ishtp_cl_flush_queues(struct ishtp_cl *cl) in ishtp_cl_flush_queues() argument
68 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_flush_queues()
71 ishtp_read_list_flush(cl); in ishtp_cl_flush_queues()
85 static void ishtp_cl_init(struct ishtp_cl *cl, struct ishtp_device *dev) in ishtp_cl_init() argument
87 memset(cl, 0, sizeof(struct ishtp_cl)); in ishtp_cl_init()
88 init_waitqueue_head(&cl->wait_ctrl_res); in ishtp_cl_init()
89 spin_lock_init(&cl->free_list_spinlock); in ishtp_cl_init()
90 spin_lock_init(&cl->in_process_spinlock); in ishtp_cl_init()
91 spin_lock_init(&cl->tx_list_spinlock); in ishtp_cl_init()
92 spin_lock_init(&cl->tx_free_list_spinlock); in ishtp_cl_init()
93 spin_lock_init(&cl->fc_spinlock); in ishtp_cl_init()
94 INIT_LIST_HEAD(&cl->link); in ishtp_cl_init()
95 cl->dev = dev; in ishtp_cl_init()
97 INIT_LIST_HEAD(&cl->free_rb_list.list); in ishtp_cl_init()
98 INIT_LIST_HEAD(&cl->tx_list.list); in ishtp_cl_init()
99 INIT_LIST_HEAD(&cl->tx_free_list.list); in ishtp_cl_init()
100 INIT_LIST_HEAD(&cl->in_process_list.list); in ishtp_cl_init()
102 cl->rx_ring_size = CL_DEF_RX_RING_SIZE; in ishtp_cl_init()
103 cl->tx_ring_size = CL_DEF_TX_RING_SIZE; in ishtp_cl_init()
104 cl->tx_ring_free_size = cl->tx_ring_size; in ishtp_cl_init()
107 cl->last_tx_path = CL_TX_PATH_IPC; in ishtp_cl_init()
108 cl->last_dma_acked = 1; in ishtp_cl_init()
109 cl->last_dma_addr = NULL; in ishtp_cl_init()
110 cl->last_ipc_acked = 1; in ishtp_cl_init()
123 struct ishtp_cl *cl; in ishtp_cl_allocate() local
125 cl = kmalloc(sizeof(struct ishtp_cl), GFP_KERNEL); in ishtp_cl_allocate()
126 if (!cl) in ishtp_cl_allocate()
129 ishtp_cl_init(cl, cl_device->ishtp_dev); in ishtp_cl_allocate()
130 return cl; in ishtp_cl_allocate()
140 void ishtp_cl_free(struct ishtp_cl *cl) in ishtp_cl_free() argument
145 if (!cl) in ishtp_cl_free()
148 dev = cl->dev; in ishtp_cl_free()
153 ishtp_cl_free_rx_ring(cl); in ishtp_cl_free()
154 ishtp_cl_free_tx_ring(cl); in ishtp_cl_free()
155 kfree(cl); in ishtp_cl_free()
171 int ishtp_cl_link(struct ishtp_cl *cl) in ishtp_cl_link() argument
177 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_link()
180 dev = cl->dev; in ishtp_cl_link()
193 dev_err(&cl->device->dev, "id exceeded %d", ISHTP_CLIENTS_MAX); in ishtp_cl_link()
198 cl->host_client_id = id; in ishtp_cl_link()
204 list_add_tail(&cl->link, &dev->cl_list); in ishtp_cl_link()
206 cl->state = ISHTP_CL_INITIALIZING; in ishtp_cl_link()
222 void ishtp_cl_unlink(struct ishtp_cl *cl) in ishtp_cl_unlink() argument
229 if (!cl || !cl->dev) in ishtp_cl_unlink()
232 dev = cl->dev; in ishtp_cl_unlink()
236 clear_bit(cl->host_client_id, dev->host_clients_map); in ishtp_cl_unlink()
247 if (cl->host_client_id == pos->host_client_id) { in ishtp_cl_unlink()
264 int ishtp_cl_disconnect(struct ishtp_cl *cl) in ishtp_cl_disconnect() argument
268 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_disconnect()
271 dev = cl->dev; in ishtp_cl_disconnect()
273 dev->print_log(dev, "%s() state %d\n", __func__, cl->state); in ishtp_cl_disconnect()
275 if (cl->state != ISHTP_CL_DISCONNECTING) { in ishtp_cl_disconnect()
280 if (ishtp_hbm_cl_disconnect_req(dev, cl)) { in ishtp_cl_disconnect()
282 dev_err(&cl->device->dev, "failed to disconnect.\n"); in ishtp_cl_disconnect()
286 wait_event_interruptible_timeout(cl->wait_ctrl_res, in ishtp_cl_disconnect()
288 cl->state == ISHTP_CL_DISCONNECTED), in ishtp_cl_disconnect()
301 if (cl->state == ISHTP_CL_DISCONNECTED) { in ishtp_cl_disconnect()
318 static bool ishtp_cl_is_other_connecting(struct ishtp_cl *cl) in ishtp_cl_is_other_connecting() argument
324 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_is_other_connecting()
327 dev = cl->dev; in ishtp_cl_is_other_connecting()
330 if ((pos->state == ISHTP_CL_CONNECTING) && (pos != cl) && in ishtp_cl_is_other_connecting()
331 cl->fw_client_id == pos->fw_client_id) { in ishtp_cl_is_other_connecting()
351 int ishtp_cl_connect(struct ishtp_cl *cl) in ishtp_cl_connect() argument
356 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_connect()
359 dev = cl->dev; in ishtp_cl_connect()
361 dev->print_log(dev, "%s() current_state = %d\n", __func__, cl->state); in ishtp_cl_connect()
363 if (ishtp_cl_is_other_connecting(cl)) { in ishtp_cl_connect()
368 if (ishtp_hbm_cl_connect_req(dev, cl)) { in ishtp_cl_connect()
373 rets = wait_event_interruptible_timeout(cl->wait_ctrl_res, in ishtp_cl_connect()
375 (cl->state == ISHTP_CL_CONNECTED || in ishtp_cl_connect()
376 cl->state == ISHTP_CL_DISCONNECTED)), in ishtp_cl_connect()
389 if (cl->state != ISHTP_CL_CONNECTED) { in ishtp_cl_connect()
395 rets = cl->status; in ishtp_cl_connect()
401 rets = ishtp_cl_device_bind(cl); in ishtp_cl_connect()
404 ishtp_cl_disconnect(cl); in ishtp_cl_connect()
408 rets = ishtp_cl_alloc_rx_ring(cl); in ishtp_cl_connect()
412 ishtp_cl_disconnect(cl); in ishtp_cl_connect()
416 rets = ishtp_cl_alloc_tx_ring(cl); in ishtp_cl_connect()
420 ishtp_cl_free_rx_ring(cl); in ishtp_cl_connect()
421 ishtp_cl_disconnect(cl); in ishtp_cl_connect()
426 rets = ishtp_cl_read_start(cl); in ishtp_cl_connect()
444 int ishtp_cl_read_start(struct ishtp_cl *cl) in ishtp_cl_read_start() argument
453 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_read_start()
456 dev = cl->dev; in ishtp_cl_read_start()
458 if (cl->state != ISHTP_CL_CONNECTED) in ishtp_cl_read_start()
464 i = ishtp_fw_cl_by_id(dev, cl->fw_client_id); in ishtp_cl_read_start()
466 dev_err(&cl->device->dev, "no such fw client %d\n", in ishtp_cl_read_start()
467 cl->fw_client_id); in ishtp_cl_read_start()
472 spin_lock_irqsave(&cl->free_list_spinlock, flags); in ishtp_cl_read_start()
473 if (list_empty(&cl->free_rb_list.list)) { in ishtp_cl_read_start()
474 dev_warn(&cl->device->dev, in ishtp_cl_read_start()
478 spin_unlock_irqrestore(&cl->free_list_spinlock, flags); in ishtp_cl_read_start()
481 rb = list_entry(cl->free_rb_list.list.next, struct ishtp_cl_rb, list); in ishtp_cl_read_start()
483 spin_unlock_irqrestore(&cl->free_list_spinlock, flags); in ishtp_cl_read_start()
485 rb->cl = cl; in ishtp_cl_read_start()
498 if (ishtp_hbm_cl_flow_control_req(dev, cl)) { in ishtp_cl_read_start()
509 spin_lock_irqsave(&cl->free_list_spinlock, flags); in ishtp_cl_read_start()
510 list_add_tail(&rb->list, &cl->free_rb_list.list); in ishtp_cl_read_start()
511 spin_unlock_irqrestore(&cl->free_list_spinlock, flags); in ishtp_cl_read_start()
528 int ishtp_cl_send(struct ishtp_cl *cl, uint8_t *buf, size_t length) in ishtp_cl_send() argument
536 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_send()
539 dev = cl->dev; in ishtp_cl_send()
541 if (cl->state != ISHTP_CL_CONNECTED) { in ishtp_cl_send()
542 ++cl->err_send_msg; in ishtp_cl_send()
547 ++cl->err_send_msg; in ishtp_cl_send()
552 id = ishtp_fw_cl_by_id(dev, cl->fw_client_id); in ishtp_cl_send()
554 ++cl->err_send_msg; in ishtp_cl_send()
559 ++cl->err_send_msg; in ishtp_cl_send()
564 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); in ishtp_cl_send()
565 if (list_empty(&cl->tx_free_list.list)) { in ishtp_cl_send()
566 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, in ishtp_cl_send()
568 ++cl->err_send_msg; in ishtp_cl_send()
572 cl_msg = list_first_entry(&cl->tx_free_list.list, in ishtp_cl_send()
575 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, in ishtp_cl_send()
585 --cl->tx_ring_free_size; in ishtp_cl_send()
587 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags); in ishtp_cl_send()
590 spin_lock_irqsave(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send()
591 have_msg_to_send = !list_empty(&cl->tx_list.list); in ishtp_cl_send()
592 list_add_tail(&cl_msg->list, &cl->tx_list.list); in ishtp_cl_send()
593 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send()
595 if (!have_msg_to_send && cl->ishtp_flow_ctrl_creds > 0) in ishtp_cl_send()
596 ishtp_cl_send_msg(dev, cl); in ishtp_cl_send()
613 struct ishtp_cl *cl = rb->cl; in ishtp_cl_read_complete() local
615 spin_lock_irqsave(&cl->in_process_spinlock, flags); in ishtp_cl_read_complete()
620 schedule_work_flag = list_empty(&cl->in_process_list.list); in ishtp_cl_read_complete()
621 list_add_tail(&rb->list, &cl->in_process_list.list); in ishtp_cl_read_complete()
622 spin_unlock_irqrestore(&cl->in_process_spinlock, flags); in ishtp_cl_read_complete()
625 ishtp_cl_bus_rx_event(cl->device); in ishtp_cl_read_complete()
638 struct ishtp_cl *cl = prm; in ipc_tx_send() local
641 struct ishtp_device *dev = (cl ? cl->dev : NULL); in ipc_tx_send()
656 if (cl->state != ISHTP_CL_CONNECTED) in ipc_tx_send()
659 spin_lock_irqsave(&cl->tx_list_spinlock, tx_flags); in ipc_tx_send()
660 if (list_empty(&cl->tx_list.list)) { in ipc_tx_send()
661 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ipc_tx_send()
665 if (cl->ishtp_flow_ctrl_creds != 1 && !cl->sending) { in ipc_tx_send()
666 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ipc_tx_send()
670 if (!cl->sending) { in ipc_tx_send()
671 --cl->ishtp_flow_ctrl_creds; in ipc_tx_send()
672 cl->last_ipc_acked = 0; in ipc_tx_send()
673 cl->last_tx_path = CL_TX_PATH_IPC; in ipc_tx_send()
674 cl->sending = 1; in ipc_tx_send()
677 cl_msg = list_entry(cl->tx_list.list.next, struct ishtp_cl_tx_ring, in ipc_tx_send()
679 rem = cl_msg->send_buf.size - cl->tx_offs; in ipc_tx_send()
682 ishtp_hdr.host_addr = cl->host_client_id; in ipc_tx_send()
683 ishtp_hdr.fw_addr = cl->fw_client_id; in ipc_tx_send()
685 pmsg = cl_msg->send_buf.data + cl->tx_offs; in ipc_tx_send()
693 cl->tx_offs = 0; in ipc_tx_send()
694 cl->sending = 0; in ipc_tx_send()
703 cl->tx_offs += dev->mtu; in ipc_tx_send()
704 rem = cl_msg->send_buf.size - cl->tx_offs; in ipc_tx_send()
709 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ipc_tx_send()
711 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); in ipc_tx_send()
712 list_add_tail(&cl_msg->list, &cl->tx_free_list.list); in ipc_tx_send()
713 ++cl->tx_ring_free_size; in ipc_tx_send()
714 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, in ipc_tx_send()
726 struct ishtp_cl *cl) in ishtp_cl_send_msg_ipc() argument
729 if (cl->last_tx_path == CL_TX_PATH_DMA && cl->last_dma_acked == 0) in ishtp_cl_send_msg_ipc()
732 cl->tx_offs = 0; in ishtp_cl_send_msg_ipc()
733 ipc_tx_send(cl); in ishtp_cl_send_msg_ipc()
734 ++cl->send_msg_cnt_ipc; in ishtp_cl_send_msg_ipc()
745 struct ishtp_cl *cl) in ishtp_cl_send_msg_dma() argument
755 if (cl->last_tx_path == CL_TX_PATH_IPC && cl->last_ipc_acked == 0) in ishtp_cl_send_msg_dma()
758 spin_lock_irqsave(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send_msg_dma()
759 if (list_empty(&cl->tx_list.list)) { in ishtp_cl_send_msg_dma()
760 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send_msg_dma()
764 cl_msg = list_entry(cl->tx_list.list.next, struct ishtp_cl_tx_ring, in ishtp_cl_send_msg_dma()
769 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send_msg_dma()
771 ishtp_cl_send_msg_ipc(dev, cl); in ishtp_cl_send_msg_dma()
776 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send_msg_dma()
778 --cl->ishtp_flow_ctrl_creds; in ishtp_cl_send_msg_dma()
779 cl->last_dma_acked = 0; in ishtp_cl_send_msg_dma()
780 cl->last_dma_addr = msg_addr; in ishtp_cl_send_msg_dma()
781 cl->last_tx_path = CL_TX_PATH_DMA; in ishtp_cl_send_msg_dma()
798 dma_xfer.fw_client_id = cl->fw_client_id; in ishtp_cl_send_msg_dma()
799 dma_xfer.host_client_id = cl->host_client_id; in ishtp_cl_send_msg_dma()
805 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); in ishtp_cl_send_msg_dma()
806 list_add_tail(&cl_msg->list, &cl->tx_free_list.list); in ishtp_cl_send_msg_dma()
807 ++cl->tx_ring_free_size; in ishtp_cl_send_msg_dma()
808 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags); in ishtp_cl_send_msg_dma()
809 ++cl->send_msg_cnt_dma; in ishtp_cl_send_msg_dma()
819 void ishtp_cl_send_msg(struct ishtp_device *dev, struct ishtp_cl *cl) in ishtp_cl_send_msg() argument
822 ishtp_cl_send_msg_dma(dev, cl); in ishtp_cl_send_msg()
824 ishtp_cl_send_msg_ipc(dev, cl); in ishtp_cl_send_msg()
838 struct ishtp_cl *cl; in recv_ishtp_cl_msg() local
858 cl = rb->cl; in recv_ishtp_cl_msg()
859 if (!cl || !(cl->host_client_id == ishtp_hdr->host_addr && in recv_ishtp_cl_msg()
860 cl->fw_client_id == ishtp_hdr->fw_addr) || in recv_ishtp_cl_msg()
861 !(cl->state == ISHTP_CL_CONNECTED)) in recv_ishtp_cl_msg()
867 dev_err(&cl->device->dev, in recv_ishtp_cl_msg()
871 cl->status = -ENOMEM; in recv_ishtp_cl_msg()
883 dev_err(&cl->device->dev, in recv_ishtp_cl_msg()
889 cl->status = -EIO; in recv_ishtp_cl_msg()
899 cl->status = 0; in recv_ishtp_cl_msg()
903 --cl->out_flow_ctrl_creds; in recv_ishtp_cl_msg()
908 spin_lock(&cl->free_list_spinlock); in recv_ishtp_cl_msg()
910 if (!list_empty(&cl->free_rb_list.list)) { in recv_ishtp_cl_msg()
911 new_rb = list_entry(cl->free_rb_list.list.next, in recv_ishtp_cl_msg()
914 spin_unlock(&cl->free_list_spinlock); in recv_ishtp_cl_msg()
915 new_rb->cl = cl; in recv_ishtp_cl_msg()
921 ishtp_hbm_cl_flow_control_req(dev, cl); in recv_ishtp_cl_msg()
923 spin_unlock(&cl->free_list_spinlock); in recv_ishtp_cl_msg()
927 ++cl->recv_msg_num_frags; in recv_ishtp_cl_msg()
947 cl = complete_rb->cl; in recv_ishtp_cl_msg()
948 cl->ts_rx = ktime_get(); in recv_ishtp_cl_msg()
949 ++cl->recv_msg_cnt_ipc; in recv_ishtp_cl_msg()
968 struct ishtp_cl *cl; in recv_ishtp_cl_msg_dma() local
978 cl = rb->cl; in recv_ishtp_cl_msg_dma()
979 if (!cl || !(cl->host_client_id == hbm->host_client_id && in recv_ishtp_cl_msg_dma()
980 cl->fw_client_id == hbm->fw_client_id) || in recv_ishtp_cl_msg_dma()
981 !(cl->state == ISHTP_CL_CONNECTED)) in recv_ishtp_cl_msg_dma()
989 dev_err(&cl->device->dev, in recv_ishtp_cl_msg_dma()
993 cl->status = -ENOMEM; in recv_ishtp_cl_msg_dma()
1005 dev_err(&cl->device->dev, in recv_ishtp_cl_msg_dma()
1010 cl->status = -EIO; in recv_ishtp_cl_msg_dma()
1028 cl->status = 0; in recv_ishtp_cl_msg_dma()
1032 --cl->out_flow_ctrl_creds; in recv_ishtp_cl_msg_dma()
1037 spin_lock(&cl->free_list_spinlock); in recv_ishtp_cl_msg_dma()
1039 if (!list_empty(&cl->free_rb_list.list)) { in recv_ishtp_cl_msg_dma()
1040 new_rb = list_entry(cl->free_rb_list.list.next, in recv_ishtp_cl_msg_dma()
1043 spin_unlock(&cl->free_list_spinlock); in recv_ishtp_cl_msg_dma()
1044 new_rb->cl = cl; in recv_ishtp_cl_msg_dma()
1050 ishtp_hbm_cl_flow_control_req(dev, cl); in recv_ishtp_cl_msg_dma()
1052 spin_unlock(&cl->free_list_spinlock); in recv_ishtp_cl_msg_dma()
1056 ++cl->recv_msg_num_frags; in recv_ishtp_cl_msg_dma()
1073 cl = complete_rb->cl; in recv_ishtp_cl_msg_dma()
1074 cl->ts_rx = ktime_get(); in recv_ishtp_cl_msg_dma()
1075 ++cl->recv_msg_cnt_dma; in recv_ishtp_cl_msg_dma()
1082 void *ishtp_get_client_data(struct ishtp_cl *cl) in ishtp_get_client_data() argument
1084 return cl->client_data; in ishtp_get_client_data()
1088 void ishtp_set_client_data(struct ishtp_cl *cl, void *data) in ishtp_set_client_data() argument
1090 cl->client_data = data; in ishtp_set_client_data()
1094 struct ishtp_device *ishtp_get_ishtp_device(struct ishtp_cl *cl) in ishtp_get_ishtp_device() argument
1096 return cl->dev; in ishtp_get_ishtp_device()
1100 void ishtp_set_tx_ring_size(struct ishtp_cl *cl, int size) in ishtp_set_tx_ring_size() argument
1102 cl->tx_ring_size = size; in ishtp_set_tx_ring_size()
1106 void ishtp_set_rx_ring_size(struct ishtp_cl *cl, int size) in ishtp_set_rx_ring_size() argument
1108 cl->rx_ring_size = size; in ishtp_set_rx_ring_size()
1112 void ishtp_set_connection_state(struct ishtp_cl *cl, int state) in ishtp_set_connection_state() argument
1114 cl->state = state; in ishtp_set_connection_state()
1118 void ishtp_cl_set_fw_client_id(struct ishtp_cl *cl, int fw_client_id) in ishtp_cl_set_fw_client_id() argument
1120 cl->fw_client_id = fw_client_id; in ishtp_cl_set_fw_client_id()