⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_edb7xxx.c

📁 Intel XScale PXA255 引导Linux的Redboot 版bootloader源代码!
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      dev/if_edb7xxx.c////      Ethernet device driver for Cirrus Logic EDB7xxx using CS8900////==========================================================================//####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 Red Hat, Inc.                             // All Rights Reserved.                                                     // -------------------------------------------                              //                                                                          //####COPYRIGHTEND####//####BSDCOPYRIGHTBEGIN####//// -------------------------------------------//// Portions of this software may have been derived from OpenBSD or other sources,// and are covered by the appropriate copyright disclaimers included herein.//// -------------------------------------------////####BSDCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    gthomas// Contributors: gthomas// Date:         2000-01-10// Purpose:      // Description:  hardware driver for CS8900 ethernet//              ////####DESCRIPTIONEND####////==========================================================================// Ethernet device driver for Cirrus Logic EDB7xxx// Based on CS8900A#include <pkgconf/system.h>#include <pkgconf/devs_eth_arm_edb7xxx.h>#ifdef CYGPKG_NET#include <pkgconf/net.h>#include <cyg/kernel/kapi.h>#endif#include <cyg/infra/cyg_type.h>#include <cyg/hal/hal_arch.h>#include <cyg/hal/hal_intr.h>#include <cyg/infra/diag.h>#include <cyg/hal/drv_api.h>#include <netdev.h>#include <eth_drv.h>#ifndef CYGSEM_ARM_EDB7XXX_SET_ESA#ifdef CYGPKG_REDBOOT#include <pkgconf/redboot.h>#ifdef CYGSEM_REDBOOT_FLASH_CONFIG#include <redboot.h>#include <flash_config.h>RedBoot_config_option("Network hardware address [MAC]",                      edb7xxx_esa,                      ALWAYS_ENABLED, true,                      CONFIG_ESA    );#endif#endif#endif#define INTS_DONT_WORK#undef  INTS_DONT_WORK#ifdef INTS_DONT_WORK#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUMstatic char cs8900_fake_int_stack[STACK_SIZE];static cyg_thread cs8900_fake_int_thread_data;static cyg_handle_t cs8900_fake_int_thread_handle;static void cs8900_fake_int(cyg_addrword_t);#endif#define  CS8900_BASE 0x20000000#include "cs8900.h"#define ETHER_ADDR_LEN 6extern int net_debug; // FIXMEstruct cs8900_priv_data {    int txbusy;            // A packet has been sent    unsigned long txkey;   // Used to ack when packet sent#ifdef CYGPKG_NET    cyg_tick_count_t txstart;#endif} _cs8900_priv_data;ETH_DRV_SC(edb7xxx_sc,           &_cs8900_priv_data, // Driver specific data           "eth0",             // Name for this interface           cs8900_start,           cs8900_stop,           cs8900_control,           cs8900_can_send,           cs8900_send,           cs8900_recv,           cs8900_deliver,     // "pseudoDSR" called from fast net thread           cs8900_int,         // poll function, encapsulates ISR and DSR           cs8900_int_vector);NETDEVTAB_ENTRY(edb7xxx_netdev,                 "edb7xxx",                 edb7xxx_cs8900_init,                 &edb7xxx_sc);#ifdef CYGSEM_ARM_EDB7XXX_SET_ESAstatic unsigned char enaddr[] = CYGDAT_ARM_EDB7XXX_ESA;#elsestatic unsigned char enaddr[ETHER_ADDR_LEN];#endifstatic void cs8900_int(struct eth_drv_sc *sc);static cyg_interrupt cs8900_interrupt;static cyg_handle_t  cs8900_interrupt_handle;// This ISR is called when the ethernet interrupt occursstatic intcs8900_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs){    cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_EINT3);    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR}// The deliver function (ex-DSR)  handles the ethernet [logical] processingstatic voidcs8900_deliver(struct eth_drv_sc *sc){    cs8900_int(sc);    // Allow interrupts to happen again    cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_EINT3);    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT3);}static intcs8900_int_vector(struct eth_drv_sc *sc){    return (CYGNUM_HAL_INTERRUPT_EINT3);}static bool edb7xxx_cs8900_init(struct cyg_netdevtab_entry *tab){    struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;    unsigned short chip_type, chip_rev, chip_status;    int i;    // Initialize environment, setup interrupt handler    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_EINT3,                             99, // Priority - what goes here?                             (cyg_addrword_t)sc, //  Data item passed to interrupt handler                             (cyg_ISR_t *)cs8900_isr,                             (cyg_DSR_t *)eth_drv_dsr, // The logical driver DSR                             &cs8900_interrupt_handle,                             &cs8900_interrupt);    cyg_drv_interrupt_attach(cs8900_interrupt_handle);    cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_EINT3);    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT3);#ifdef INTS_DONT_WORK    cyg_thread_create(1,                 // Priority                      cs8900_fake_int,   // entry                      0,                 // entry parameter                      "CS8900 int",      // Name                      &cs8900_fake_int_stack[0],         // Stack                      STACK_SIZE,        // Size                      &cs8900_fake_int_thread_handle,    // Handle                      &cs8900_fake_int_thread_data       // Thread data structure            );    cyg_thread_resume(cs8900_fake_int_thread_handle);  // Start it#endif    chip_type = get_reg(PP_ChipID);    chip_rev = get_reg(PP_ChipRev);#if 0    diag_printf("CS8900 - type: %x, rev: %x\n", chip_type, chip_rev);#endif    // Fetch hardware address#if defined(CYGPKG_REDBOOT) && \    defined(CYGSEM_REDBOOT_FLASH_CONFIG) && \    !defined(CYGSEM_ARM_EDB7XXX_SET_ESA)    flash_get_config("edb7xxx_esa", enaddr, CONFIG_ESA);#else    for (i = 0;  i < ETHER_ADDR_LEN;  i += 2) {        unsigned short esa_reg = get_reg(PP_IA+i);        enaddr[i] = esa_reg & 0xFF;        enaddr[i+1] = esa_reg >> 8;    }#endif    put_reg(PP_SelfCtl, PP_SelfCtl_Reset);  // Reset chip    while ((get_reg(PP_SelfStat) & PP_SelfStat_InitD) == 0) ;      chip_status = get_reg(PP_SelfStat);#if 0    diag_printf("CS8900 - status: %x (%sEEPROM present)\n", chip_status,                chip_status&PP_SelfStat_EEPROM ? "" : "no ");#endif    // Set up hardware address    for (i = 0;  i < ETHER_ADDR_LEN;  i += 2) {        put_reg(PP_LAF+i, 0xFFFF);        put_reg(PP_IA+i, enaddr[i] | (enaddr[i+1] << 8));    }    // Initialize upper level driver    (sc->funs->eth_drv->init)(sc, enaddr);    return true;}static voidcs8900_stop(struct eth_drv_sc *sc){    put_reg(PP_SelfCtl, PP_SelfCtl_Reset);  // Reset chip    while ((get_reg(PP_SelfStat) & PP_SelfStat_InitD) == 0) ;  }//// This function is called to "start up" the interface.  It may be called// multiple times, even when the hardware is already running.  It will be// called whenever something "hardware oriented" changes and should leave

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -