Lines Matching refs:cl
16 int ishtp_cl_get_tx_free_buffer_size(struct ishtp_cl *cl)
21 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags);
22 size = cl->tx_ring_free_size * cl->device->fw_client->props.max_msg_length;
23 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags);
29 int ishtp_cl_get_tx_free_rings(struct ishtp_cl *cl)
31 return cl->tx_ring_free_size;
37 * @cl: ishtp client instance
41 static void ishtp_read_list_flush(struct ishtp_cl *cl)
47 spin_lock_irqsave(&cl->dev->read_list_spinlock, flags);
48 list_for_each_entry_safe(rb, next, &cl->dev->read_list.list, list)
49 if (rb->cl && ishtp_cl_cmp_id(cl, rb->cl)) {
53 spin_unlock_irqrestore(&cl->dev->read_list_spinlock, flags);
58 * @cl: ishtp client instance
65 int ishtp_cl_flush_queues(struct ishtp_cl *cl)
67 if (WARN_ON(!cl || !cl->dev))
70 ishtp_read_list_flush(cl);
78 * @cl: ishtp client instance
84 static void ishtp_cl_init(struct ishtp_cl *cl, struct ishtp_device *dev)
86 memset(cl, 0, sizeof(struct ishtp_cl));
87 init_waitqueue_head(&cl->wait_ctrl_res);
88 spin_lock_init(&cl->free_list_spinlock);
89 spin_lock_init(&cl->in_process_spinlock);
90 spin_lock_init(&cl->tx_list_spinlock);
91 spin_lock_init(&cl->tx_free_list_spinlock);
92 spin_lock_init(&cl->fc_spinlock);
93 INIT_LIST_HEAD(&cl->link);
94 cl->dev = dev;
96 INIT_LIST_HEAD(&cl->free_rb_list.list);
97 INIT_LIST_HEAD(&cl->tx_list.list);
98 INIT_LIST_HEAD(&cl->tx_free_list.list);
99 INIT_LIST_HEAD(&cl->in_process_list.list);
101 cl->rx_ring_size = CL_DEF_RX_RING_SIZE;
102 cl->tx_ring_size = CL_DEF_TX_RING_SIZE;
103 cl->tx_ring_free_size = cl->tx_ring_size;
106 cl->last_tx_path = CL_TX_PATH_IPC;
107 cl->last_dma_acked = 1;
108 cl->last_dma_addr = NULL;
109 cl->last_ipc_acked = 1;
122 struct ishtp_cl *cl;
124 cl = kmalloc(sizeof(struct ishtp_cl), GFP_KERNEL);
125 if (!cl)
128 ishtp_cl_init(cl, cl_device->ishtp_dev);
129 return cl;
135 * @cl: client device instance
139 void ishtp_cl_free(struct ishtp_cl *cl)
144 if (!cl)
147 dev = cl->dev;
152 ishtp_cl_free_rx_ring(cl);
153 ishtp_cl_free_tx_ring(cl);
154 kfree(cl);
161 * @cl: client device instance
170 int ishtp_cl_link(struct ishtp_cl *cl)
176 if (WARN_ON(!cl || !cl->dev))
179 dev = cl->dev;
192 dev_err(&cl->device->dev, "id exceeded %d", ISHTP_CLIENTS_MAX);
197 cl->host_client_id = id;
203 list_add_tail(&cl->link, &dev->cl_list);
205 cl->state = ISHTP_CL_INITIALIZING;
217 * @cl: client device instance
221 void ishtp_cl_unlink(struct ishtp_cl *cl)
228 if (!cl || !cl->dev)
231 dev = cl->dev;
235 clear_bit(cl->host_client_id, dev->host_clients_map);
241 * This checks that 'cl' is actually linked into device's structure,
246 if (cl->host_client_id == pos->host_client_id) {
256 * @cl: client device instance
263 int ishtp_cl_disconnect(struct ishtp_cl *cl)
268 if (WARN_ON(!cl || !cl->dev))
271 dev = cl->dev;
273 dev->print_log(dev, "%s() state %d\n", __func__, cl->state);
275 if (cl->state != ISHTP_CL_DISCONNECTING) {
280 if (ishtp_hbm_cl_disconnect_req(dev, cl)) {
282 dev_err(&cl->device->dev, "failed to disconnect.\n");
286 err = wait_event_interruptible_timeout(cl->wait_ctrl_res,
288 cl->state == ISHTP_CL_DISCONNECTED),
292 * If FW reset arrived, this will happen. Don't check cl->,
293 * as 'cl' may be freed already
301 if (cl->state == ISHTP_CL_DISCONNECTED) {
312 * @cl: client device instance
318 static bool ishtp_cl_is_other_connecting(struct ishtp_cl *cl)
324 if (WARN_ON(!cl || !cl->dev))
327 dev = cl->dev;
330 if ((pos->state == ISHTP_CL_CONNECTING) && (pos != cl) &&
331 cl->fw_client_id == pos->fw_client_id) {
343 * @cl: client device instance
351 int ishtp_cl_connect(struct ishtp_cl *cl)
356 if (WARN_ON(!cl || !cl->dev))
359 dev = cl->dev;
361 dev->print_log(dev, "%s() current_state = %d\n", __func__, cl->state);
363 if (ishtp_cl_is_other_connecting(cl)) {
368 if (ishtp_hbm_cl_connect_req(dev, cl)) {
373 rets = wait_event_interruptible_timeout(cl->wait_ctrl_res,
375 (cl->state == ISHTP_CL_CONNECTED ||
376 cl->state == ISHTP_CL_DISCONNECTED)),
380 * If FW reset arrived, this will happen. Don't check cl->,
381 * as 'cl' may be freed already
389 if (cl->state != ISHTP_CL_CONNECTED) {
395 rets = cl->status;
401 rets = ishtp_cl_device_bind(cl);
404 ishtp_cl_disconnect(cl);
408 rets = ishtp_cl_alloc_rx_ring(cl);
412 ishtp_cl_disconnect(cl);
416 rets = ishtp_cl_alloc_tx_ring(cl);
420 ishtp_cl_free_rx_ring(cl);
421 ishtp_cl_disconnect(cl);
426 rets = ishtp_cl_read_start(cl);
436 * @cl: client device instance
444 int ishtp_cl_read_start(struct ishtp_cl *cl)
453 if (WARN_ON(!cl || !cl->dev))
456 dev = cl->dev;
458 if (cl->state != ISHTP_CL_CONNECTED)
464 i = ishtp_fw_cl_by_id(dev, cl->fw_client_id);
466 dev_err(&cl->device->dev, "no such fw client %d\n",
467 cl->fw_client_id);
472 spin_lock_irqsave(&cl->free_list_spinlock, flags);
473 if (list_empty(&cl->free_rb_list.list)) {
474 dev_warn(&cl->device->dev,
478 spin_unlock_irqrestore(&cl->free_list_spinlock, flags);
481 rb = list_entry(cl->free_rb_list.list.next, struct ishtp_cl_rb, list);
483 spin_unlock_irqrestore(&cl->free_list_spinlock, flags);
485 rb->cl = cl;
498 if (ishtp_hbm_cl_flow_control_req(dev, cl)) {
509 spin_lock_irqsave(&cl->free_list_spinlock, flags);
510 list_add_tail(&rb->list, &cl->free_rb_list.list);
511 spin_unlock_irqrestore(&cl->free_list_spinlock, flags);
518 * @cl: client device instance
528 int ishtp_cl_send(struct ishtp_cl *cl, uint8_t *buf, size_t length)
536 if (WARN_ON(!cl || !cl->dev))
539 dev = cl->dev;
541 if (cl->state != ISHTP_CL_CONNECTED) {
542 ++cl->err_send_msg;
547 ++cl->err_send_msg;
552 id = ishtp_fw_cl_by_id(dev, cl->fw_client_id);
554 ++cl->err_send_msg;
559 ++cl->err_send_msg;
564 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags);
565 if (list_empty(&cl->tx_free_list.list)) {
566 spin_unlock_irqrestore(&cl->tx_free_list_spinlock,
568 ++cl->err_send_msg;
572 cl_msg = list_first_entry(&cl->tx_free_list.list,
575 spin_unlock_irqrestore(&cl->tx_free_list_spinlock,
585 --cl->tx_ring_free_size;
587 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags);
590 spin_lock_irqsave(&cl->tx_list_spinlock, tx_flags);
591 have_msg_to_send = !list_empty(&cl->tx_list.list);
592 list_add_tail(&cl_msg->list, &cl->tx_list.list);
593 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags);
595 if (!have_msg_to_send && cl->ishtp_flow_ctrl_creds > 0)
596 ishtp_cl_send_msg(dev, cl);
613 struct ishtp_cl *cl = rb->cl;
615 spin_lock_irqsave(&cl->in_process_spinlock, flags);
620 schedule_work_flag = list_empty(&cl->in_process_list.list);
621 list_add_tail(&rb->list, &cl->in_process_list.list);
622 spin_unlock_irqrestore(&cl->in_process_spinlock, flags);
625 ishtp_cl_bus_rx_event(cl->device);
638 struct ishtp_cl *cl = prm;
641 struct ishtp_device *dev = (cl ? cl->dev : NULL);
656 if (cl->state != ISHTP_CL_CONNECTED)
659 spin_lock_irqsave(&cl->tx_list_spinlock, tx_flags);
660 if (list_empty(&cl->tx_list.list)) {
661 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags);
665 if (cl->ishtp_flow_ctrl_creds != 1 && !cl->sending) {
666 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags);
670 if (!cl->sending) {
671 --cl->ishtp_flow_ctrl_creds;
672 cl->last_ipc_acked = 0;
673 cl->last_tx_path = CL_TX_PATH_IPC;
674 cl->sending = 1;
677 cl_msg = list_entry(cl->tx_list.list.next, struct ishtp_cl_tx_ring,
679 rem = cl_msg->send_buf.size - cl->tx_offs;
682 ishtp_hdr.host_addr = cl->host_client_id;
683 ishtp_hdr.fw_addr = cl->fw_client_id;
685 pmsg = cl_msg->send_buf.data + cl->tx_offs;
693 cl->tx_offs = 0;
694 cl->sending = 0;
703 cl->tx_offs += dev->mtu;
704 rem = cl_msg->send_buf.size - cl->tx_offs;
709 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags);
711 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags);
712 list_add_tail(&cl_msg->list, &cl->tx_free_list.list);
713 ++cl->tx_ring_free_size;
714 spin_unlock_irqrestore(&cl->tx_free_list_spinlock,
721 * @cl: Pointer to client device instance
726 struct ishtp_cl *cl)
729 if (cl->last_tx_path == CL_TX_PATH_DMA && cl->last_dma_acked == 0)
732 cl->tx_offs = 0;
733 ipc_tx_send(cl);
734 ++cl->send_msg_cnt_ipc;
740 * @cl: Pointer to client device instance
745 struct ishtp_cl *cl)
755 if (cl->last_tx_path == CL_TX_PATH_IPC && cl->last_ipc_acked == 0)
758 spin_lock_irqsave(&cl->tx_list_spinlock, tx_flags);
759 if (list_empty(&cl->tx_list.list)) {
760 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags);
764 cl_msg = list_entry(cl->tx_list.list.next, struct ishtp_cl_tx_ring,
769 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags);
771 ishtp_cl_send_msg_ipc(dev, cl);
776 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags);
778 --cl->ishtp_flow_ctrl_creds;
779 cl->last_dma_acked = 0;
780 cl->last_dma_addr = msg_addr;
781 cl->last_tx_path = CL_TX_PATH_DMA;
790 dma_xfer.fw_client_id = cl->fw_client_id;
791 dma_xfer.host_client_id = cl->host_client_id;
797 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags);
798 list_add_tail(&cl_msg->list, &cl->tx_free_list.list);
799 ++cl->tx_ring_free_size;
800 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags);
801 ++cl->send_msg_cnt_dma;
807 * @cl: Pointer to client device instance
811 void ishtp_cl_send_msg(struct ishtp_device *dev, struct ishtp_cl *cl)
814 ishtp_cl_send_msg_dma(dev, cl);
816 ishtp_cl_send_msg_ipc(dev, cl);
830 struct ishtp_cl *cl;
853 cl = rb->cl;
854 if (!cl || !(cl->host_client_id == ishtp_hdr->host_addr &&
855 cl->fw_client_id == ishtp_hdr->fw_addr) ||
856 !(cl->state == ISHTP_CL_CONNECTED))
862 dev_err(&cl->device->dev,
866 cl->status = -ENOMEM;
878 dev_err(&cl->device->dev,
884 cl->status = -EIO;
894 cl->status = 0;
898 --cl->out_flow_ctrl_creds;
903 spin_lock(&cl->free_list_spinlock);
905 if (!list_empty(&cl->free_rb_list.list)) {
906 new_rb = list_entry(cl->free_rb_list.list.next,
909 spin_unlock(&cl->free_list_spinlock);
910 new_rb->cl = cl;
916 ishtp_hbm_cl_flow_control_req(dev, cl);
918 spin_unlock(&cl->free_list_spinlock);
922 ++cl->recv_msg_num_frags;
942 cl = complete_rb->cl;
943 cl->ts_rx = ktime_get();
944 ++cl->recv_msg_cnt_ipc;
963 struct ishtp_cl *cl;
973 cl = rb->cl;
974 if (!cl || !(cl->host_client_id == hbm->host_client_id &&
975 cl->fw_client_id == hbm->fw_client_id) ||
976 !(cl->state == ISHTP_CL_CONNECTED))
984 dev_err(&cl->device->dev,
988 cl->status = -ENOMEM;
1000 dev_err(&cl->device->dev,
1005 cl->status = -EIO;
1014 cl->status = 0;
1018 --cl->out_flow_ctrl_creds;
1023 spin_lock(&cl->free_list_spinlock);
1025 if (!list_empty(&cl->free_rb_list.list)) {
1026 new_rb = list_entry(cl->free_rb_list.list.next,
1029 spin_unlock(&cl->free_list_spinlock);
1030 new_rb->cl = cl;
1036 ishtp_hbm_cl_flow_control_req(dev, cl);
1038 spin_unlock(&cl->free_list_spinlock);
1042 ++cl->recv_msg_num_frags;
1059 cl = complete_rb->cl;
1060 cl->ts_rx = ktime_get();
1061 ++cl->recv_msg_cnt_dma;
1068 void *ishtp_get_client_data(struct ishtp_cl *cl)
1070 return cl->client_data;
1074 void ishtp_set_client_data(struct ishtp_cl *cl, void *data)
1076 cl->client_data = data;
1080 struct ishtp_device *ishtp_get_ishtp_device(struct ishtp_cl *cl)
1082 return cl->dev;
1086 void ishtp_set_tx_ring_size(struct ishtp_cl *cl, int size)
1088 cl->tx_ring_size = size;
1092 void ishtp_set_rx_ring_size(struct ishtp_cl *cl, int size)
1094 cl->rx_ring_size = size;
1098 void ishtp_set_connection_state(struct ishtp_cl *cl, int state)
1100 cl->state = state;
1104 void ishtp_cl_set_fw_client_id(struct ishtp_cl *cl, int fw_client_id)
1106 cl->fw_client_id = fw_client_id;