Lines Matching +full:frame +full:- +full:buffer

1 // SPDX-License-Identifier: GPL-2.0
3 * Thunderbolt driver - control channel and configuration commands
23 * struct tb_cfg - thunderbolt control channel
42 dev_WARN(&(ctl)->nhi->pdev->dev, format, ## arg)
45 dev_err(&(ctl)->nhi->pdev->dev, format, ## arg)
48 dev_warn(&(ctl)->nhi->pdev->dev, format, ## arg)
51 dev_info(&(ctl)->nhi->pdev->dev, format, ## arg)
54 dev_dbg(&(ctl)->nhi->pdev->dev, format, ## arg)
61 * tb_cfg_request_alloc() - Allocates a new config request
74 kref_init(&req->kref); in tb_cfg_request_alloc()
80 * tb_cfg_request_get() - Increase refcount of a request
86 kref_get(&req->kref); in tb_cfg_request_get()
98 * tb_cfg_request_put() - Decrease refcount and possibly release the request
107 kref_put(&req->kref, tb_cfg_request_destroy); in tb_cfg_request_put()
114 WARN_ON(test_bit(TB_CFG_REQUEST_ACTIVE, &req->flags)); in tb_cfg_request_enqueue()
115 WARN_ON(req->ctl); in tb_cfg_request_enqueue()
117 mutex_lock(&ctl->request_queue_lock); in tb_cfg_request_enqueue()
118 if (!ctl->running) { in tb_cfg_request_enqueue()
119 mutex_unlock(&ctl->request_queue_lock); in tb_cfg_request_enqueue()
120 return -ENOTCONN; in tb_cfg_request_enqueue()
122 req->ctl = ctl; in tb_cfg_request_enqueue()
123 list_add_tail(&req->list, &ctl->request_queue); in tb_cfg_request_enqueue()
124 set_bit(TB_CFG_REQUEST_ACTIVE, &req->flags); in tb_cfg_request_enqueue()
125 mutex_unlock(&ctl->request_queue_lock); in tb_cfg_request_enqueue()
131 struct tb_ctl *ctl = req->ctl; in tb_cfg_request_dequeue()
133 mutex_lock(&ctl->request_queue_lock); in tb_cfg_request_dequeue()
134 list_del(&req->list); in tb_cfg_request_dequeue()
135 clear_bit(TB_CFG_REQUEST_ACTIVE, &req->flags); in tb_cfg_request_dequeue()
136 if (test_bit(TB_CFG_REQUEST_CANCELED, &req->flags)) in tb_cfg_request_dequeue()
138 mutex_unlock(&ctl->request_queue_lock); in tb_cfg_request_dequeue()
143 return test_bit(TB_CFG_REQUEST_ACTIVE, &req->flags); in tb_cfg_request_is_active()
152 mutex_lock(&pkg->ctl->request_queue_lock); in tb_cfg_request_find()
153 list_for_each_entry(req, &pkg->ctl->request_queue, list) { in tb_cfg_request_find()
155 if (req->match(req, pkg)) { in tb_cfg_request_find()
161 mutex_unlock(&pkg->ctl->request_queue_lock); in tb_cfg_request_find()
172 struct tb_cfg_header *header = pkg->buffer; in check_header()
174 /* check frame, TODO: frame flags */ in check_header()
175 if (WARN(len != pkg->frame.size, in check_header()
177 len, pkg->frame.size)) in check_header()
178 return -EIO; in check_header()
179 if (WARN(type != pkg->frame.eof, "wrong eof (expected %#x, got %#x)\n", in check_header()
180 type, pkg->frame.eof)) in check_header()
181 return -EIO; in check_header()
182 if (WARN(pkg->frame.sof, "wrong sof (expected 0x0, got %#x)\n", in check_header()
183 pkg->frame.sof)) in check_header()
184 return -EIO; in check_header()
187 if (WARN(header->unknown != 1 << 9, in check_header()
188 "header->unknown is %#x\n", header->unknown)) in check_header()
189 return -EIO; in check_header()
193 return -EIO; in check_header()
202 return -EIO; in check_config_address()
205 return -EIO; in check_config_address()
208 return -EIO; in check_config_address()
211 return -EIO; in check_config_address()
213 * We cannot check addr->port as it is set to the upstream port of the in check_config_address()
221 struct cfg_error_pkg *pkg = response->buffer; in decode_error()
223 res.response_route = tb_cfg_get_route(&pkg->header); in decode_error()
226 tb_cfg_get_route(&pkg->header)); in decode_error()
230 WARN(pkg->zero1, "pkg->zero1 is %#x\n", pkg->zero1); in decode_error()
231 WARN(pkg->zero2, "pkg->zero1 is %#x\n", pkg->zero1); in decode_error()
232 WARN(pkg->zero3, "pkg->zero1 is %#x\n", pkg->zero1); in decode_error()
234 res.tb_error = pkg->error; in decode_error()
235 res.response_port = pkg->port; in decode_error()
243 struct tb_cfg_header *header = pkg->buffer; in parse_header()
246 if (pkg->frame.eof == TB_CFG_PKG_ERROR) in parse_header()
258 WARN_ON(res->err != 1); in tb_cfg_print_error()
259 switch (res->tb_error) { in tb_cfg_print_error()
271 res->response_route, res->response_port); in tb_cfg_print_error()
275 * - The route contains a non-existent port. in tb_cfg_print_error()
276 * - The route contains a non-PHY port (e.g. PCIe). in tb_cfg_print_error()
277 * - The port in cfg_read/cfg_write does not exist. in tb_cfg_print_error()
280 res->response_route, res->response_port); in tb_cfg_print_error()
284 res->response_route, res->response_port); in tb_cfg_print_error()
289 res->response_route, res->response_port); in tb_cfg_print_error()
302 dma_pool_free(pkg->ctl->frame_pool, in tb_ctl_pkg_free()
303 pkg->buffer, pkg->frame.buffer_phy); in tb_ctl_pkg_free()
313 pkg->ctl = ctl; in tb_ctl_pkg_alloc()
314 pkg->buffer = dma_pool_alloc(ctl->frame_pool, GFP_KERNEL, in tb_ctl_pkg_alloc()
315 &pkg->frame.buffer_phy); in tb_ctl_pkg_alloc()
316 if (!pkg->buffer) { in tb_ctl_pkg_alloc()
326 static void tb_ctl_tx_callback(struct tb_ring *ring, struct ring_frame *frame, in tb_ctl_tx_callback() argument
329 struct ctl_pkg *pkg = container_of(frame, typeof(*pkg), frame); in tb_ctl_tx_callback()
334 * tb_cfg_tx() - transmit a packet on the control channel
345 if (len % 4 != 0) { /* required for le->be conversion */ in tb_ctl_tx()
347 return -EINVAL; in tb_ctl_tx()
349 if (len > TB_FRAME_SIZE - 4) { /* checksum is 4 bytes */ in tb_ctl_tx()
351 len, TB_FRAME_SIZE - 4); in tb_ctl_tx()
352 return -EINVAL; in tb_ctl_tx()
356 return -ENOMEM; in tb_ctl_tx()
357 pkg->frame.callback = tb_ctl_tx_callback; in tb_ctl_tx()
358 pkg->frame.size = len + 4; in tb_ctl_tx()
359 pkg->frame.sof = type; in tb_ctl_tx()
360 pkg->frame.eof = type; in tb_ctl_tx()
361 cpu_to_be32_array(pkg->buffer, data, len / 4); in tb_ctl_tx()
362 *(__be32 *) (pkg->buffer + len) = tb_crc(pkg->buffer, len); in tb_ctl_tx()
364 res = tb_ring_tx(ctl->tx, &pkg->frame); in tb_ctl_tx()
371 * tb_ctl_handle_event() - acknowledge a plug event, invoke ctl->callback
376 return ctl->callback(ctl->callback_data, type, pkg->buffer, size); in tb_ctl_handle_event()
381 tb_ring_rx(pkg->ctl->rx, &pkg->frame); /* in tb_ctl_rx_submit()
384 * from ctl->rx_packets, so we do in tb_ctl_rx_submit()
393 if (pkg->frame.eof != TB_CFG_PKG_ERROR) in tb_async_error()
396 switch (error->error) { in tb_async_error()
407 static void tb_ctl_rx_callback(struct tb_ring *ring, struct ring_frame *frame, in tb_ctl_rx_callback() argument
410 struct ctl_pkg *pkg = container_of(frame, typeof(*pkg), frame); in tb_ctl_rx_callback()
417 * ctl->rx_packets. in tb_ctl_rx_callback()
420 if (frame->size < 4 || frame->size % 4 != 0) { in tb_ctl_rx_callback()
421 tb_ctl_err(pkg->ctl, "RX: invalid size %#x, dropping packet\n", in tb_ctl_rx_callback()
422 frame->size); in tb_ctl_rx_callback()
426 frame->size -= 4; /* remove checksum */ in tb_ctl_rx_callback()
427 crc32 = tb_crc(pkg->buffer, frame->size); in tb_ctl_rx_callback()
428 be32_to_cpu_array(pkg->buffer, pkg->buffer, frame->size / 4); in tb_ctl_rx_callback()
430 switch (frame->eof) { in tb_ctl_rx_callback()
436 if (*(__be32 *)(pkg->buffer + frame->size) != crc32) { in tb_ctl_rx_callback()
437 tb_ctl_err(pkg->ctl, in tb_ctl_rx_callback()
442 tb_ctl_handle_event(pkg->ctl, frame->eof, in tb_ctl_rx_callback()
443 pkg, frame->size); in tb_ctl_rx_callback()
451 if (*(__be32 *)(pkg->buffer + frame->size) != crc32) { in tb_ctl_rx_callback()
452 tb_ctl_err(pkg->ctl, in tb_ctl_rx_callback()
458 if (tb_ctl_handle_event(pkg->ctl, frame->eof, pkg, frame->size)) in tb_ctl_rx_callback()
472 req = tb_cfg_request_find(pkg->ctl, pkg); in tb_ctl_rx_callback()
474 if (req->copy(req, pkg)) in tb_ctl_rx_callback()
475 schedule_work(&req->work); in tb_ctl_rx_callback()
487 if (!test_bit(TB_CFG_REQUEST_CANCELED, &req->flags)) in tb_cfg_request_work()
488 req->callback(req->callback_data); in tb_cfg_request_work()
495 * tb_cfg_request() - Start control request not waiting for it to complete
509 req->flags = 0; in tb_cfg_request()
510 req->callback = callback; in tb_cfg_request()
511 req->callback_data = callback_data; in tb_cfg_request()
512 INIT_WORK(&req->work, tb_cfg_request_work); in tb_cfg_request()
513 INIT_LIST_HEAD(&req->list); in tb_cfg_request()
520 ret = tb_ctl_tx(ctl, req->request, req->request_size, in tb_cfg_request()
521 req->request_type); in tb_cfg_request()
525 if (!req->response) in tb_cfg_request()
526 schedule_work(&req->work); in tb_cfg_request()
539 * tb_cfg_request_cancel() - Cancel a control request
548 set_bit(TB_CFG_REQUEST_CANCELED, &req->flags); in tb_cfg_request_cancel()
549 schedule_work(&req->work); in tb_cfg_request_cancel()
551 req->result.err = err; in tb_cfg_request_cancel()
560 * tb_cfg_request_sync() - Start control request and wait until it completes
586 tb_cfg_request_cancel(req, -ETIMEDOUT); in tb_cfg_request_sync()
588 flush_work(&req->work); in tb_cfg_request_sync()
590 return req->result; in tb_cfg_request_sync()
596 * tb_ctl_alloc() - allocate a control channel
608 ctl->nhi = nhi; in tb_ctl_alloc()
609 ctl->callback = cb; in tb_ctl_alloc()
610 ctl->callback_data = cb_data; in tb_ctl_alloc()
612 mutex_init(&ctl->request_queue_lock); in tb_ctl_alloc()
613 INIT_LIST_HEAD(&ctl->request_queue); in tb_ctl_alloc()
614 ctl->frame_pool = dma_pool_create("thunderbolt_ctl", &nhi->pdev->dev, in tb_ctl_alloc()
616 if (!ctl->frame_pool) in tb_ctl_alloc()
619 ctl->tx = tb_ring_alloc_tx(nhi, 0, 10, RING_FLAG_NO_SUSPEND); in tb_ctl_alloc()
620 if (!ctl->tx) in tb_ctl_alloc()
623 ctl->rx = tb_ring_alloc_rx(nhi, 0, 10, RING_FLAG_NO_SUSPEND, 0xffff, in tb_ctl_alloc()
625 if (!ctl->rx) in tb_ctl_alloc()
629 ctl->rx_packets[i] = tb_ctl_pkg_alloc(ctl); in tb_ctl_alloc()
630 if (!ctl->rx_packets[i]) in tb_ctl_alloc()
632 ctl->rx_packets[i]->frame.callback = tb_ctl_rx_callback; in tb_ctl_alloc()
643 * tb_ctl_free() - free a control channel
647 * Must NOT be called from ctl->callback.
656 if (ctl->rx) in tb_ctl_free()
657 tb_ring_free(ctl->rx); in tb_ctl_free()
658 if (ctl->tx) in tb_ctl_free()
659 tb_ring_free(ctl->tx); in tb_ctl_free()
663 tb_ctl_pkg_free(ctl->rx_packets[i]); in tb_ctl_free()
666 dma_pool_destroy(ctl->frame_pool); in tb_ctl_free()
671 * tb_cfg_start() - start/resume the control channel
677 tb_ring_start(ctl->tx); /* is used to ack hotplug packets, start first */ in tb_ctl_start()
678 tb_ring_start(ctl->rx); in tb_ctl_start()
680 tb_ctl_rx_submit(ctl->rx_packets[i]); in tb_ctl_start()
682 ctl->running = true; in tb_ctl_start()
686 * control() - pause the control channel
688 * All invocations of ctl->callback will have finished after this method
691 * Must NOT be called from ctl->callback.
695 mutex_lock(&ctl->request_queue_lock); in tb_ctl_stop()
696 ctl->running = false; in tb_ctl_stop()
697 mutex_unlock(&ctl->request_queue_lock); in tb_ctl_stop()
699 tb_ring_stop(ctl->rx); in tb_ctl_stop()
700 tb_ring_stop(ctl->tx); in tb_ctl_stop()
702 if (!list_empty(&ctl->request_queue)) in tb_ctl_stop()
704 INIT_LIST_HEAD(&ctl->request_queue); in tb_ctl_stop()
711 * tb_cfg_error() - send error packet
730 u64 route = tb_cfg_get_route(pkg->buffer) & ~BIT_ULL(63); in tb_cfg_match()
732 if (pkg->frame.eof == TB_CFG_PKG_ERROR) in tb_cfg_match()
735 if (pkg->frame.eof != req->response_type) in tb_cfg_match()
737 if (route != tb_cfg_get_route(req->request)) in tb_cfg_match()
739 if (pkg->frame.size != req->response_size) in tb_cfg_match()
742 if (pkg->frame.eof == TB_CFG_PKG_READ || in tb_cfg_match()
743 pkg->frame.eof == TB_CFG_PKG_WRITE) { in tb_cfg_match()
744 const struct cfg_read_pkg *req_hdr = req->request; in tb_cfg_match()
745 const struct cfg_read_pkg *res_hdr = pkg->buffer; in tb_cfg_match()
747 if (req_hdr->addr.seq != res_hdr->addr.seq) in tb_cfg_match()
759 res = parse_header(pkg, req->response_size, req->response_type, in tb_cfg_copy()
760 tb_cfg_get_route(req->request)); in tb_cfg_copy()
762 memcpy(req->response, pkg->buffer, req->response_size); in tb_cfg_copy()
764 req->result = res; in tb_cfg_copy()
771 * tb_cfg_reset() - send a reset packet and wait for a response
775 * -ETIMEDOUT and attempt to reconfigure the switch.
787 res.err = -ENOMEM; in tb_cfg_reset()
791 req->match = tb_cfg_match; in tb_cfg_reset()
792 req->copy = tb_cfg_copy; in tb_cfg_reset()
793 req->request = &request; in tb_cfg_reset()
794 req->request_size = sizeof(request); in tb_cfg_reset()
795 req->request_type = TB_CFG_PKG_RESET; in tb_cfg_reset()
796 req->response = &reply; in tb_cfg_reset()
797 req->response_size = sizeof(reply); in tb_cfg_reset()
798 req->response_type = TB_CFG_PKG_RESET; in tb_cfg_reset()
808 * tb_cfg_read() - read from config space into buffer
812 struct tb_cfg_result tb_cfg_read_raw(struct tb_ctl *ctl, void *buffer, in tb_cfg_read_raw() argument
834 res.err = -ENOMEM; in tb_cfg_read_raw()
840 req->match = tb_cfg_match; in tb_cfg_read_raw()
841 req->copy = tb_cfg_copy; in tb_cfg_read_raw()
842 req->request = &request; in tb_cfg_read_raw()
843 req->request_size = sizeof(request); in tb_cfg_read_raw()
844 req->request_type = TB_CFG_PKG_READ; in tb_cfg_read_raw()
845 req->response = &reply; in tb_cfg_read_raw()
846 req->response_size = 12 + 4 * length; in tb_cfg_read_raw()
847 req->response_type = TB_CFG_PKG_READ; in tb_cfg_read_raw()
853 if (res.err != -ETIMEDOUT) in tb_cfg_read_raw()
866 memcpy(buffer, &reply.data, 4 * length); in tb_cfg_read_raw()
871 * tb_cfg_write() - write from buffer into config space
875 struct tb_cfg_result tb_cfg_write_raw(struct tb_ctl *ctl, const void *buffer, in tb_cfg_write_raw() argument
892 memcpy(&request.data, buffer, length * 4); in tb_cfg_write_raw()
899 res.err = -ENOMEM; in tb_cfg_write_raw()
905 req->match = tb_cfg_match; in tb_cfg_write_raw()
906 req->copy = tb_cfg_copy; in tb_cfg_write_raw()
907 req->request = &request; in tb_cfg_write_raw()
908 req->request_size = 12 + 4 * length; in tb_cfg_write_raw()
909 req->request_type = TB_CFG_PKG_WRITE; in tb_cfg_write_raw()
910 req->response = &reply; in tb_cfg_write_raw()
911 req->response_size = sizeof(reply); in tb_cfg_write_raw()
912 req->response_type = TB_CFG_PKG_WRITE; in tb_cfg_write_raw()
918 if (res.err != -ETIMEDOUT) in tb_cfg_write_raw()
939 * set to TB_TYPE_INACTIVE). In the former case return -ENODEV so in tb_cfg_get_error()
943 res->tb_error == TB_CFG_ERROR_INVALID_CONFIG_SPACE) in tb_cfg_get_error()
944 return -ENODEV; in tb_cfg_get_error()
947 return -EIO; in tb_cfg_get_error()
950 int tb_cfg_read(struct tb_ctl *ctl, void *buffer, u64 route, u32 port, in tb_cfg_read() argument
953 struct tb_cfg_result res = tb_cfg_read_raw(ctl, buffer, route, port, in tb_cfg_read()
964 case -ETIMEDOUT: in tb_cfg_read()
976 int tb_cfg_write(struct tb_ctl *ctl, const void *buffer, u64 route, u32 port, in tb_cfg_write() argument
979 struct tb_cfg_result res = tb_cfg_write_raw(ctl, buffer, route, port, in tb_cfg_write()
990 case -ETIMEDOUT: in tb_cfg_write()
1003 * tb_cfg_get_upstream_port() - get upstream port number of switch at route
1018 return -EIO; in tb_cfg_get_upstream_port()