Lines Matching full:tc6

14 /* OPEN Alliance TC6 registers */
158 static int oa_tc6_spi_transfer(struct oa_tc6 *tc6, in oa_tc6_spi_transfer() argument
165 xfer.tx_buf = tc6->spi_data_tx_buf; in oa_tc6_spi_transfer()
166 xfer.rx_buf = tc6->spi_data_rx_buf; in oa_tc6_spi_transfer()
168 xfer.tx_buf = tc6->spi_ctrl_tx_buf; in oa_tc6_spi_transfer()
169 xfer.rx_buf = tc6->spi_ctrl_rx_buf; in oa_tc6_spi_transfer()
176 return spi_sync(tc6->spi, &msg); in oa_tc6_spi_transfer()
209 static void oa_tc6_update_ctrl_write_data(struct oa_tc6 *tc6, u32 value[], in oa_tc6_update_ctrl_write_data() argument
212 __be32 *tx_buf = tc6->spi_ctrl_tx_buf + OA_TC6_CTRL_HEADER_SIZE; in oa_tc6_update_ctrl_write_data()
227 static void oa_tc6_prepare_ctrl_spi_buf(struct oa_tc6 *tc6, u32 address, in oa_tc6_prepare_ctrl_spi_buf() argument
231 __be32 *tx_buf = tc6->spi_ctrl_tx_buf; in oa_tc6_prepare_ctrl_spi_buf()
236 oa_tc6_update_ctrl_write_data(tc6, value, length); in oa_tc6_prepare_ctrl_spi_buf()
239 static int oa_tc6_check_ctrl_write_reply(struct oa_tc6 *tc6, u8 size) in oa_tc6_check_ctrl_write_reply() argument
241 u8 *tx_buf = tc6->spi_ctrl_tx_buf; in oa_tc6_check_ctrl_write_reply()
242 u8 *rx_buf = tc6->spi_ctrl_rx_buf; in oa_tc6_check_ctrl_write_reply()
255 static int oa_tc6_check_ctrl_read_reply(struct oa_tc6 *tc6, u8 size) in oa_tc6_check_ctrl_read_reply() argument
257 u32 *rx_buf = tc6->spi_ctrl_rx_buf + OA_TC6_CTRL_IGNORED_SIZE; in oa_tc6_check_ctrl_read_reply()
258 u32 *tx_buf = tc6->spi_ctrl_tx_buf; in oa_tc6_check_ctrl_read_reply()
269 static void oa_tc6_copy_ctrl_read_data(struct oa_tc6 *tc6, u32 value[], in oa_tc6_copy_ctrl_read_data() argument
272 __be32 *rx_buf = tc6->spi_ctrl_rx_buf + OA_TC6_CTRL_IGNORED_SIZE + in oa_tc6_copy_ctrl_read_data()
279 static int oa_tc6_perform_ctrl(struct oa_tc6 *tc6, u32 address, u32 value[], in oa_tc6_perform_ctrl() argument
286 oa_tc6_prepare_ctrl_spi_buf(tc6, address, value, length, reg_op); in oa_tc6_perform_ctrl()
291 ret = oa_tc6_spi_transfer(tc6, OA_TC6_CTRL_HEADER, size); in oa_tc6_perform_ctrl()
293 dev_err(&tc6->spi->dev, "SPI transfer failed for control: %d\n", in oa_tc6_perform_ctrl()
300 return oa_tc6_check_ctrl_write_reply(tc6, size); in oa_tc6_perform_ctrl()
303 ret = oa_tc6_check_ctrl_read_reply(tc6, size); in oa_tc6_perform_ctrl()
307 oa_tc6_copy_ctrl_read_data(tc6, value, length); in oa_tc6_perform_ctrl()
314 * @tc6: oa_tc6 struct.
323 int oa_tc6_read_registers(struct oa_tc6 *tc6, u32 address, u32 value[], in oa_tc6_read_registers() argument
329 dev_err(&tc6->spi->dev, "Invalid register length parameter\n"); in oa_tc6_read_registers()
333 mutex_lock(&tc6->spi_ctrl_lock); in oa_tc6_read_registers()
334 ret = oa_tc6_perform_ctrl(tc6, address, value, length, in oa_tc6_read_registers()
336 mutex_unlock(&tc6->spi_ctrl_lock); in oa_tc6_read_registers()
344 * @tc6: oa_tc6 struct.
350 int oa_tc6_read_register(struct oa_tc6 *tc6, u32 address, u32 *value) in oa_tc6_read_register() argument
352 return oa_tc6_read_registers(tc6, address, value, 1); in oa_tc6_read_register()
358 * @tc6: oa_tc6 struct.
367 int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, u32 value[], in oa_tc6_write_registers() argument
373 dev_err(&tc6->spi->dev, "Invalid register length parameter\n"); in oa_tc6_write_registers()
377 mutex_lock(&tc6->spi_ctrl_lock); in oa_tc6_write_registers()
378 ret = oa_tc6_perform_ctrl(tc6, address, value, length, in oa_tc6_write_registers()
380 mutex_unlock(&tc6->spi_ctrl_lock); in oa_tc6_write_registers()
388 * @tc6: oa_tc6 struct.
394 int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, u32 value) in oa_tc6_write_register() argument
396 return oa_tc6_write_registers(tc6, address, &value, 1); in oa_tc6_write_register()
400 static int oa_tc6_check_phy_reg_direct_access_capability(struct oa_tc6 *tc6) in oa_tc6_check_phy_reg_direct_access_capability() argument
405 ret = oa_tc6_read_register(tc6, OA_TC6_REG_STDCAP, &regval); in oa_tc6_check_phy_reg_direct_access_capability()
422 struct oa_tc6 *tc6 = bus->priv; in oa_tc6_mdiobus_read() local
426 ret = oa_tc6_read_register(tc6, OA_TC6_PHY_STD_REG_ADDR_BASE | in oa_tc6_mdiobus_read()
438 struct oa_tc6 *tc6 = bus->priv; in oa_tc6_mdiobus_write() local
440 return oa_tc6_write_register(tc6, OA_TC6_PHY_STD_REG_ADDR_BASE | in oa_tc6_mdiobus_write()
466 struct oa_tc6 *tc6 = bus->priv; in oa_tc6_mdiobus_read_c45() local
474 ret = oa_tc6_read_register(tc6, (ret << 16) | regnum, &regval); in oa_tc6_mdiobus_read_c45()
484 struct oa_tc6 *tc6 = bus->priv; in oa_tc6_mdiobus_write_c45() local
491 return oa_tc6_write_register(tc6, (ret << 16) | regnum, val); in oa_tc6_mdiobus_write_c45()
494 static int oa_tc6_mdiobus_register(struct oa_tc6 *tc6) in oa_tc6_mdiobus_register() argument
498 tc6->mdiobus = mdiobus_alloc(); in oa_tc6_mdiobus_register()
499 if (!tc6->mdiobus) { in oa_tc6_mdiobus_register()
500 netdev_err(tc6->netdev, "MDIO bus alloc failed\n"); in oa_tc6_mdiobus_register()
504 tc6->mdiobus->priv = tc6; in oa_tc6_mdiobus_register()
505 tc6->mdiobus->read = oa_tc6_mdiobus_read; in oa_tc6_mdiobus_register()
506 tc6->mdiobus->write = oa_tc6_mdiobus_write; in oa_tc6_mdiobus_register()
517 tc6->mdiobus->read_c45 = oa_tc6_mdiobus_read_c45; in oa_tc6_mdiobus_register()
518 tc6->mdiobus->write_c45 = oa_tc6_mdiobus_write_c45; in oa_tc6_mdiobus_register()
519 tc6->mdiobus->name = "oa-tc6-mdiobus"; in oa_tc6_mdiobus_register()
520 tc6->mdiobus->parent = tc6->dev; in oa_tc6_mdiobus_register()
522 snprintf(tc6->mdiobus->id, ARRAY_SIZE(tc6->mdiobus->id), "%s", in oa_tc6_mdiobus_register()
523 dev_name(&tc6->spi->dev)); in oa_tc6_mdiobus_register()
525 ret = mdiobus_register(tc6->mdiobus); in oa_tc6_mdiobus_register()
527 netdev_err(tc6->netdev, "Could not register MDIO bus\n"); in oa_tc6_mdiobus_register()
528 mdiobus_free(tc6->mdiobus); in oa_tc6_mdiobus_register()
535 static void oa_tc6_mdiobus_unregister(struct oa_tc6 *tc6) in oa_tc6_mdiobus_unregister() argument
537 mdiobus_unregister(tc6->mdiobus); in oa_tc6_mdiobus_unregister()
538 mdiobus_free(tc6->mdiobus); in oa_tc6_mdiobus_unregister()
541 static int oa_tc6_phy_init(struct oa_tc6 *tc6) in oa_tc6_phy_init() argument
545 ret = oa_tc6_check_phy_reg_direct_access_capability(tc6); in oa_tc6_phy_init()
547 netdev_err(tc6->netdev, in oa_tc6_phy_init()
552 ret = oa_tc6_mdiobus_register(tc6); in oa_tc6_phy_init()
556 tc6->phydev = phy_find_first(tc6->mdiobus); in oa_tc6_phy_init()
557 if (!tc6->phydev) { in oa_tc6_phy_init()
558 netdev_err(tc6->netdev, "No PHY found\n"); in oa_tc6_phy_init()
559 oa_tc6_mdiobus_unregister(tc6); in oa_tc6_phy_init()
563 tc6->phydev->is_internal = true; in oa_tc6_phy_init()
564 ret = phy_connect_direct(tc6->netdev, tc6->phydev, in oa_tc6_phy_init()
568 netdev_err(tc6->netdev, "Can't attach PHY to %s\n", in oa_tc6_phy_init()
569 tc6->mdiobus->id); in oa_tc6_phy_init()
570 oa_tc6_mdiobus_unregister(tc6); in oa_tc6_phy_init()
574 phy_attached_info(tc6->netdev->phydev); in oa_tc6_phy_init()
579 static void oa_tc6_phy_exit(struct oa_tc6 *tc6) in oa_tc6_phy_exit() argument
581 phy_disconnect(tc6->phydev); in oa_tc6_phy_exit()
582 oa_tc6_mdiobus_unregister(tc6); in oa_tc6_phy_exit()
585 static int oa_tc6_read_status0(struct oa_tc6 *tc6) in oa_tc6_read_status0() argument
590 ret = oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, &regval); in oa_tc6_read_status0()
592 dev_err(&tc6->spi->dev, "STATUS0 register read failed: %d\n", in oa_tc6_read_status0()
600 static int oa_tc6_sw_reset_macphy(struct oa_tc6 *tc6) in oa_tc6_sw_reset_macphy() argument
605 ret = oa_tc6_write_register(tc6, OA_TC6_REG_RESET, regval); in oa_tc6_sw_reset_macphy()
610 ret = readx_poll_timeout(oa_tc6_read_status0, tc6, regval, in oa_tc6_sw_reset_macphy()
618 return oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, regval); in oa_tc6_sw_reset_macphy()
621 static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6) in oa_tc6_unmask_macphy_error_interrupts() argument
626 ret = oa_tc6_read_register(tc6, OA_TC6_REG_INT_MASK0, &regval); in oa_tc6_unmask_macphy_error_interrupts()
635 return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval); in oa_tc6_unmask_macphy_error_interrupts()
638 static int oa_tc6_enable_data_transfer(struct oa_tc6 *tc6) in oa_tc6_enable_data_transfer() argument
643 ret = oa_tc6_read_register(tc6, OA_TC6_REG_CONFIG0, &value); in oa_tc6_enable_data_transfer()
650 return oa_tc6_write_register(tc6, OA_TC6_REG_CONFIG0, value); in oa_tc6_enable_data_transfer()
653 static void oa_tc6_cleanup_ongoing_rx_skb(struct oa_tc6 *tc6) in oa_tc6_cleanup_ongoing_rx_skb() argument
655 if (tc6->rx_skb) { in oa_tc6_cleanup_ongoing_rx_skb()
656 tc6->netdev->stats.rx_dropped++; in oa_tc6_cleanup_ongoing_rx_skb()
657 kfree_skb(tc6->rx_skb); in oa_tc6_cleanup_ongoing_rx_skb()
658 tc6->rx_skb = NULL; in oa_tc6_cleanup_ongoing_rx_skb()
662 static void oa_tc6_cleanup_ongoing_tx_skb(struct oa_tc6 *tc6) in oa_tc6_cleanup_ongoing_tx_skb() argument
664 if (tc6->ongoing_tx_skb) { in oa_tc6_cleanup_ongoing_tx_skb()
665 tc6->netdev->stats.tx_dropped++; in oa_tc6_cleanup_ongoing_tx_skb()
666 kfree_skb(tc6->ongoing_tx_skb); in oa_tc6_cleanup_ongoing_tx_skb()
667 tc6->ongoing_tx_skb = NULL; in oa_tc6_cleanup_ongoing_tx_skb()
671 static int oa_tc6_process_extended_status(struct oa_tc6 *tc6) in oa_tc6_process_extended_status() argument
676 ret = oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, &value); in oa_tc6_process_extended_status()
678 netdev_err(tc6->netdev, "STATUS0 register read failed: %d\n", in oa_tc6_process_extended_status()
684 ret = oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, value); in oa_tc6_process_extended_status()
686 netdev_err(tc6->netdev, "STATUS0 register write failed: %d\n", in oa_tc6_process_extended_status()
692 tc6->rx_buf_overflow = true; in oa_tc6_process_extended_status()
693 oa_tc6_cleanup_ongoing_rx_skb(tc6); in oa_tc6_process_extended_status()
695 tc6->netdev->name); in oa_tc6_process_extended_status()
699 netdev_err(tc6->netdev, "Transmit protocol error\n"); in oa_tc6_process_extended_status()
706 netdev_err(tc6->netdev, "Loss of frame error\n"); in oa_tc6_process_extended_status()
710 netdev_err(tc6->netdev, "Header error\n"); in oa_tc6_process_extended_status()
717 static int oa_tc6_process_rx_chunk_footer(struct oa_tc6 *tc6, u32 footer) in oa_tc6_process_rx_chunk_footer() argument
724 tc6->tx_credits = FIELD_GET(OA_TC6_DATA_FOOTER_TX_CREDITS, footer); in oa_tc6_process_rx_chunk_footer()
725 tc6->rx_chunks_available = FIELD_GET(OA_TC6_DATA_FOOTER_RX_CHUNKS, in oa_tc6_process_rx_chunk_footer()
729 int ret = oa_tc6_process_extended_status(tc6); in oa_tc6_process_rx_chunk_footer()
740 netdev_err(tc6->netdev, "Rxd header bad error\n"); in oa_tc6_process_rx_chunk_footer()
745 netdev_err(tc6->netdev, "Config unsync error\n"); in oa_tc6_process_rx_chunk_footer()
752 static void oa_tc6_submit_rx_skb(struct oa_tc6 *tc6) in oa_tc6_submit_rx_skb() argument
754 tc6->rx_skb->protocol = eth_type_trans(tc6->rx_skb, tc6->netdev); in oa_tc6_submit_rx_skb()
755 tc6->netdev->stats.rx_packets++; in oa_tc6_submit_rx_skb()
756 tc6->netdev->stats.rx_bytes += tc6->rx_skb->len; in oa_tc6_submit_rx_skb()
758 netif_rx(tc6->rx_skb); in oa_tc6_submit_rx_skb()
760 tc6->rx_skb = NULL; in oa_tc6_submit_rx_skb()
763 static void oa_tc6_update_rx_skb(struct oa_tc6 *tc6, u8 *payload, u8 length) in oa_tc6_update_rx_skb() argument
765 memcpy(skb_put(tc6->rx_skb, length), payload, length); in oa_tc6_update_rx_skb()
768 static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6) in oa_tc6_allocate_rx_skb() argument
770 tc6->rx_skb = netdev_alloc_skb_ip_align(tc6->netdev, tc6->netdev->mtu + in oa_tc6_allocate_rx_skb()
772 if (!tc6->rx_skb) { in oa_tc6_allocate_rx_skb()
773 tc6->netdev->stats.rx_dropped++; in oa_tc6_allocate_rx_skb()
780 static int oa_tc6_prcs_complete_rx_frame(struct oa_tc6 *tc6, u8 *payload, in oa_tc6_prcs_complete_rx_frame() argument
785 ret = oa_tc6_allocate_rx_skb(tc6); in oa_tc6_prcs_complete_rx_frame()
789 oa_tc6_update_rx_skb(tc6, payload, size); in oa_tc6_prcs_complete_rx_frame()
791 oa_tc6_submit_rx_skb(tc6); in oa_tc6_prcs_complete_rx_frame()
796 static int oa_tc6_prcs_rx_frame_start(struct oa_tc6 *tc6, u8 *payload, u16 size) in oa_tc6_prcs_rx_frame_start() argument
800 ret = oa_tc6_allocate_rx_skb(tc6); in oa_tc6_prcs_rx_frame_start()
804 oa_tc6_update_rx_skb(tc6, payload, size); in oa_tc6_prcs_rx_frame_start()
809 static void oa_tc6_prcs_rx_frame_end(struct oa_tc6 *tc6, u8 *payload, u16 size) in oa_tc6_prcs_rx_frame_end() argument
811 oa_tc6_update_rx_skb(tc6, payload, size); in oa_tc6_prcs_rx_frame_end()
813 oa_tc6_submit_rx_skb(tc6); in oa_tc6_prcs_rx_frame_end()
816 static void oa_tc6_prcs_ongoing_rx_frame(struct oa_tc6 *tc6, u8 *payload, in oa_tc6_prcs_ongoing_rx_frame() argument
819 oa_tc6_update_rx_skb(tc6, payload, OA_TC6_CHUNK_PAYLOAD_SIZE); in oa_tc6_prcs_ongoing_rx_frame()
822 static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data, in oa_tc6_prcs_rx_chunk_payload() argument
834 if (start_valid && tc6->rx_buf_overflow) in oa_tc6_prcs_rx_chunk_payload()
835 tc6->rx_buf_overflow = false; in oa_tc6_prcs_rx_chunk_payload()
837 if (tc6->rx_buf_overflow) in oa_tc6_prcs_rx_chunk_payload()
843 return oa_tc6_prcs_complete_rx_frame(tc6, in oa_tc6_prcs_rx_chunk_payload()
851 return oa_tc6_prcs_rx_frame_start(tc6, in oa_tc6_prcs_rx_chunk_payload()
859 oa_tc6_prcs_rx_frame_end(tc6, data, size); in oa_tc6_prcs_rx_chunk_payload()
871 if (tc6->rx_skb) { in oa_tc6_prcs_rx_chunk_payload()
873 oa_tc6_prcs_rx_frame_end(tc6, data, size); in oa_tc6_prcs_rx_chunk_payload()
876 return oa_tc6_prcs_rx_frame_start(tc6, in oa_tc6_prcs_rx_chunk_payload()
882 oa_tc6_prcs_ongoing_rx_frame(tc6, data, footer); in oa_tc6_prcs_rx_chunk_payload()
887 static u32 oa_tc6_get_rx_chunk_footer(struct oa_tc6 *tc6, u16 footer_offset) in oa_tc6_get_rx_chunk_footer() argument
889 u8 *rx_buf = tc6->spi_data_rx_buf; in oa_tc6_get_rx_chunk_footer()
897 static int oa_tc6_process_spi_data_rx_buf(struct oa_tc6 *tc6, u16 length) in oa_tc6_process_spi_data_rx_buf() argument
906 footer = oa_tc6_get_rx_chunk_footer(tc6, i * OA_TC6_CHUNK_SIZE + in oa_tc6_process_spi_data_rx_buf()
909 ret = oa_tc6_process_rx_chunk_footer(tc6, footer); in oa_tc6_process_spi_data_rx_buf()
918 u8 *payload = tc6->spi_data_rx_buf + i * in oa_tc6_process_spi_data_rx_buf()
921 ret = oa_tc6_prcs_rx_chunk_payload(tc6, payload, in oa_tc6_process_spi_data_rx_buf()
948 static void oa_tc6_add_tx_skb_to_spi_buf(struct oa_tc6 *tc6) in oa_tc6_add_tx_skb_to_spi_buf() argument
951 __be32 *tx_buf = tc6->spi_data_tx_buf + tc6->spi_data_tx_buf_offset; in oa_tc6_add_tx_skb_to_spi_buf()
952 u16 remaining_len = tc6->ongoing_tx_skb->len - tc6->tx_skb_offset; in oa_tc6_add_tx_skb_to_spi_buf()
953 u8 *tx_skb_data = tc6->ongoing_tx_skb->data + tc6->tx_skb_offset; in oa_tc6_add_tx_skb_to_spi_buf()
966 if (!tc6->tx_skb_offset) in oa_tc6_add_tx_skb_to_spi_buf()
977 tc6->tx_skb_offset += length_to_copy; in oa_tc6_add_tx_skb_to_spi_buf()
982 if (tc6->ongoing_tx_skb->len == tc6->tx_skb_offset) { in oa_tc6_add_tx_skb_to_spi_buf()
985 tc6->tx_skb_offset = 0; in oa_tc6_add_tx_skb_to_spi_buf()
986 tc6->netdev->stats.tx_bytes += tc6->ongoing_tx_skb->len; in oa_tc6_add_tx_skb_to_spi_buf()
987 tc6->netdev->stats.tx_packets++; in oa_tc6_add_tx_skb_to_spi_buf()
988 kfree_skb(tc6->ongoing_tx_skb); in oa_tc6_add_tx_skb_to_spi_buf()
989 tc6->ongoing_tx_skb = NULL; in oa_tc6_add_tx_skb_to_spi_buf()
994 tc6->spi_data_tx_buf_offset += OA_TC6_CHUNK_SIZE; in oa_tc6_add_tx_skb_to_spi_buf()
997 static u16 oa_tc6_prepare_spi_tx_buf_for_tx_skbs(struct oa_tc6 *tc6) in oa_tc6_prepare_spi_tx_buf_for_tx_skbs() argument
1004 for (used_tx_credits = 0; used_tx_credits < tc6->tx_credits; in oa_tc6_prepare_spi_tx_buf_for_tx_skbs()
1006 if (!tc6->ongoing_tx_skb) { in oa_tc6_prepare_spi_tx_buf_for_tx_skbs()
1007 tc6->ongoing_tx_skb = tc6->waiting_tx_skb; in oa_tc6_prepare_spi_tx_buf_for_tx_skbs()
1008 tc6->waiting_tx_skb = NULL; in oa_tc6_prepare_spi_tx_buf_for_tx_skbs()
1010 if (!tc6->ongoing_tx_skb) in oa_tc6_prepare_spi_tx_buf_for_tx_skbs()
1012 oa_tc6_add_tx_skb_to_spi_buf(tc6); in oa_tc6_prepare_spi_tx_buf_for_tx_skbs()
1018 static void oa_tc6_add_empty_chunks_to_spi_buf(struct oa_tc6 *tc6, in oa_tc6_add_empty_chunks_to_spi_buf() argument
1028 __be32 *tx_buf = tc6->spi_data_tx_buf + in oa_tc6_add_empty_chunks_to_spi_buf()
1029 tc6->spi_data_tx_buf_offset; in oa_tc6_add_empty_chunks_to_spi_buf()
1032 tc6->spi_data_tx_buf_offset += OA_TC6_CHUNK_SIZE; in oa_tc6_add_empty_chunks_to_spi_buf()
1036 static u16 oa_tc6_prepare_spi_tx_buf_for_rx_chunks(struct oa_tc6 *tc6, u16 len) in oa_tc6_prepare_spi_tx_buf_for_rx_chunks() argument
1045 if (tx_chunks >= tc6->rx_chunks_available) in oa_tc6_prepare_spi_tx_buf_for_rx_chunks()
1048 needed_empty_chunks = tc6->rx_chunks_available - tx_chunks; in oa_tc6_prepare_spi_tx_buf_for_rx_chunks()
1050 oa_tc6_add_empty_chunks_to_spi_buf(tc6, needed_empty_chunks); in oa_tc6_prepare_spi_tx_buf_for_rx_chunks()
1055 static int oa_tc6_try_spi_transfer(struct oa_tc6 *tc6) in oa_tc6_try_spi_transfer() argument
1062 tc6->spi_data_tx_buf_offset = 0; in oa_tc6_try_spi_transfer()
1064 if (tc6->ongoing_tx_skb || tc6->waiting_tx_skb) in oa_tc6_try_spi_transfer()
1065 spi_len = oa_tc6_prepare_spi_tx_buf_for_tx_skbs(tc6); in oa_tc6_try_spi_transfer()
1067 spi_len = oa_tc6_prepare_spi_tx_buf_for_rx_chunks(tc6, spi_len); in oa_tc6_try_spi_transfer()
1069 if (tc6->int_flag) { in oa_tc6_try_spi_transfer()
1070 tc6->int_flag = false; in oa_tc6_try_spi_transfer()
1072 oa_tc6_add_empty_chunks_to_spi_buf(tc6, 1); in oa_tc6_try_spi_transfer()
1080 ret = oa_tc6_spi_transfer(tc6, OA_TC6_DATA_HEADER, spi_len); in oa_tc6_try_spi_transfer()
1082 netdev_err(tc6->netdev, "SPI data transfer failed: %d\n", in oa_tc6_try_spi_transfer()
1087 ret = oa_tc6_process_spi_data_rx_buf(tc6, spi_len); in oa_tc6_try_spi_transfer()
1092 oa_tc6_cleanup_ongoing_tx_skb(tc6); in oa_tc6_try_spi_transfer()
1093 oa_tc6_cleanup_ongoing_rx_skb(tc6); in oa_tc6_try_spi_transfer()
1094 netdev_err(tc6->netdev, "Device error: %d\n", ret); in oa_tc6_try_spi_transfer()
1098 if (!tc6->waiting_tx_skb && netif_queue_stopped(tc6->netdev)) in oa_tc6_try_spi_transfer()
1099 netif_wake_queue(tc6->netdev); in oa_tc6_try_spi_transfer()
1107 struct oa_tc6 *tc6 = data; in oa_tc6_spi_thread_handler() local
1114 wait_event_interruptible(tc6->spi_wq, tc6->waiting_tx_skb || in oa_tc6_spi_thread_handler()
1115 tc6->int_flag || in oa_tc6_spi_thread_handler()
1121 ret = oa_tc6_try_spi_transfer(tc6); in oa_tc6_spi_thread_handler()
1129 static int oa_tc6_update_buffer_status_from_register(struct oa_tc6 *tc6) in oa_tc6_update_buffer_status_from_register() argument
1138 ret = oa_tc6_read_register(tc6, OA_TC6_REG_BUFFER_STATUS, &value); in oa_tc6_update_buffer_status_from_register()
1142 tc6->tx_credits = FIELD_GET(BUFFER_STATUS_TX_CREDITS_AVAILABLE, value); in oa_tc6_update_buffer_status_from_register()
1143 tc6->rx_chunks_available = FIELD_GET(BUFFER_STATUS_RX_CHUNKS_AVAILABLE, in oa_tc6_update_buffer_status_from_register()
1151 struct oa_tc6 *tc6 = data; in oa_tc6_macphy_isr() local
1160 tc6->int_flag = true; in oa_tc6_macphy_isr()
1162 wake_up_interruptible(&tc6->spi_wq); in oa_tc6_macphy_isr()
1170 * @tc6: oa_tc6 struct.
1174 int oa_tc6_zero_align_receive_frame_enable(struct oa_tc6 *tc6) in oa_tc6_zero_align_receive_frame_enable() argument
1179 ret = oa_tc6_read_register(tc6, OA_TC6_REG_CONFIG0, &regval); in oa_tc6_zero_align_receive_frame_enable()
1186 return oa_tc6_write_register(tc6, OA_TC6_REG_CONFIG0, regval); in oa_tc6_zero_align_receive_frame_enable()
1193 * @tc6: oa_tc6 struct.
1199 netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, struct sk_buff *skb) in oa_tc6_start_xmit() argument
1201 if (tc6->waiting_tx_skb) { in oa_tc6_start_xmit()
1202 netif_stop_queue(tc6->netdev); in oa_tc6_start_xmit()
1208 tc6->netdev->stats.tx_dropped++; in oa_tc6_start_xmit()
1212 tc6->waiting_tx_skb = skb; in oa_tc6_start_xmit()
1215 wake_up_interruptible(&tc6->spi_wq); in oa_tc6_start_xmit()
1231 struct oa_tc6 *tc6; in oa_tc6_init() local
1234 tc6 = devm_kzalloc(&spi->dev, sizeof(*tc6), GFP_KERNEL); in oa_tc6_init()
1235 if (!tc6) in oa_tc6_init()
1238 tc6->spi = spi; in oa_tc6_init()
1239 tc6->netdev = netdev; in oa_tc6_init()
1241 mutex_init(&tc6->spi_ctrl_lock); in oa_tc6_init()
1244 tc6->spi->rt = true; in oa_tc6_init()
1245 spi_setup(tc6->spi); in oa_tc6_init()
1247 tc6->spi_ctrl_tx_buf = devm_kzalloc(&tc6->spi->dev, in oa_tc6_init()
1250 if (!tc6->spi_ctrl_tx_buf) in oa_tc6_init()
1253 tc6->spi_ctrl_rx_buf = devm_kzalloc(&tc6->spi->dev, in oa_tc6_init()
1256 if (!tc6->spi_ctrl_rx_buf) in oa_tc6_init()
1259 tc6->spi_data_tx_buf = devm_kzalloc(&tc6->spi->dev, in oa_tc6_init()
1262 if (!tc6->spi_data_tx_buf) in oa_tc6_init()
1265 tc6->spi_data_rx_buf = devm_kzalloc(&tc6->spi->dev, in oa_tc6_init()
1268 if (!tc6->spi_data_rx_buf) in oa_tc6_init()
1271 ret = oa_tc6_sw_reset_macphy(tc6); in oa_tc6_init()
1273 dev_err(&tc6->spi->dev, in oa_tc6_init()
1278 ret = oa_tc6_unmask_macphy_error_interrupts(tc6); in oa_tc6_init()
1280 dev_err(&tc6->spi->dev, in oa_tc6_init()
1285 ret = oa_tc6_phy_init(tc6); in oa_tc6_init()
1287 dev_err(&tc6->spi->dev, in oa_tc6_init()
1292 ret = oa_tc6_enable_data_transfer(tc6); in oa_tc6_init()
1294 dev_err(&tc6->spi->dev, "Failed to enable data transfer: %d\n", in oa_tc6_init()
1299 ret = oa_tc6_update_buffer_status_from_register(tc6); in oa_tc6_init()
1301 dev_err(&tc6->spi->dev, in oa_tc6_init()
1306 init_waitqueue_head(&tc6->spi_wq); in oa_tc6_init()
1308 tc6->spi_thread = kthread_run(oa_tc6_spi_thread_handler, tc6, in oa_tc6_init()
1309 "oa-tc6-spi-thread"); in oa_tc6_init()
1310 if (IS_ERR(tc6->spi_thread)) { in oa_tc6_init()
1311 dev_err(&tc6->spi->dev, "Failed to create SPI thread\n"); in oa_tc6_init()
1315 sched_set_fifo(tc6->spi_thread); in oa_tc6_init()
1317 ret = devm_request_irq(&tc6->spi->dev, tc6->spi->irq, oa_tc6_macphy_isr, in oa_tc6_init()
1318 IRQF_TRIGGER_FALLING, dev_name(&tc6->spi->dev), in oa_tc6_init()
1319 tc6); in oa_tc6_init()
1321 dev_err(&tc6->spi->dev, "Failed to request macphy isr %d\n", in oa_tc6_init()
1332 tc6->int_flag = true; in oa_tc6_init()
1333 wake_up_interruptible(&tc6->spi_wq); in oa_tc6_init()
1335 return tc6; in oa_tc6_init()
1338 kthread_stop(tc6->spi_thread); in oa_tc6_init()
1340 oa_tc6_phy_exit(tc6); in oa_tc6_init()
1347 * @tc6: oa_tc6 struct.
1349 void oa_tc6_exit(struct oa_tc6 *tc6) in oa_tc6_exit() argument
1351 oa_tc6_phy_exit(tc6); in oa_tc6_exit()
1352 kthread_stop(tc6->spi_thread); in oa_tc6_exit()
1353 dev_kfree_skb_any(tc6->ongoing_tx_skb); in oa_tc6_exit()
1354 dev_kfree_skb_any(tc6->waiting_tx_skb); in oa_tc6_exit()
1355 dev_kfree_skb_any(tc6->rx_skb); in oa_tc6_exit()