Mercurial > ecos
diff packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c @ 208:e0c0827131d1 ecos
Merge from eCos master repository on 2002-05-20-20:11:54-BST
| author | jlarmour |
|---|---|
| date | Mon, 20 May 2002 22:19:26 +0000 |
| parents | 51b34619b677 |
| children | d2c90368aeef |
line wrap: on
line diff
--- a/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c +++ b/packages/devs/eth/cl/cs8900a/current/src/if_cs8900a.c @@ -5,29 +5,38 @@ // Device driver for Cirrus Logic CS8900A ethernet controller // //========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos 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. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### //####BSDCOPYRIGHTBEGIN#### // // ------------------------------------------- @@ -70,8 +79,8 @@ #include <cyg/hal/drv_api.h> #undef __ECOS #define __ECOS -#include <eth_drv.h> -#include <netdev.h> +#include <cyg/io/eth/eth_drv.h> +#include <cyg/io/eth/netdev.h> #include <cyg/io/cs8900.h> @@ -104,6 +113,7 @@ cs8900a_isr(cyg_vector_t vector, cyg_add { cs8900a_priv_data_t* cpd = (cs8900a_priv_data_t *)data; cyg_drv_interrupt_mask(cpd->interrupt); + cyg_drv_interrupt_acknowledge(cpd->interrupt); return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR } @@ -139,7 +149,6 @@ cs8900a_deliver(struct eth_drv_sc *sc) { cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private; // Allow interrupts to happen again - cyg_drv_interrupt_acknowledge(cpd->interrupt); cyg_drv_interrupt_unmask(cpd->interrupt); } #endif @@ -212,6 +221,9 @@ cs8900a_init(struct cyg_netdevtab_entry CYGHWR_CL_CS8900A_PLF_RESET(base); put_reg(base, PP_SelfCtl, PP_SelfCtl_Reset); // Reset chip + + CYGHWR_CL_CS8900A_PLF_POST_RESET(base); + while ((get_reg(base, PP_SelfStat) & PP_SelfStat_InitD) == 0) { if (--timeout <= 0) { #if DEBUG & 8 @@ -308,8 +320,8 @@ cs8900a_start(struct eth_drv_sc *sc, cyg put_reg(base, PP_IntReg, PP_IntReg_IRQ0); // Only possibility put_reg(base, PP_RxCFG, PP_RxCFG_RxOK | PP_RxCFG_CRC | PP_RxCFG_RUNT | PP_RxCFG_EXTRA); - put_reg(base, PP_RxCTL, PP_RxCTL_RxOK | PP_RxCTL_Broadcast | - PP_RxCTL_IA); + cpd->rxmode = PP_RxCTL_RxOK | PP_RxCTL_Broadcast | PP_RxCTL_IA; + put_reg(base, PP_RxCTL, cpd->rxmode); put_reg(base, PP_TxCFG, PP_TxCFG_TxOK | PP_TxCFG_Collision | PP_TxCFG_CRS | PP_TxCFG_SQE | PP_TxCFG_Late | PP_TxCFG_Jabber | PP_TxCFG_16Collisions); @@ -329,10 +341,27 @@ cs8900a_start(struct eth_drv_sc *sc, cyg static int cs8900a_control(struct eth_drv_sc *sc, unsigned long key, void *data, int data_length) { + cs8900a_priv_data_t *cpd = (cs8900a_priv_data_t *)sc->driver_private; + cyg_addrword_t base = cpd->base; + struct eth_drv_mc_list *mc_list = data; + switch (key) { case ETH_DRV_SET_MAC_ADDRESS: return 0; break; + case ETH_DRV_SET_MC_LIST: + case ETH_DRV_SET_MC_ALL: + // Note: this code always accepts all multicast addresses if any + // are desired. It would be possible to accept a subset by adjusting + // the Logical Address Filter (LAF), but that would require scanning + // this list and building a suitable mask. + if (mc_list->len) { + cpd->rxmode |= PP_RxCTL_Multicast; + } else { + cpd->rxmode &= ~PP_RxCTL_Multicast; + } + put_reg(base, PP_RxCTL, cpd->rxmode); // When is it safe to do this? + return 0; default: return 1; break;
