Lines Matching +full:pmsg +full:- +full:size
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (c) 2003-2016, Intel Corporation.
12 #include <linux/dma-mapping.h>
20 int size; in ishtp_cl_get_tx_free_buffer_size() local
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()
26 return size; in ishtp_cl_get_tx_free_buffer_size()
32 return cl->tx_ring_free_size; in ishtp_cl_get_tx_free_rings()
37 * ishtp_read_list_flush() - Flush read queue
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()
51 list_del(&rb->list); in ishtp_read_list_flush()
52 spin_lock(&cl->free_list_spinlock); in ishtp_read_list_flush()
53 list_add_tail(&rb->list, &cl->free_rb_list.list); in ishtp_read_list_flush()
54 spin_unlock(&cl->free_list_spinlock); in ishtp_read_list_flush()
56 spin_unlock_irqrestore(&cl->dev->read_list_spinlock, flags); in ishtp_read_list_flush()
60 * ishtp_cl_flush_queues() - Flush all queues for a client
66 * Return: 0 on success else -EINVAL if device is NULL
70 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_flush_queues()
71 return -EINVAL; in ishtp_cl_flush_queues()
80 * ishtp_cl_init() - Initialize all fields of a client device
90 init_waitqueue_head(&cl->wait_ctrl_res); in ishtp_cl_init()
91 spin_lock_init(&cl->free_list_spinlock); in ishtp_cl_init()
92 spin_lock_init(&cl->in_process_spinlock); in ishtp_cl_init()
93 spin_lock_init(&cl->tx_list_spinlock); in ishtp_cl_init()
94 spin_lock_init(&cl->tx_free_list_spinlock); in ishtp_cl_init()
95 spin_lock_init(&cl->fc_spinlock); in ishtp_cl_init()
96 INIT_LIST_HEAD(&cl->link); in ishtp_cl_init()
97 cl->dev = dev; in ishtp_cl_init()
99 INIT_LIST_HEAD(&cl->free_rb_list.list); in ishtp_cl_init()
100 INIT_LIST_HEAD(&cl->tx_list.list); in ishtp_cl_init()
101 INIT_LIST_HEAD(&cl->tx_free_list.list); in ishtp_cl_init()
102 INIT_LIST_HEAD(&cl->in_process_list.list); in ishtp_cl_init()
104 cl->rx_ring_size = CL_DEF_RX_RING_SIZE; in ishtp_cl_init()
105 cl->tx_ring_size = CL_DEF_TX_RING_SIZE; in ishtp_cl_init()
106 cl->tx_ring_free_size = cl->tx_ring_size; in ishtp_cl_init()
109 cl->last_tx_path = CL_TX_PATH_IPC; in ishtp_cl_init()
110 cl->last_dma_acked = 1; in ishtp_cl_init()
111 cl->last_dma_addr = NULL; in ishtp_cl_init()
112 cl->last_ipc_acked = 1; in ishtp_cl_init()
116 * ishtp_cl_allocate() - allocates client structure and sets it up.
131 ishtp_cl_init(cl, cl_device->ishtp_dev); in ishtp_cl_allocate()
137 * ishtp_cl_free() - Frees a client device
150 dev = cl->dev; in ishtp_cl_free()
154 spin_lock_irqsave(&dev->cl_list_lock, flags); in ishtp_cl_free()
158 spin_unlock_irqrestore(&dev->cl_list_lock, flags); in ishtp_cl_free()
163 * ishtp_cl_link() - Reserve a host id and link the client instance
179 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_link()
180 return -EINVAL; in ishtp_cl_link()
182 dev = cl->dev; in ishtp_cl_link()
184 spin_lock_irqsave(&dev->device_lock, flags); in ishtp_cl_link()
186 if (dev->open_handle_count >= ISHTP_MAX_OPEN_HANDLE_COUNT) { in ishtp_cl_link()
187 ret = -EMFILE; in ishtp_cl_link()
191 id = find_first_zero_bit(dev->host_clients_map, ISHTP_CLIENTS_MAX); in ishtp_cl_link()
194 spin_unlock_irqrestore(&dev->device_lock, flags); in ishtp_cl_link()
195 dev_err(&cl->device->dev, "id exceeded %d", ISHTP_CLIENTS_MAX); in ishtp_cl_link()
196 return -ENOENT; in ishtp_cl_link()
199 dev->open_handle_count++; in ishtp_cl_link()
200 cl->host_client_id = id; in ishtp_cl_link()
201 spin_lock_irqsave(&dev->cl_list_lock, flags_cl); in ishtp_cl_link()
202 if (dev->dev_state != ISHTP_DEV_ENABLED) { in ishtp_cl_link()
203 ret = -ENODEV; in ishtp_cl_link()
206 list_add_tail(&cl->link, &dev->cl_list); in ishtp_cl_link()
207 set_bit(id, dev->host_clients_map); in ishtp_cl_link()
208 cl->state = ISHTP_CL_INITIALIZING; in ishtp_cl_link()
211 spin_unlock_irqrestore(&dev->cl_list_lock, flags_cl); in ishtp_cl_link()
213 spin_unlock_irqrestore(&dev->device_lock, flags); in ishtp_cl_link()
219 * ishtp_cl_unlink() - remove fw_cl from the client device list
231 if (!cl || !cl->dev) in ishtp_cl_unlink()
234 dev = cl->dev; in ishtp_cl_unlink()
236 spin_lock_irqsave(&dev->device_lock, flags); in ishtp_cl_unlink()
237 if (dev->open_handle_count > 0) { in ishtp_cl_unlink()
238 clear_bit(cl->host_client_id, dev->host_clients_map); in ishtp_cl_unlink()
239 dev->open_handle_count--; in ishtp_cl_unlink()
241 spin_unlock_irqrestore(&dev->device_lock, flags); in ishtp_cl_unlink()
247 spin_lock_irqsave(&dev->cl_list_lock, flags); in ishtp_cl_unlink()
248 list_for_each_entry(pos, &dev->cl_list, link) in ishtp_cl_unlink()
249 if (cl->host_client_id == pos->host_client_id) { in ishtp_cl_unlink()
250 list_del_init(&pos->link); in ishtp_cl_unlink()
253 spin_unlock_irqrestore(&dev->cl_list_lock, flags); in ishtp_cl_unlink()
258 * ishtp_cl_disconnect() - Send disconnect request to firmware
270 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_disconnect()
271 return -ENODEV; in ishtp_cl_disconnect()
273 dev = cl->dev; in ishtp_cl_disconnect()
275 dev->print_log(dev, "%s() state %d\n", __func__, cl->state); in ishtp_cl_disconnect()
277 if (cl->state != ISHTP_CL_DISCONNECTING) { in ishtp_cl_disconnect()
278 dev->print_log(dev, "%s() Disconnect in progress\n", __func__); in ishtp_cl_disconnect()
283 dev->print_log(dev, "%s() Failed to disconnect\n", __func__); in ishtp_cl_disconnect()
284 dev_err(&cl->device->dev, "failed to disconnect.\n"); in ishtp_cl_disconnect()
285 return -ENODEV; in ishtp_cl_disconnect()
288 wait_event_interruptible_timeout(cl->wait_ctrl_res, in ishtp_cl_disconnect()
289 (dev->dev_state != ISHTP_DEV_ENABLED || in ishtp_cl_disconnect()
290 cl->state == ISHTP_CL_DISCONNECTED), in ishtp_cl_disconnect()
294 * If FW reset arrived, this will happen. Don't check cl->, in ishtp_cl_disconnect()
297 if (dev->dev_state != ISHTP_DEV_ENABLED) { in ishtp_cl_disconnect()
298 dev->print_log(dev, "%s() dev_state != ISHTP_DEV_ENABLED\n", in ishtp_cl_disconnect()
300 return -ENODEV; in ishtp_cl_disconnect()
303 if (cl->state == ISHTP_CL_DISCONNECTED) { in ishtp_cl_disconnect()
304 dev->print_log(dev, "%s() successful\n", __func__); in ishtp_cl_disconnect()
308 return -ENODEV; in ishtp_cl_disconnect()
313 * ishtp_cl_is_other_connecting() - Check other client is connecting
326 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_is_other_connecting()
329 dev = cl->dev; in ishtp_cl_is_other_connecting()
330 spin_lock_irqsave(&dev->cl_list_lock, flags); in ishtp_cl_is_other_connecting()
331 list_for_each_entry(pos, &dev->cl_list, link) { in ishtp_cl_is_other_connecting()
332 if ((pos->state == ISHTP_CL_CONNECTING) && (pos != cl) && in ishtp_cl_is_other_connecting()
333 cl->fw_client_id == pos->fw_client_id) { in ishtp_cl_is_other_connecting()
334 spin_unlock_irqrestore(&dev->cl_list_lock, flags); in ishtp_cl_is_other_connecting()
338 spin_unlock_irqrestore(&dev->cl_list_lock, flags); in ishtp_cl_is_other_connecting()
344 * ishtp_cl_connect_to_fw() - Send connect request to firmware
359 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_connect_to_fw()
360 return -ENODEV; in ishtp_cl_connect_to_fw()
362 dev = cl->dev; in ishtp_cl_connect_to_fw()
365 dev->print_log(dev, "%s() Busy\n", __func__); in ishtp_cl_connect_to_fw()
366 return -EBUSY; in ishtp_cl_connect_to_fw()
370 dev->print_log(dev, "%s() HBM connect req fail\n", __func__); in ishtp_cl_connect_to_fw()
371 return -ENODEV; in ishtp_cl_connect_to_fw()
374 rets = wait_event_interruptible_timeout(cl->wait_ctrl_res, in ishtp_cl_connect_to_fw()
375 (dev->dev_state == ISHTP_DEV_ENABLED && in ishtp_cl_connect_to_fw()
376 (cl->state == ISHTP_CL_CONNECTED || in ishtp_cl_connect_to_fw()
377 cl->state == ISHTP_CL_DISCONNECTED)), in ishtp_cl_connect_to_fw()
381 * If FW reset arrived, this will happen. Don't check cl->, in ishtp_cl_connect_to_fw()
384 if (dev->dev_state != ISHTP_DEV_ENABLED) { in ishtp_cl_connect_to_fw()
385 dev->print_log(dev, "%s() dev_state != ISHTP_DEV_ENABLED\n", in ishtp_cl_connect_to_fw()
387 return -EFAULT; in ishtp_cl_connect_to_fw()
390 if (cl->state != ISHTP_CL_CONNECTED) { in ishtp_cl_connect_to_fw()
391 dev->print_log(dev, "%s() state != ISHTP_CL_CONNECTED\n", in ishtp_cl_connect_to_fw()
393 return -EFAULT; in ishtp_cl_connect_to_fw()
396 rets = cl->status; in ishtp_cl_connect_to_fw()
398 dev->print_log(dev, "%s() Invalid status\n", __func__); in ishtp_cl_connect_to_fw()
404 dev->print_log(dev, "%s() Bind error\n", __func__); in ishtp_cl_connect_to_fw()
413 * ishtp_cl_connect() - Build connection with firmware
428 if (!cl || !cl->dev) in ishtp_cl_connect()
429 return -ENODEV; in ishtp_cl_connect()
431 dev = cl->dev; in ishtp_cl_connect()
433 dev->print_log(dev, "%s() current_state = %d\n", __func__, cl->state); in ishtp_cl_connect()
437 dev->print_log(dev, "%s() Connect to fw failed\n", __func__); in ishtp_cl_connect()
443 dev->print_log(dev, "%s() Alloc RX ring failed\n", __func__); in ishtp_cl_connect()
451 dev->print_log(dev, "%s() Alloc TX ring failed\n", __func__); in ishtp_cl_connect()
459 * Upon successful connection and allocation, start flow-control. in ishtp_cl_connect()
468 * ishtp_cl_establish_connection() - Establish connection with the firmware
471 * @tx_size: TX ring buffer size
472 * @rx_size: RX ring buffer size
495 if (!cl || !cl->dev) in ishtp_cl_establish_connection()
496 return -ENODEV; in ishtp_cl_establish_connection()
498 dev = cl->dev; in ishtp_cl_establish_connection()
504 cl->host_client_id = 0; in ishtp_cl_establish_connection()
505 cl->fw_client_id = 0; in ishtp_cl_establish_connection()
506 cl->ishtp_flow_ctrl_creds = 0; in ishtp_cl_establish_connection()
507 cl->out_flow_ctrl_creds = 0; in ishtp_cl_establish_connection()
509 cl->last_tx_path = CL_TX_PATH_IPC; in ishtp_cl_establish_connection()
510 cl->last_dma_acked = 1; in ishtp_cl_establish_connection()
511 cl->last_dma_addr = NULL; in ishtp_cl_establish_connection()
512 cl->last_ipc_acked = 1; in ishtp_cl_establish_connection()
514 cl->sending = 0; in ishtp_cl_establish_connection()
515 cl->err_send_msg = 0; in ishtp_cl_establish_connection()
516 cl->err_send_fc = 0; in ishtp_cl_establish_connection()
518 cl->send_msg_cnt_ipc = 0; in ishtp_cl_establish_connection()
519 cl->send_msg_cnt_dma = 0; in ishtp_cl_establish_connection()
520 cl->recv_msg_cnt_ipc = 0; in ishtp_cl_establish_connection()
521 cl->recv_msg_cnt_dma = 0; in ishtp_cl_establish_connection()
522 cl->recv_msg_num_frags = 0; in ishtp_cl_establish_connection()
523 cl->ishtp_flow_ctrl_cnt = 0; in ishtp_cl_establish_connection()
524 cl->out_flow_ctrl_cnt = 0; in ishtp_cl_establish_connection()
530 dev->print_log(dev, "%s() ishtp_cl_link failed\n", __func__); in ishtp_cl_establish_connection()
537 dev->print_log(dev, in ishtp_cl_establish_connection()
539 return -ENOENT; in ishtp_cl_establish_connection()
558 dev->print_log(dev, in ishtp_cl_establish_connection()
569 * ishtp_cl_destroy_connection() - Disconnect with the firmware
588 if (cl->state != ISHTP_CL_DISCONNECTED) { in ishtp_cl_destroy_connection()
600 * ishtp_cl_read_start() - Prepare to read client message
618 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_read_start()
619 return -ENODEV; in ishtp_cl_read_start()
621 dev = cl->dev; in ishtp_cl_read_start()
623 if (cl->state != ISHTP_CL_CONNECTED) in ishtp_cl_read_start()
624 return -ENODEV; in ishtp_cl_read_start()
626 if (dev->dev_state != ISHTP_DEV_ENABLED) in ishtp_cl_read_start()
627 return -ENODEV; in ishtp_cl_read_start()
629 i = ishtp_fw_cl_by_id(dev, cl->fw_client_id); in ishtp_cl_read_start()
631 dev_err(&cl->device->dev, "no such fw client %d\n", in ishtp_cl_read_start()
632 cl->fw_client_id); in ishtp_cl_read_start()
633 return -ENODEV; in ishtp_cl_read_start()
637 spin_lock_irqsave(&cl->free_list_spinlock, flags); in ishtp_cl_read_start()
638 if (list_empty(&cl->free_rb_list.list)) { in ishtp_cl_read_start()
639 dev_warn(&cl->device->dev, in ishtp_cl_read_start()
640 "[ishtp-ish] Rx buffers pool is empty\n"); in ishtp_cl_read_start()
641 rets = -ENOMEM; in ishtp_cl_read_start()
643 spin_unlock_irqrestore(&cl->free_list_spinlock, flags); in ishtp_cl_read_start()
646 rb = list_entry(cl->free_rb_list.list.next, struct ishtp_cl_rb, list); in ishtp_cl_read_start()
647 list_del_init(&rb->list); in ishtp_cl_read_start()
648 spin_unlock_irqrestore(&cl->free_list_spinlock, flags); in ishtp_cl_read_start()
650 rb->cl = cl; in ishtp_cl_read_start()
651 rb->buf_idx = 0; in ishtp_cl_read_start()
653 INIT_LIST_HEAD(&rb->list); in ishtp_cl_read_start()
657 * This must be BEFORE sending flow control - in ishtp_cl_read_start()
660 spin_lock_irqsave(&dev->read_list_spinlock, dev_flags); in ishtp_cl_read_start()
661 list_add_tail(&rb->list, &dev->read_list.list); in ishtp_cl_read_start()
662 spin_unlock_irqrestore(&dev->read_list_spinlock, dev_flags); in ishtp_cl_read_start()
664 rets = -ENODEV; in ishtp_cl_read_start()
670 spin_lock_irqsave(&dev->read_list_spinlock, dev_flags); in ishtp_cl_read_start()
671 list_del(&rb->list); in ishtp_cl_read_start()
672 spin_unlock_irqrestore(&dev->read_list_spinlock, dev_flags); in ishtp_cl_read_start()
674 spin_lock_irqsave(&cl->free_list_spinlock, flags); in ishtp_cl_read_start()
675 list_add_tail(&rb->list, &cl->free_rb_list.list); in ishtp_cl_read_start()
676 spin_unlock_irqrestore(&cl->free_list_spinlock, flags); in ishtp_cl_read_start()
682 * ishtp_cl_send() - Send a message to firmware
701 if (WARN_ON(!cl || !cl->dev)) in ishtp_cl_send()
702 return -ENODEV; in ishtp_cl_send()
704 dev = cl->dev; in ishtp_cl_send()
706 if (cl->state != ISHTP_CL_CONNECTED) { in ishtp_cl_send()
707 ++cl->err_send_msg; in ishtp_cl_send()
708 return -EPIPE; in ishtp_cl_send()
711 if (dev->dev_state != ISHTP_DEV_ENABLED) { in ishtp_cl_send()
712 ++cl->err_send_msg; in ishtp_cl_send()
713 return -ENODEV; in ishtp_cl_send()
717 id = ishtp_fw_cl_by_id(dev, cl->fw_client_id); in ishtp_cl_send()
719 ++cl->err_send_msg; in ishtp_cl_send()
720 return -ENOENT; in ishtp_cl_send()
723 if (length > dev->fw_clients[id].props.max_msg_length) { in ishtp_cl_send()
724 ++cl->err_send_msg; in ishtp_cl_send()
725 return -EMSGSIZE; in ishtp_cl_send()
729 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); in ishtp_cl_send()
730 if (list_empty(&cl->tx_free_list.list)) { in ishtp_cl_send()
731 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, in ishtp_cl_send()
733 ++cl->err_send_msg; in ishtp_cl_send()
734 return -ENOMEM; in ishtp_cl_send()
737 cl_msg = list_first_entry(&cl->tx_free_list.list, in ishtp_cl_send()
739 if (!cl_msg->send_buf.data) { in ishtp_cl_send()
740 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, in ishtp_cl_send()
742 return -EIO; in ishtp_cl_send()
743 /* Should not happen, as free list is pre-allocated */ in ishtp_cl_send()
747 * max ISHTP message size per client in ishtp_cl_send()
749 list_del_init(&cl_msg->list); in ishtp_cl_send()
750 --cl->tx_ring_free_size; in ishtp_cl_send()
752 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags); in ishtp_cl_send()
753 memcpy(cl_msg->send_buf.data, buf, length); in ishtp_cl_send()
754 cl_msg->send_buf.size = length; in ishtp_cl_send()
755 spin_lock_irqsave(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send()
756 have_msg_to_send = !list_empty(&cl->tx_list.list); in ishtp_cl_send()
757 list_add_tail(&cl_msg->list, &cl->tx_list.list); in ishtp_cl_send()
758 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send()
760 if (!have_msg_to_send && cl->ishtp_flow_ctrl_creds > 0) in ishtp_cl_send()
768 * ishtp_cl_read_complete() - read complete
778 struct ishtp_cl *cl = rb->cl; in ishtp_cl_read_complete()
780 spin_lock_irqsave(&cl->in_process_spinlock, flags); in ishtp_cl_read_complete()
782 * if in-process list is empty, then need to schedule in ishtp_cl_read_complete()
785 schedule_work_flag = list_empty(&cl->in_process_list.list); in ishtp_cl_read_complete()
786 list_add_tail(&rb->list, &cl->in_process_list.list); in ishtp_cl_read_complete()
787 spin_unlock_irqrestore(&cl->in_process_spinlock, flags); in ishtp_cl_read_complete()
790 ishtp_cl_bus_rx_event(cl->device); in ishtp_cl_read_complete()
794 * ipc_tx_send() - IPC tx send function
798 * if message size is bigger than IPC FIFO size, and all
806 struct ishtp_device *dev = (cl ? cl->dev : NULL); in ipc_tx_send()
809 unsigned char *pmsg; in ipc_tx_send() local
818 if (dev->dev_state != ISHTP_DEV_ENABLED) in ipc_tx_send()
821 if (cl->state != ISHTP_CL_CONNECTED) in ipc_tx_send()
824 spin_lock_irqsave(&cl->tx_list_spinlock, tx_flags); in ipc_tx_send()
825 if (list_empty(&cl->tx_list.list)) { in ipc_tx_send()
826 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ipc_tx_send()
830 if (cl->ishtp_flow_ctrl_creds != 1 && !cl->sending) { in ipc_tx_send()
831 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ipc_tx_send()
835 if (!cl->sending) { in ipc_tx_send()
836 --cl->ishtp_flow_ctrl_creds; in ipc_tx_send()
837 cl->last_ipc_acked = 0; in ipc_tx_send()
838 cl->last_tx_path = CL_TX_PATH_IPC; in ipc_tx_send()
839 cl->sending = 1; in ipc_tx_send()
842 cl_msg = list_entry(cl->tx_list.list.next, struct ishtp_cl_tx_ring, in ipc_tx_send()
844 rem = cl_msg->send_buf.size - cl->tx_offs; in ipc_tx_send()
847 ishtp_hdr.host_addr = cl->host_client_id; in ipc_tx_send()
848 ishtp_hdr.fw_addr = cl->fw_client_id; in ipc_tx_send()
850 pmsg = cl_msg->send_buf.data + cl->tx_offs; in ipc_tx_send()
852 if (rem <= dev->mtu) { in ipc_tx_send()
857 ishtp_write_message(dev, &ishtp_hdr, pmsg); in ipc_tx_send()
858 cl->tx_offs = 0; in ipc_tx_send()
859 cl->sending = 0; in ipc_tx_send()
864 ishtp_hdr.length = dev->mtu; in ipc_tx_send()
867 ishtp_write_message(dev, &ishtp_hdr, pmsg); in ipc_tx_send()
868 cl->tx_offs += dev->mtu; in ipc_tx_send()
869 rem = cl_msg->send_buf.size - cl->tx_offs; in ipc_tx_send()
873 list_del_init(&cl_msg->list); in ipc_tx_send()
874 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ipc_tx_send()
876 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); in ipc_tx_send()
877 list_add_tail(&cl_msg->list, &cl->tx_free_list.list); in ipc_tx_send()
878 ++cl->tx_ring_free_size; in ipc_tx_send()
879 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, in ipc_tx_send()
884 * ishtp_cl_send_msg_ipc() -Send message using IPC
894 if (cl->last_tx_path == CL_TX_PATH_DMA && cl->last_dma_acked == 0) in ishtp_cl_send_msg_ipc()
897 cl->tx_offs = 0; in ishtp_cl_send_msg_ipc()
899 ++cl->send_msg_cnt_ipc; in ishtp_cl_send_msg_ipc()
903 * ishtp_cl_send_msg_dma() -Send message using DMA
920 if (cl->last_tx_path == CL_TX_PATH_IPC && cl->last_ipc_acked == 0) in ishtp_cl_send_msg_dma()
923 spin_lock_irqsave(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send_msg_dma()
924 if (list_empty(&cl->tx_list.list)) { in ishtp_cl_send_msg_dma()
925 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send_msg_dma()
929 cl_msg = list_entry(cl->tx_list.list.next, struct ishtp_cl_tx_ring, in ishtp_cl_send_msg_dma()
932 msg_addr = ishtp_cl_get_dma_send_buf(dev, cl_msg->send_buf.size); in ishtp_cl_send_msg_dma()
934 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send_msg_dma()
935 if (dev->transfer_path == CL_TX_PATH_DEFAULT) in ishtp_cl_send_msg_dma()
940 list_del_init(&cl_msg->list); /* Must be before write */ in ishtp_cl_send_msg_dma()
941 spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); in ishtp_cl_send_msg_dma()
943 --cl->ishtp_flow_ctrl_creds; in ishtp_cl_send_msg_dma()
944 cl->last_dma_acked = 0; in ishtp_cl_send_msg_dma()
945 cl->last_dma_addr = msg_addr; in ishtp_cl_send_msg_dma()
946 cl->last_tx_path = CL_TX_PATH_DMA; in ishtp_cl_send_msg_dma()
949 memcpy(msg_addr, cl_msg->send_buf.data, cl_msg->send_buf.size); in ishtp_cl_send_msg_dma()
955 if (dev->ops->dma_no_cache_snooping && in ishtp_cl_send_msg_dma()
956 dev->ops->dma_no_cache_snooping(dev)) in ishtp_cl_send_msg_dma()
957 clflush_cache_range(msg_addr, cl_msg->send_buf.size); in ishtp_cl_send_msg_dma()
960 off = msg_addr - (unsigned char *)dev->ishtp_host_dma_tx_buf; in ishtp_cl_send_msg_dma()
963 dma_xfer.fw_client_id = cl->fw_client_id; in ishtp_cl_send_msg_dma()
964 dma_xfer.host_client_id = cl->host_client_id; in ishtp_cl_send_msg_dma()
966 dma_xfer.msg_addr = dev->ishtp_host_dma_tx_buf_phys + off; in ishtp_cl_send_msg_dma()
967 dma_xfer.msg_length = cl_msg->send_buf.size; in ishtp_cl_send_msg_dma()
970 spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); in ishtp_cl_send_msg_dma()
971 list_add_tail(&cl_msg->list, &cl->tx_free_list.list); in ishtp_cl_send_msg_dma()
972 ++cl->tx_ring_free_size; in ishtp_cl_send_msg_dma()
973 spin_unlock_irqrestore(&cl->tx_free_list_spinlock, tx_free_flags); in ishtp_cl_send_msg_dma()
974 ++cl->send_msg_cnt_dma; in ishtp_cl_send_msg_dma()
978 * ishtp_cl_send_msg() -Send message using DMA or IPC
986 if (dev->transfer_path == CL_TX_PATH_DMA) in ishtp_cl_send_msg()
993 * recv_ishtp_cl_msg() -Receive client message
1010 if (ishtp_hdr->reserved) { in recv_ishtp_cl_msg()
1011 dev_err(dev->devc, "corrupted message header.\n"); in recv_ishtp_cl_msg()
1015 if (ishtp_hdr->length > IPC_PAYLOAD_SIZE) { in recv_ishtp_cl_msg()
1016 dev_err(dev->devc, in recv_ishtp_cl_msg()
1021 spin_lock_irqsave(&dev->read_list_spinlock, flags); in recv_ishtp_cl_msg()
1022 list_for_each_entry(rb, &dev->read_list.list, list) { in recv_ishtp_cl_msg()
1023 cl = rb->cl; in recv_ishtp_cl_msg()
1024 if (!cl || !(cl->host_client_id == ishtp_hdr->host_addr && in recv_ishtp_cl_msg()
1025 cl->fw_client_id == ishtp_hdr->fw_addr) || in recv_ishtp_cl_msg()
1026 !(cl->state == ISHTP_CL_CONNECTED)) in recv_ishtp_cl_msg()
1030 if (rb->buffer.size == 0 || rb->buffer.data == NULL) { in recv_ishtp_cl_msg()
1031 spin_unlock_irqrestore(&dev->read_list_spinlock, flags); in recv_ishtp_cl_msg()
1032 dev_err(&cl->device->dev, in recv_ishtp_cl_msg()
1034 list_del(&rb->list); in recv_ishtp_cl_msg()
1036 cl->status = -ENOMEM; in recv_ishtp_cl_msg()
1042 * size, drop message and return to free buffer. in recv_ishtp_cl_msg()
1046 if (rb->buffer.size < ishtp_hdr->length + rb->buf_idx) { in recv_ishtp_cl_msg()
1047 spin_unlock_irqrestore(&dev->read_list_spinlock, flags); in recv_ishtp_cl_msg()
1048 dev_err(&cl->device->dev, in recv_ishtp_cl_msg()
1049 "message overflow. size %d len %d idx %ld\n", in recv_ishtp_cl_msg()
1050 rb->buffer.size, ishtp_hdr->length, in recv_ishtp_cl_msg()
1051 rb->buf_idx); in recv_ishtp_cl_msg()
1052 list_del(&rb->list); in recv_ishtp_cl_msg()
1054 cl->status = -EIO; in recv_ishtp_cl_msg()
1058 buffer = rb->buffer.data + rb->buf_idx; in recv_ishtp_cl_msg()
1059 dev->ops->ishtp_read(dev, buffer, ishtp_hdr->length); in recv_ishtp_cl_msg()
1061 rb->buf_idx += ishtp_hdr->length; in recv_ishtp_cl_msg()
1062 if (ishtp_hdr->msg_complete) { in recv_ishtp_cl_msg()
1063 /* Last fragment in message - it's complete */ in recv_ishtp_cl_msg()
1064 cl->status = 0; in recv_ishtp_cl_msg()
1065 list_del(&rb->list); in recv_ishtp_cl_msg()
1068 --cl->out_flow_ctrl_creds; in recv_ishtp_cl_msg()
1073 spin_lock(&cl->free_list_spinlock); in recv_ishtp_cl_msg()
1075 if (!list_empty(&cl->free_rb_list.list)) { in recv_ishtp_cl_msg()
1076 new_rb = list_entry(cl->free_rb_list.list.next, in recv_ishtp_cl_msg()
1078 list_del_init(&new_rb->list); in recv_ishtp_cl_msg()
1079 spin_unlock(&cl->free_list_spinlock); in recv_ishtp_cl_msg()
1080 new_rb->cl = cl; in recv_ishtp_cl_msg()
1081 new_rb->buf_idx = 0; in recv_ishtp_cl_msg()
1082 INIT_LIST_HEAD(&new_rb->list); in recv_ishtp_cl_msg()
1083 list_add_tail(&new_rb->list, in recv_ishtp_cl_msg()
1084 &dev->read_list.list); in recv_ishtp_cl_msg()
1088 spin_unlock(&cl->free_list_spinlock); in recv_ishtp_cl_msg()
1092 ++cl->recv_msg_num_frags; in recv_ishtp_cl_msg()
1101 spin_unlock_irqrestore(&dev->read_list_spinlock, flags); in recv_ishtp_cl_msg()
1106 dev_err(dev->devc, "Dropped Rx msg - no request\n"); in recv_ishtp_cl_msg()
1107 dev->ops->ishtp_read(dev, rd_msg_buf, ishtp_hdr->length); in recv_ishtp_cl_msg()
1112 cl = complete_rb->cl; in recv_ishtp_cl_msg()
1113 cl->ts_rx = ktime_get(); in recv_ishtp_cl_msg()
1114 ++cl->recv_msg_cnt_ipc; in recv_ishtp_cl_msg()
1122 * recv_ishtp_cl_msg_dma() -Receive client message
1140 spin_lock_irqsave(&dev->read_list_spinlock, flags); in recv_ishtp_cl_msg_dma()
1142 list_for_each_entry(rb, &dev->read_list.list, list) { in recv_ishtp_cl_msg_dma()
1143 cl = rb->cl; in recv_ishtp_cl_msg_dma()
1144 if (!cl || !(cl->host_client_id == hbm->host_client_id && in recv_ishtp_cl_msg_dma()
1145 cl->fw_client_id == hbm->fw_client_id) || in recv_ishtp_cl_msg_dma()
1146 !(cl->state == ISHTP_CL_CONNECTED)) in recv_ishtp_cl_msg_dma()
1152 if (rb->buffer.size == 0 || rb->buffer.data == NULL) { in recv_ishtp_cl_msg_dma()
1153 spin_unlock_irqrestore(&dev->read_list_spinlock, flags); in recv_ishtp_cl_msg_dma()
1154 dev_err(&cl->device->dev, in recv_ishtp_cl_msg_dma()
1156 list_del(&rb->list); in recv_ishtp_cl_msg_dma()
1158 cl->status = -ENOMEM; in recv_ishtp_cl_msg_dma()
1164 * size, drop message and return to free buffer. in recv_ishtp_cl_msg_dma()
1168 if (rb->buffer.size < hbm->msg_length) { in recv_ishtp_cl_msg_dma()
1169 spin_unlock_irqrestore(&dev->read_list_spinlock, flags); in recv_ishtp_cl_msg_dma()
1170 dev_err(&cl->device->dev, in recv_ishtp_cl_msg_dma()
1171 "message overflow. size %d len %d idx %ld\n", in recv_ishtp_cl_msg_dma()
1172 rb->buffer.size, hbm->msg_length, rb->buf_idx); in recv_ishtp_cl_msg_dma()
1173 list_del(&rb->list); in recv_ishtp_cl_msg_dma()
1175 cl->status = -EIO; in recv_ishtp_cl_msg_dma()
1179 buffer = rb->buffer.data; in recv_ishtp_cl_msg_dma()
1185 if (dev->ops->dma_no_cache_snooping && in recv_ishtp_cl_msg_dma()
1186 dev->ops->dma_no_cache_snooping(dev)) in recv_ishtp_cl_msg_dma()
1187 clflush_cache_range(msg, hbm->msg_length); in recv_ishtp_cl_msg_dma()
1189 memcpy(buffer, msg, hbm->msg_length); in recv_ishtp_cl_msg_dma()
1190 rb->buf_idx = hbm->msg_length; in recv_ishtp_cl_msg_dma()
1192 /* Last fragment in message - it's complete */ in recv_ishtp_cl_msg_dma()
1193 cl->status = 0; in recv_ishtp_cl_msg_dma()
1194 list_del(&rb->list); in recv_ishtp_cl_msg_dma()
1197 --cl->out_flow_ctrl_creds; in recv_ishtp_cl_msg_dma()
1202 spin_lock(&cl->free_list_spinlock); in recv_ishtp_cl_msg_dma()
1204 if (!list_empty(&cl->free_rb_list.list)) { in recv_ishtp_cl_msg_dma()
1205 new_rb = list_entry(cl->free_rb_list.list.next, in recv_ishtp_cl_msg_dma()
1207 list_del_init(&new_rb->list); in recv_ishtp_cl_msg_dma()
1208 spin_unlock(&cl->free_list_spinlock); in recv_ishtp_cl_msg_dma()
1209 new_rb->cl = cl; in recv_ishtp_cl_msg_dma()
1210 new_rb->buf_idx = 0; in recv_ishtp_cl_msg_dma()
1211 INIT_LIST_HEAD(&new_rb->list); in recv_ishtp_cl_msg_dma()
1212 list_add_tail(&new_rb->list, in recv_ishtp_cl_msg_dma()
1213 &dev->read_list.list); in recv_ishtp_cl_msg_dma()
1217 spin_unlock(&cl->free_list_spinlock); in recv_ishtp_cl_msg_dma()
1221 ++cl->recv_msg_num_frags; in recv_ishtp_cl_msg_dma()
1230 spin_unlock_irqrestore(&dev->read_list_spinlock, flags); in recv_ishtp_cl_msg_dma()
1233 dev_err(dev->devc, "Dropped Rx (DMA) msg - no request\n"); in recv_ishtp_cl_msg_dma()
1238 cl = complete_rb->cl; in recv_ishtp_cl_msg_dma()
1239 cl->ts_rx = ktime_get(); in recv_ishtp_cl_msg_dma()
1240 ++cl->recv_msg_cnt_dma; in recv_ishtp_cl_msg_dma()
1249 return cl->client_data; in ishtp_get_client_data()
1255 cl->client_data = data; in ishtp_set_client_data()
1261 return cl->dev; in ishtp_get_ishtp_device()
1265 void ishtp_set_tx_ring_size(struct ishtp_cl *cl, int size) in ishtp_set_tx_ring_size() argument
1267 cl->tx_ring_size = size; in ishtp_set_tx_ring_size()
1271 void ishtp_set_rx_ring_size(struct ishtp_cl *cl, int size) in ishtp_set_rx_ring_size() argument
1273 cl->rx_ring_size = size; in ishtp_set_rx_ring_size()
1279 cl->state = state; in ishtp_set_connection_state()
1285 cl->fw_client_id = fw_client_id; in ishtp_cl_set_fw_client_id()