1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (C) 2003-2005 Chelsio Communications. All rights reserved. 24 */ 25 26 #include "cphy.h" 27 #include "elmer0.h" 28 29 /* ARGSUSED */ 30 static int xpak_reset(struct cphy *cphy, int wait) 31 { 32 return 0; 33 } 34 35 /* ARGSUSED */ 36 static int xpak_interrupt_enable(struct cphy *cphy) 37 { 38 return 0; 39 } 40 41 /* ARGSUSED */ 42 static int xpak_interrupt_disable(struct cphy *cphy) 43 { 44 return 0; 45 } 46 47 /* ARGSUSED */ 48 static int xpak_interrupt_clear(struct cphy *cphy) 49 { 50 return 0; 51 } 52 53 /* ARGSUSED */ 54 static int xpak_set_loopback(struct cphy *cphy, int on) 55 { 56 return 0; 57 } 58 59 /* ARGSUSED */ 60 static int xpak_get_link_status(struct cphy *cphy, int *link_ok, int *speed, 61 int *duplex, int *fc) 62 { 63 if (link_ok) 64 *link_ok = 1; 65 if (speed) 66 *speed = SPEED_10000; 67 if (duplex) 68 *duplex = DUPLEX_FULL; 69 if (fc) 70 *fc = PAUSE_RX | PAUSE_TX; 71 return 0; 72 } 73 74 static void xpak_destroy(struct cphy *cphy) 75 { 76 t1_os_free((void *)cphy, sizeof(*cphy)); 77 } 78 79 #ifdef C99_NOT_SUPPORTED 80 static struct cphy_ops xpak_ops = { 81 xpak_destroy, 82 xpak_reset, 83 xpak_interrupt_enable, 84 xpak_interrupt_disable, 85 xpak_interrupt_clear, 86 NULL, 87 NULL, 88 NULL, 89 NULL, 90 NULL, 91 xpak_set_loopback, 92 NULL, 93 xpak_get_link_status, 94 }; 95 #else 96 static struct cphy_ops xpak_ops = { 97 .destroy = xpak_destroy, 98 .reset = xpak_reset, 99 .interrupt_enable = xpak_interrupt_enable, 100 .interrupt_disable = xpak_interrupt_disable, 101 .interrupt_clear = xpak_interrupt_clear, 102 .get_link_status = xpak_get_link_status, 103 .set_loopback = xpak_set_loopback, 104 }; 105 #endif 106 107 /* ARGSUSED */ 108 static struct cphy *xpak_phy_create(adapter_t * adapter, int phy_addr, 109 struct mdio_ops *mdio_ops) 110 { 111 struct cphy *cphy = t1_os_malloc_wait_zero(sizeof(*cphy)); 112 113 if (!cphy) 114 return NULL; 115 116 cphy->ops = &xpak_ops; 117 cphy->adapter = adapter; 118 cphy->mdio_read = mdio_ops->read; 119 cphy->mdio_write = mdio_ops->write; 120 return cphy; 121 } 122 123 static int xpak_phy_reset(adapter_t *adapter) 124 { 125 u32 val; 126 127 (void) t1_tpi_read(adapter, A_ELMER0_GPO, &val); 128 val &= ~4; 129 (void) t1_tpi_write(adapter, A_ELMER0_GPO, val); 130 DELAY_MS(100); 131 132 /* 133 * Errata #26 states to wait 5 seconds after reset before transceiver 134 * becomes operational. 135 */ 136 (void) t1_tpi_write(adapter, A_ELMER0_GPO, val | 4); 137 DELAY_MS(5000); 138 139 /* Now lets enable the Laser. Delay 100us 140 * as defined in XPAK errata. 141 */ 142 (void) t1_tpi_read(adapter, A_ELMER0_GPO, &val); 143 val |= 0x8000; 144 (void) t1_tpi_write(adapter, A_ELMER0_GPO, val); 145 DELAY_US(100); 146 return 0; 147 } 148 149 struct gphy t1_xpak_ops = { 150 xpak_phy_create, 151 xpak_phy_reset 152 }; 153 154