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 #pragma ident "%Z%%M% %I% %E% SMI" /* xpak.c */ 27 28 #include "cphy.h" 29 #include "elmer0.h" 30 31 /* ARGSUSED */ 32 static int xpak_reset(struct cphy *cphy, int wait) 33 { 34 return 0; 35 } 36 37 /* ARGSUSED */ 38 static int xpak_interrupt_enable(struct cphy *cphy) 39 { 40 return 0; 41 } 42 43 /* ARGSUSED */ 44 static int xpak_interrupt_disable(struct cphy *cphy) 45 { 46 return 0; 47 } 48 49 /* ARGSUSED */ 50 static int xpak_interrupt_clear(struct cphy *cphy) 51 { 52 return 0; 53 } 54 55 /* ARGSUSED */ 56 static int xpak_set_loopback(struct cphy *cphy, int on) 57 { 58 return 0; 59 } 60 61 /* ARGSUSED */ 62 static int xpak_get_link_status(struct cphy *cphy, int *link_ok, int *speed, 63 int *duplex, int *fc) 64 { 65 if (link_ok) 66 *link_ok = 1; 67 if (speed) 68 *speed = SPEED_10000; 69 if (duplex) 70 *duplex = DUPLEX_FULL; 71 if (fc) 72 *fc = PAUSE_RX | PAUSE_TX; 73 return 0; 74 } 75 76 static void xpak_destroy(struct cphy *cphy) 77 { 78 t1_os_free((void *)cphy, sizeof(*cphy)); 79 } 80 81 #ifdef C99_NOT_SUPPORTED 82 static struct cphy_ops xpak_ops = { 83 xpak_destroy, 84 xpak_reset, 85 xpak_interrupt_enable, 86 xpak_interrupt_disable, 87 xpak_interrupt_clear, 88 NULL, 89 NULL, 90 NULL, 91 NULL, 92 NULL, 93 xpak_set_loopback, 94 NULL, 95 xpak_get_link_status, 96 }; 97 #else 98 static struct cphy_ops xpak_ops = { 99 .destroy = xpak_destroy, 100 .reset = xpak_reset, 101 .interrupt_enable = xpak_interrupt_enable, 102 .interrupt_disable = xpak_interrupt_disable, 103 .interrupt_clear = xpak_interrupt_clear, 104 .get_link_status = xpak_get_link_status, 105 .set_loopback = xpak_set_loopback, 106 }; 107 #endif 108 109 /* ARGSUSED */ 110 static struct cphy *xpak_phy_create(adapter_t * adapter, int phy_addr, 111 struct mdio_ops *mdio_ops) 112 { 113 struct cphy *cphy = t1_os_malloc_wait_zero(sizeof(*cphy)); 114 115 if (!cphy) 116 return NULL; 117 118 cphy->ops = &xpak_ops; 119 cphy->adapter = adapter; 120 cphy->mdio_read = mdio_ops->read; 121 cphy->mdio_write = mdio_ops->write; 122 return cphy; 123 } 124 125 static int xpak_phy_reset(adapter_t *adapter) 126 { 127 u32 val; 128 129 (void) t1_tpi_read(adapter, A_ELMER0_GPO, &val); 130 val &= ~4; 131 (void) t1_tpi_write(adapter, A_ELMER0_GPO, val); 132 DELAY_MS(100); 133 134 /* 135 * Errata #26 states to wait 5 seconds after reset before transceiver 136 * becomes operational. 137 */ 138 (void) t1_tpi_write(adapter, A_ELMER0_GPO, val | 4); 139 DELAY_MS(5000); 140 141 /* Now lets enable the Laser. Delay 100us 142 * as defined in XPAK errata. 143 */ 144 (void) t1_tpi_read(adapter, A_ELMER0_GPO, &val); 145 val |= 0x8000; 146 (void) t1_tpi_write(adapter, A_ELMER0_GPO, val); 147 DELAY_US(100); 148 return 0; 149 } 150 151 struct gphy t1_xpak_ops = { 152 xpak_phy_create, 153 xpak_phy_reset 154 }; 155 156