/* * Copyright (C) 2002-2003 by Call Direct Cellular Solutions Pty. Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgement: * * This product includes software developed by Call Direct Cellular Solutions Pty. Ltd. * and its contributors. * * THIS SOFTWARE IS PROVIDED BY CALL DIRECT CELLULAR SOLUTIONS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CALL DIRECT * CELLULAR SOLUTIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * For additional information see http://www.calldirect.com.au/ * * - * Copyright (C) 2001-2003 by egnite Software GmbH. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgement: * * This product includes software developed by egnite Software GmbH * and its contributors. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * For additional information see http://www.ethernut.de/ * * - * Portions Copyright (C) 2000 David J. Hudson * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You can redistribute this file and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software Foundation; * either version 2 of the License, or (at your discretion) any later version. * See the accompanying file "copying-gpl.txt" for more details. * * As a special exception to the GPL, permission is granted for additional * uses of the text contained in this file. See the accompanying file * "copying-liquorice.txt" for details. * - * Portions Copyright (c) 1983, 1993 by * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /*! * \file arch/avr/dev/cs8900.c * \brief AVR network driver for CS8900A. * * \verbatim * $Id: cs8900.c 4706 2012-10-06 17:42:01Z haraldkipp $ * \endverbatim */ /* Not ported. */ #ifdef __GNUC__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cs8900.h" #ifdef NUTDEBUG #include #include #endif /*! * \addtogroup xgNicCs8900 */ /*@{*/ // Ethernet flags byte // Bit 0 = transmit byte flag uint8_t cs_flags; volatile uint16_t cs_base = 0x0000; void CSWrite16(uint16_t addr, uint16_t data) { uint16_t *p; p = (uint16_t *) addr; cli(); *p = data; sei(); } void CSWritePP16(uint16_t addr, uint16_t data) { uint16_t *p; cli(); p = (uint16_t *) CS_PP_PTR; *p = addr; CSWrite16(CS_PP_DATA0, data); return; } uint16_t CSRead16(uint16_t addr) { uint16_t *p; uint16_t d; cli(); p = (uint16_t *) addr; d = *p; sei(); return d; } uint16_t CSReadPP16(uint16_t addr) { uint16_t *p; cli(); p = (uint16_t *) CS_PP_PTR; *p = addr; return CSRead16(CS_PP_DATA0); } uint32_t CSReadPP32(unsigned int addr) { uint32_t l; uint32_t *p; cli(); p = (uint32_t *) CS_PP_PTR; *p = addr; p = (uint32_t *) CS_PP_DATA0; l = *p; sei(); return l; } void CSBeginFrame(void) { cs_flags &= ~1; } void CSEndFrame(void) { uint8_t *p; cli(); p = (uint8_t *) CS_DATA_P0 + 1; sei(); // If odd number of bytes in packet pad it out if (cs_flags & 1) p = 0; } void CSWriteFrameByte(uint8_t data) { uint8_t *p; if (cs_flags & 1) p = (uint8_t *) CS_DATA_P0 + 1; else p = (uint8_t *) CS_DATA_P0; *p = data; cs_flags ^= 1; } static int CSEthPutPacket(NUTDEVICE * dev, NETBUF * nb) { uint16_t i; uint16_t sz; uint8_t *p; NICINFO *ni; ni = (NICINFO *) dev->dev_dcb; // // Calculate the number of bytes to be send. Do not // send packets larger than 1536 bytes. // sz = nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz; if (sz >= 0x600) { NutNetBufFree(nb); return -1; } #if 0 if (tcp_trace) { NutPrintFormat_P(dev_debug, PSTR("[ETHTX-%u]\r\n"), sz); NutPrintFlush(dev_debug); } #endif // Start transmission after entire frame is loaded into CS8900 CSWrite16(CS_TX_CMD_I, 0xC0); // Set frame size CSWrite16(CS_TX_LEN_I, sz); // Wait for buffer space, but only for a while (200ms) // If the cable is disconnected this will never become true // If we don't get the go ahead within 200ms return 0 (Sucess) // And let the upper layers deal with re-transmission // If we return failure TCP sockets will close straight away which probably // isn't the correct behaviour i = 0; while ((CSReadPP16(CS_BUS_STAT) & 0x0100) == 0) { i++; if (i > 20) return 0; NutSleep(10); } // // Transfer ethernet physical header. // CSBeginFrame(); p = nb->nb_dl.vp; for (i = 0; i < nb->nb_dl.sz; i++) { CSWriteFrameByte(*p++); } p = nb->nb_nw.vp; for (i = 0; i < nb->nb_nw.sz; i++) { CSWriteFrameByte(*p++); } p = nb->nb_tp.vp; for (i = 0; i < nb->nb_tp.sz; i++) { CSWriteFrameByte(*p++); } p = nb->nb_ap.vp; for (i = 0; i < nb->nb_ap.sz; i++) { CSWriteFrameByte(*p++); } CSEndFrame(); return 0; } /*! * \brief Send Ethernet packet. * * \param dev Identifies the device to use. * \param nb Network buffer structure containing the packet to be sent. * The structure must have been allocated by a previous * call NutNetBufAlloc(). This buffer will be automatically * released in case of an error. * * \return 0 on success, -1 in case of any errors. Errors * will automatically release the network buffer * structure. */ int CSNicOutput(NUTDEVICE * dev, NETBUF * nb) { int rc = -1; NICINFO *ni; ni = (NICINFO *) dev->dev_dcb; #if 0 if (tcp_trace) { NutPrintFormat_P(dev_debug, PSTR("Enter EthOutput\r\n")); NutPrintFlush(dev_debug); } #endif if ((rc = CSEthPutPacket(dev, nb)) == 0) ni->ni_tx_packets++; return rc; } /*! \fn CSNICrx(void *arg) * \brief NIC receiver thread. * * * It runs with high priority. */ THREAD(CSNICrx, arg) { NUTDEVICE *dev; IFNET *ifn; NICINFO *ni; NETBUF *nb; uint8_t *p; uint8_t *q; uint16_t i, m; volatile uint16_t l; dev = arg; ifn = (IFNET *) dev->dev_icb; ni = (NICINFO *) dev->dev_dcb; #if 0 if (tcp_trace) { NutPrintFormat_P(dev_debug, PSTR("Enter ETHReceive\r\n")); NutPrintFlush(dev_debug); } #endif l = 0; NutThreadSetPriority(8); for (;;) { while ((CSReadPP16(CS_RX_EVENT) & 0x0100) == 0) { NutSleep(10); } #ifdef NUT_CS8900_OLD // Get the RxStatus But don't let the compiler do any optomisation asm volatile ("lds __tmp_reg__, %3" "\n\t" "mov %B0, __tmp_reg__" "\n\t" "lds __tmp_reg__, %2" "\n\t" "mov %A0, __tmp_reg__" "\n\t":"=r" (l) :"0"(l), "n"((unsigned short) (CS_DATA_P0)), "n"((unsigned short) (CS_DATA_P0 + 1)) ); // Get the Packet Length But don't let the compiler do any optomisation asm volatile ("lds __tmp_reg__, %3" "\n\t" "mov %B0, __tmp_reg__" "\n\t" "lds __tmp_reg__, %2" "\n\t" "mov %A0, __tmp_reg__" "\n\t":"=r" (l) :"0"(l), "n"((unsigned short) (CS_DATA_P0)), "n"((unsigned short) (CS_DATA_P0 + 1)) ); #else l = *(uint8_t *) (CS_DATA_P0 + 1) << 8 | *(uint8_t *) (CS_DATA_P0); l = *(uint8_t *) (CS_DATA_P0 + 1) << 8 | *(uint8_t *) (CS_DATA_P0); #endif //NutPrintFormat_P(dev_debug,PSTR("RxLength = %x \r\n"), l); //NutPrintFlush(dev_debug); // Account for odd length packets if (l & 1) m = l - 1; else m = l; nb = NutNetBufAlloc(0, NBAF_DATALINK, l); if (nb) { q = nb->nb_dl.vp; for (i = 0; i < m; i += 2) { p = (uint8_t *) CS_DATA_P0; *q++ = *p; p = (uint8_t *) CS_DATA_P0 + 1; *q++ = *p; } // Odd length packets if (m != l) { p = (uint8_t *) CS_DATA_P0; *q++ = *p; p = (uint8_t *) CS_DATA_P0 + 1; m = *p; } ni->ni_rx_packets++; (*ifn->if_recv) (dev, nb); } } } void CSSoftwareWakeup(void) { volatile uint16_t *p; p = (uint16_t *) CS_PP_PTR; *p = CS_SELF_CTRL; NutDelay(10); } void CSSoftwareReset(void) { volatile uint16_t *p; p = (uint16_t *) CS_PP_PTR; *p = CS_SELF_CTRL; p = (uint16_t *) CS_DATA_P0; *p = 0x0040; } /*! * \brief Initialize Ethernet Interface. * * * Applications typically do not use this function, but * call NutNetIfConfig(). * * \param dev Identifies the device to initialize. The * structure must be properly set. */ int CSNicInit(NUTDEVICE * dev) { uint16_t i; uint16_t j; IFNET *ifn; NICINFO *ni; #if 0 if (tcp_trace) { NutPrintFormat_P(dev_debug, PSTR("Enter NicInit \r\n")); NutPrintFlush(dev_debug); } #endif cs_base = dev->dev_base; if (confnet.cd_size == 0) NutNetLoadConfig(dev->dev_name); ifn = dev->dev_icb; memcpy(ifn->if_mac, confnet.cdn_mac, 6); memset(dev->dev_dcb, 0, sizeof(NICINFO)); ni = (NICINFO *) dev->dev_dcb; // Take CS8900 out of reset and wait for internal reset to complete #ifdef NUT_CS8900_OLD outb(PORTD, inb(PORTD) & ~RESETE); #else CSSoftwareWakeup(); CSSoftwareReset(); #endif NutDelay(100); // Check for presence if (CSReadPP16(CS_PROD_ID) != 0x630E) return -1; // // Copy our MAC address to the NIC // for (i = 0; i < 6; i += 2) { j = ifn->if_mac[i] << 8; j |= ifn->if_mac[i + 1]; CSWritePP16(CS_IEEE_ADDR + i, j); j = CSReadPP16(CS_IEEE_ADDR + i); #if 0 if (tcp_trace) { NutPrintFormat_P(dev_debug, PSTR("ADDR = %x\r\n"), j); NutPrintFlush(dev_debug); } #endif } // // Enable the Transmitter and Receiver // CSWritePP16(CS_LINE_CTRL, 0x00C0); //i = CSReadPP16(CS_LINE_CTRL); //NutPrintFormat_P(dev_debug,PSTR("CS_LINE_CTRL = %x\r\n"), i); CSWritePP16(CS_RX_CTL, 0x0F40); //i = CSReadPP16(CS_RX_CTL); //NutPrintFormat_P(dev_debug,PSTR("CS_RX_CTL = %x\r\n"), i); // // Start receiver thread // NutThreadCreate("csnicrx", CSNICrx, dev, 500); return 0; } /*@}*/ #else void keep_icc_happy(void) { } #endif