Lines Matching +full:tx +full:- +full:pcs

1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later
3 * Copyright 2008 - 2015 Freescale Semiconductor Inc.
14 #include <linux/pcs-lynx.h>
25 #define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */
29 #define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */
56 #define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */
57 #define IF_MODE_10G 0x00000000 /* 30-31 10G interface */
58 #define IF_MODE_MII 0x00000001 /* 30-31 MII interface */
59 #define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */
62 #define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */
63 #define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */
64 #define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */
71 /* 26-31 Hash table address code */
89 #define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */
90 #define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */
95 #define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */
96 #define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */
97 #define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */
101 #define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */
117 /* Lower 32 bits of 48-bit MAC address */
119 /* Upper 16 bits of 48-bit MAC address */
127 struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */
136 u32 tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */
144 struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS];/* 0x80-0x0B4 mac padr */
204 /* Tx Statistics Counter */
263 u32 thm; /* 0x37C tx messages counter */
310 iowrite32be(tmp0, &regs->mac_addr0.mac_addr_l); in add_addr_in_paddr()
311 iowrite32be(tmp1, &regs->mac_addr0.mac_addr_u); in add_addr_in_paddr()
313 iowrite32be(tmp0, &regs->mac_addr[paddr_num - 1].mac_addr_l); in add_addr_in_paddr()
314 iowrite32be(tmp1, &regs->mac_addr[paddr_num - 1].mac_addr_u); in add_addr_in_paddr()
323 tmp = ioread32be(&regs->command_config); in reset()
327 iowrite32be(tmp, &regs->command_config); in reset()
332 } while ((ioread32be(&regs->command_config) & CMD_CFG_SW_RESET) && in reset()
333 --count); in reset()
336 return -EBUSY; in reset()
346 tmp = ioread32be(&regs->imask); in set_exception()
352 iowrite32be(tmp, &regs->imask); in set_exception()
362 if (cfg->promiscuous_mode_enable) in init()
364 if (cfg->pause_ignore) in init()
374 iowrite32be(tmp, &regs->command_config); in init()
377 iowrite32be((u32)cfg->max_frame_length, &regs->maxfrm); in init()
380 iowrite32be((u32)cfg->pause_quanta, &regs->pause_quanta[0]); in init()
381 iowrite32be((u32)0, &regs->pause_thresh[0]); in init()
383 /* clear all pending events and set-up interrupts */ in init()
384 iowrite32be(0xffffffff, &regs->ievent); in init()
392 cfg->reset_on_init = false; in set_dflts()
393 cfg->promiscuous_mode_enable = false; in set_dflts()
394 cfg->pause_ignore = false; in set_dflts()
395 cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH; in set_dflts()
396 cfg->max_frame_length = DEFAULT_FRAME_LENGTH; in set_dflts()
397 cfg->pause_quanta = DEFAULT_PAUSE_QUANTA; in set_dflts()
416 xor_val |= (mask1 << (5 - i)); in get_mac_addr_hash_code()
424 if (!memac->exception_cb) { in check_init_parameters()
426 return -EINVAL; in check_init_parameters()
428 if (!memac->event_cb) { in check_init_parameters()
430 return -EINVAL; in check_init_parameters()
464 struct memac_regs __iomem *regs = memac->regs; in memac_err_exception()
467 event = ioread32be(&regs->ievent); in memac_err_exception()
468 imask = ioread32be(&regs->imask); in memac_err_exception()
473 * their corresponding location in the ievent - hence the >> 16 in memac_err_exception()
477 iowrite32be(event, &regs->ievent); in memac_err_exception()
480 memac->exception_cb(memac->dev_id, FM_MAC_EX_TS_FIFO_ECC_ERR); in memac_err_exception()
482 memac->exception_cb(memac->dev_id, FM_MAC_EX_10G_TX_ECC_ER); in memac_err_exception()
484 memac->exception_cb(memac->dev_id, FM_MAC_EX_10G_RX_ECC_ER); in memac_err_exception()
490 struct memac_regs __iomem *regs = memac->regs; in memac_exception()
493 event = ioread32be(&regs->ievent); in memac_exception()
494 imask = ioread32be(&regs->imask); in memac_exception()
499 * their corresponding location in the ievent - hence the >> 16 in memac_exception()
503 iowrite32be(event, &regs->ievent); in memac_exception()
506 memac->exception_cb(memac->dev_id, in memac_exception()
512 fman_unregister_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, in free_init_resources()
515 fman_unregister_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, in free_init_resources()
519 free_hash_table(memac->multicast_addr_hash); in free_init_resources()
520 memac->multicast_addr_hash = NULL; in free_init_resources()
523 free_hash_table(memac->unicast_addr_hash); in free_init_resources()
524 memac->unicast_addr_hash = NULL; in free_init_resources()
531 ret = phy_init(memac->serdes); in memac_enable()
533 dev_err(memac->dev_id->dev, in memac_enable()
538 ret = phy_power_on(memac->serdes); in memac_enable()
540 dev_err(memac->dev_id->dev, in memac_enable()
542 phy_exit(memac->serdes); in memac_enable()
550 phy_power_off(memac->serdes); in memac_disable()
551 phy_exit(memac->serdes); in memac_disable()
556 struct memac_regs __iomem *regs = memac->regs; in memac_set_promiscuous()
559 tmp = ioread32be(&regs->command_config); in memac_set_promiscuous()
565 iowrite32be(tmp, &regs->command_config); in memac_set_promiscuous()
573 struct memac_regs __iomem *regs = memac->regs; in memac_set_tx_pause_frames()
576 tmp = ioread32be(&regs->tx_fifo_sections); in memac_set_tx_pause_frames()
579 iowrite32be(tmp, &regs->tx_fifo_sections); in memac_set_tx_pause_frames()
581 tmp = ioread32be(&regs->command_config); in memac_set_tx_pause_frames()
584 iowrite32be(tmp, &regs->command_config); in memac_set_tx_pause_frames()
586 tmp = ioread32be(&regs->pause_quanta[priority / 2]); in memac_set_tx_pause_frames()
592 iowrite32be(tmp, &regs->pause_quanta[priority / 2]); in memac_set_tx_pause_frames()
594 tmp = ioread32be(&regs->pause_thresh[priority / 2]); in memac_set_tx_pause_frames()
600 iowrite32be(tmp, &regs->pause_thresh[priority / 2]); in memac_set_tx_pause_frames()
607 struct memac_regs __iomem *regs = memac->regs; in memac_accept_rx_pause_frames()
610 tmp = ioread32be(&regs->command_config); in memac_accept_rx_pause_frames()
616 iowrite32be(tmp, &regs->command_config); in memac_accept_rx_pause_frames()
625 struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; in memac_validate()
626 unsigned long caps = config->mac_capabilities; in memac_validate()
628 if (phy_interface_mode_is_rgmii(state->interface) && in memac_validate()
629 memac->rgmii_no_half_duplex) in memac_validate()
636 * memac_if_mode() - Convert an interface mode into an IF_MODE config
667 struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; in memac_select_pcs()
672 return memac->sgmii_pcs; in memac_select_pcs()
674 return memac->qsgmii_pcs; in memac_select_pcs()
676 return memac->xfi_pcs; in memac_select_pcs()
685 struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; in memac_prepare()
692 return phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET, in memac_prepare()
703 struct memac_regs __iomem *regs = mac_dev->fman_mac->regs; in memac_mac_config()
704 u32 tmp = ioread32be(&regs->if_mode); in memac_mac_config()
707 tmp |= memac_if_mode(state->interface); in memac_mac_config()
710 iowrite32be(tmp, &regs->if_mode); in memac_mac_config()
718 struct fman_mac *memac = mac_dev->fman_mac; in memac_link_up()
719 struct memac_regs __iomem *regs = memac->regs; in memac_link_up()
741 iowrite32be(tmp, &regs->if_mode); in memac_link_up()
746 if (memac->fm_rev_info.major == 6 && in memac_link_up()
747 memac->fm_rev_info.minor == 4) in memac_link_up()
756 iowrite32be(tmp, &regs->tx_fifo_sections); in memac_link_up()
758 mac_dev->update_speed(mac_dev, speed); in memac_link_up()
760 tmp = ioread32be(&regs->command_config); in memac_link_up()
762 iowrite32be(tmp, &regs->command_config); in memac_link_up()
768 struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; in memac_link_down()
769 struct memac_regs __iomem *regs = memac->regs; in memac_link_down()
773 tmp = ioread32be(&regs->command_config); in memac_link_down()
775 iowrite32be(tmp, &regs->command_config); in memac_link_down()
790 add_addr_in_paddr(memac->regs, (const u8 *)(*enet_addr), 0); in memac_modify_mac_address()
798 struct memac_regs __iomem *regs = memac->regs; in memac_add_hash_mac_address()
808 return -EINVAL; in memac_add_hash_mac_address()
815 return -ENOMEM; in memac_add_hash_mac_address()
816 hash_entry->addr = addr; in memac_add_hash_mac_address()
817 INIT_LIST_HEAD(&hash_entry->node); in memac_add_hash_mac_address()
819 list_add_tail(&hash_entry->node, in memac_add_hash_mac_address()
820 &memac->multicast_addr_hash->lsts[hash]); in memac_add_hash_mac_address()
821 iowrite32be(hash | HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl); in memac_add_hash_mac_address()
829 struct memac_regs __iomem *regs = memac->regs; in memac_set_allmulti()
834 &regs->hashtable_ctrl); in memac_set_allmulti()
838 &regs->hashtable_ctrl); in memac_set_allmulti()
841 memac->allmulti_enabled = enable; in memac_set_allmulti()
854 struct memac_regs __iomem *regs = memac->regs; in memac_del_hash_mac_address()
864 list_for_each(pos, &memac->multicast_addr_hash->lsts[hash]) { in memac_del_hash_mac_address()
866 if (hash_entry && hash_entry->addr == addr) { in memac_del_hash_mac_address()
867 list_del_init(&hash_entry->node); in memac_del_hash_mac_address()
873 if (!memac->allmulti_enabled) { in memac_del_hash_mac_address()
874 if (list_empty(&memac->multicast_addr_hash->lsts[hash])) in memac_del_hash_mac_address()
876 &regs->hashtable_ctrl); in memac_del_hash_mac_address()
890 memac->exceptions |= bit_mask; in memac_set_exception()
892 memac->exceptions &= ~bit_mask; in memac_set_exception()
895 return -EINVAL; in memac_set_exception()
897 set_exception(memac->regs, bit_mask, enable); in memac_set_exception()
913 memac_drv_param = memac->memac_drv_param; in memac_init()
916 if (memac_drv_param->reset_on_init) { in memac_init()
917 err = reset(memac->regs); in memac_init()
925 if (memac->addr != 0) { in memac_init()
926 MAKE_ENET_ADDR_FROM_UINT64(memac->addr, eth_addr); in memac_init()
927 add_addr_in_paddr(memac->regs, (const u8 *)eth_addr, 0); in memac_init()
930 init(memac->regs, memac->memac_drv_param, memac->exceptions); in memac_init()
935 if ((memac->fm_rev_info.major == 6) && in memac_init()
936 ((memac->fm_rev_info.minor == 0) || in memac_init()
937 (memac->fm_rev_info.minor == 3))) { in memac_init()
938 /* MAC strips CRC from received frames - this workaround in memac_init()
941 reg32 = ioread32be(&memac->regs->command_config); in memac_init()
943 iowrite32be(reg32, &memac->regs->command_config); in memac_init()
947 err = fman_set_mac_max_frame(memac->fm, memac->mac_id, in memac_init()
948 memac_drv_param->max_frame_length); in memac_init()
954 memac->multicast_addr_hash = alloc_hash_table(HASH_TABLE_SIZE); in memac_init()
955 if (!memac->multicast_addr_hash) { in memac_init()
958 return -ENOMEM; in memac_init()
961 memac->unicast_addr_hash = alloc_hash_table(HASH_TABLE_SIZE); in memac_init()
962 if (!memac->unicast_addr_hash) { in memac_init()
965 return -ENOMEM; in memac_init()
968 fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, in memac_init()
971 fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, in memac_init()
977 static void pcs_put(struct phylink_pcs *pcs) in pcs_put() argument
979 if (IS_ERR_OR_NULL(pcs)) in pcs_put()
982 lynx_pcs_destroy(pcs); in pcs_put()
989 pcs_put(memac->sgmii_pcs); in memac_free()
990 pcs_put(memac->qsgmii_pcs); in memac_free()
991 pcs_put(memac->xfi_pcs); in memac_free()
992 kfree(memac->memac_drv_param); in memac_free()
1017 memac->memac_drv_param = memac_drv_param; in memac_config()
1021 memac->addr = ENET_ADDR_TO_UINT64(mac_dev->addr); in memac_config()
1023 memac->regs = mac_dev->vaddr; in memac_config()
1024 memac->mac_id = params->mac_id; in memac_config()
1025 memac->exceptions = (MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | in memac_config()
1027 memac->exception_cb = params->exception_cb; in memac_config()
1028 memac->event_cb = params->event_cb; in memac_config()
1029 memac->dev_id = mac_dev; in memac_config()
1030 memac->fm = params->fm; in memac_config()
1033 fman_get_revision(memac->fm, &memac->fm_rev_info); in memac_config()
1042 struct phylink_pcs *pcs; in memac_pcs_create() local
1044 node = of_parse_phandle(mac_node, "pcsphy-handle", index); in memac_pcs_create()
1046 return ERR_PTR(-ENODEV); in memac_pcs_create()
1048 pcs = lynx_pcs_create_fwnode(of_fwnode_handle(node)); in memac_pcs_create()
1051 return pcs; in memac_pcs_create()
1059 if (!mac_dev->fman_mac->serdes) in memac_supports()
1060 return mac_dev->phy_if == iface; in memac_supports()
1062 return !phy_validate(mac_dev->fman_mac->serdes, PHY_MODE_ETHERNET, in memac_supports()
1072 struct phylink_pcs *pcs; in memac_initialization() local
1080 * 10GBASE-R (aka XFI), so just convert it for them. in memac_initialization()
1082 if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII) in memac_initialization()
1083 mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER; in memac_initialization()
1085 mac_dev->phylink_ops = &memac_mac_ops; in memac_initialization()
1086 mac_dev->set_promisc = memac_set_promiscuous; in memac_initialization()
1087 mac_dev->change_addr = memac_modify_mac_address; in memac_initialization()
1088 mac_dev->add_hash_mac_addr = memac_add_hash_mac_address; in memac_initialization()
1089 mac_dev->remove_hash_mac_addr = memac_del_hash_mac_address; in memac_initialization()
1090 mac_dev->set_exception = memac_set_exception; in memac_initialization()
1091 mac_dev->set_allmulti = memac_set_allmulti; in memac_initialization()
1092 mac_dev->set_tstamp = memac_set_tstamp; in memac_initialization()
1093 mac_dev->set_multi = fman_set_multi; in memac_initialization()
1094 mac_dev->enable = memac_enable; in memac_initialization()
1095 mac_dev->disable = memac_disable; in memac_initialization()
1097 mac_dev->fman_mac = memac_config(mac_dev, params); in memac_initialization()
1098 if (!mac_dev->fman_mac) in memac_initialization()
1099 return -EINVAL; in memac_initialization()
1101 memac = mac_dev->fman_mac; in memac_initialization()
1102 memac->memac_drv_param->max_frame_length = fman_get_max_frm(); in memac_initialization()
1103 memac->memac_drv_param->reset_on_init = true; in memac_initialization()
1105 err = of_property_match_string(mac_node, "pcs-handle-names", "xfi"); in memac_initialization()
1107 memac->xfi_pcs = memac_pcs_create(mac_node, err); in memac_initialization()
1108 if (IS_ERR(memac->xfi_pcs)) { in memac_initialization()
1109 err = PTR_ERR(memac->xfi_pcs); in memac_initialization()
1110 dev_err_probe(mac_dev->dev, err, "missing xfi pcs\n"); in memac_initialization()
1113 } else if (err != -EINVAL && err != -ENODATA) { in memac_initialization()
1117 err = of_property_match_string(mac_node, "pcs-handle-names", "qsgmii"); in memac_initialization()
1119 memac->qsgmii_pcs = memac_pcs_create(mac_node, err); in memac_initialization()
1120 if (IS_ERR(memac->qsgmii_pcs)) { in memac_initialization()
1121 err = PTR_ERR(memac->qsgmii_pcs); in memac_initialization()
1122 dev_err_probe(mac_dev->dev, err, in memac_initialization()
1123 "missing qsgmii pcs\n"); in memac_initialization()
1126 } else if (err != -EINVAL && err != -ENODATA) { in memac_initialization()
1130 /* For compatibility, if pcs-handle-names is missing, we assume this in memac_initialization()
1131 * phy is the first one in pcsphy-handle in memac_initialization()
1133 err = of_property_match_string(mac_node, "pcs-handle-names", "sgmii"); in memac_initialization()
1134 if (err == -EINVAL || err == -ENODATA) in memac_initialization()
1135 pcs = memac_pcs_create(mac_node, 0); in memac_initialization()
1139 pcs = memac_pcs_create(mac_node, err); in memac_initialization()
1141 if (IS_ERR(pcs)) { in memac_initialization()
1142 err = PTR_ERR(pcs); in memac_initialization()
1143 dev_err_probe(mac_dev->dev, err, "missing pcs\n"); in memac_initialization()
1147 /* If err is set here, it means that pcs-handle-names was missing above in memac_initialization()
1151 if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_10GBASER) in memac_initialization()
1152 memac->xfi_pcs = pcs; in memac_initialization()
1154 memac->sgmii_pcs = pcs; in memac_initialization()
1156 memac->serdes = devm_of_phy_optional_get(mac_dev->dev, mac_node, in memac_initialization()
1158 if (!memac->serdes) { in memac_initialization()
1159 dev_dbg(mac_dev->dev, "could not get (optional) serdes\n"); in memac_initialization()
1160 } else if (IS_ERR(memac->serdes)) { in memac_initialization()
1161 err = PTR_ERR(memac->serdes); in memac_initialization()
1167 * - 1000BASE-KX in memac_initialization()
1168 * - 10GBASE-KR in memac_initialization()
1169 * - XAUI/HiGig in memac_initialization()
1171 supported = mac_dev->phylink_config.supported_interfaces; in memac_initialization()
1175 if (memac->sgmii_pcs && in memac_initialization()
1182 if (memac->sgmii_pcs && in memac_initialization()
1186 if (memac->qsgmii_pcs && in memac_initialization()
1189 else if (mac_dev->phy_if == PHY_INTERFACE_MODE_QSGMII) in memac_initialization()
1190 dev_warn(mac_dev->dev, "no QSGMII pcs specified\n"); in memac_initialization()
1192 if (memac->xfi_pcs && in memac_initialization()
1213 mac_dev->phylink_config.mac_capabilities = capabilities; in memac_initialization()
1224 memac->rgmii_no_half_duplex = true; in memac_initialization()
1230 * configurations modes don't use in-band autonegotiation. in memac_initialization()
1232 fixed = of_get_child_by_name(mac_node, "fixed-link"); in memac_initialization()
1233 if (!fixed && !of_property_read_bool(mac_node, "fixed-link") && in memac_initialization()
1235 mac_dev->phy_if != PHY_INTERFACE_MODE_MII && in memac_initialization()
1236 !phy_interface_mode_is_rgmii(mac_dev->phy_if)) in memac_initialization()
1237 mac_dev->phylink_config.ovr_an_inband = true; in memac_initialization()
1240 err = memac_init(mac_dev->fman_mac); in memac_initialization()
1244 dev_info(mac_dev->dev, "FMan MEMAC\n"); in memac_initialization()
1249 memac_free(mac_dev->fman_mac); in memac_initialization()