📄 lmc_media.c
字号:
/* $Id: lmc_media.c,v 1.13 2000/04/11 05:25:26 asj Exp $ */#include <linux/config.h>#include <linux/kernel.h>#include <linux/string.h>#include <linux/timer.h>#include <linux/ptrace.h>#include <linux/errno.h>#include <linux/ioport.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/in.h>#include <linux/if_arp.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/inet.h>#include <net/syncppp.h>#include <asm/processor.h> /* Processor type for cache alignment. */#include <asm/bitops.h>#include <asm/io.h>#include <asm/dma.h>#include <asm/uaccess.h>#include "lmc.h"#include "lmc_var.h"#include "lmc_ioctl.h"#include "lmc_debug.h"#define CONFIG_LMC_IGNORE_HARDWARE_HANDSHAKE 1 /* * Copyright (c) 1997-2000 LAN Media Corporation (LMC) * All rights reserved. www.lanmedia.com * * This code is written by: * Andrew Stanley-Jones (asj@cban.com) * Rob Braun (bbraun@vix.com), * Michael Graff (explorer@vix.com) and * Matt Thomas (matt@3am-software.com). * * This software may be used and distributed according to the terms * of the GNU General Public License version 2, incorporated herein by reference. *//* * For lack of a better place, put the SSI cable stuff here. */char *lmc_t1_cables[] = { "V.10/RS423", "EIA530A", "reserved", "X.21", "V.35", "EIA449/EIA530/V.36", "V.28/EIA232", "none", NULL};/* * protocol independent method. */static void lmc_set_protocol (lmc_softc_t * const, lmc_ctl_t *);/* * media independent methods to check on media status, link, light LEDs, * etc. */static void lmc_ds3_init (lmc_softc_t * const);static void lmc_ds3_default (lmc_softc_t * const);static void lmc_ds3_set_status (lmc_softc_t * const, lmc_ctl_t *);static void lmc_ds3_set_100ft (lmc_softc_t * const, int);static int lmc_ds3_get_link_status (lmc_softc_t * const);static void lmc_ds3_set_crc_length (lmc_softc_t * const, int);static void lmc_ds3_set_scram (lmc_softc_t * const, int);static void lmc_ds3_watchdog (lmc_softc_t * const);static void lmc_hssi_init (lmc_softc_t * const);static void lmc_hssi_default (lmc_softc_t * const);static void lmc_hssi_set_status (lmc_softc_t * const, lmc_ctl_t *);static void lmc_hssi_set_clock (lmc_softc_t * const, int);static int lmc_hssi_get_link_status (lmc_softc_t * const);static void lmc_hssi_set_link_status (lmc_softc_t * const, int);static void lmc_hssi_set_crc_length (lmc_softc_t * const, int);static void lmc_hssi_watchdog (lmc_softc_t * const);static void lmc_ssi_init (lmc_softc_t * const);static void lmc_ssi_default (lmc_softc_t * const);static void lmc_ssi_set_status (lmc_softc_t * const, lmc_ctl_t *);static void lmc_ssi_set_clock (lmc_softc_t * const, int);static void lmc_ssi_set_speed (lmc_softc_t * const, lmc_ctl_t *);static int lmc_ssi_get_link_status (lmc_softc_t * const);static void lmc_ssi_set_link_status (lmc_softc_t * const, int);static void lmc_ssi_set_crc_length (lmc_softc_t * const, int);static void lmc_ssi_watchdog (lmc_softc_t * const);static void lmc_t1_init (lmc_softc_t * const);static void lmc_t1_default (lmc_softc_t * const);static void lmc_t1_set_status (lmc_softc_t * const, lmc_ctl_t *);static int lmc_t1_get_link_status (lmc_softc_t * const);static void lmc_t1_set_circuit_type (lmc_softc_t * const, int);static void lmc_t1_set_crc_length (lmc_softc_t * const, int);static void lmc_t1_set_clock (lmc_softc_t * const, int);static void lmc_t1_watchdog (lmc_softc_t * const);static void lmc_dummy_set_1 (lmc_softc_t * const, int);static void lmc_dummy_set2_1 (lmc_softc_t * const, lmc_ctl_t *);static inline void write_av9110_bit (lmc_softc_t *, int);static void write_av9110 (lmc_softc_t *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t);lmc_media_t lmc_ds3_media = { lmc_ds3_init, /* special media init stuff */ lmc_ds3_default, /* reset to default state */ lmc_ds3_set_status, /* reset status to state provided */ lmc_dummy_set_1, /* set clock source */ lmc_dummy_set2_1, /* set line speed */ lmc_ds3_set_100ft, /* set cable length */ lmc_ds3_set_scram, /* set scrambler */ lmc_ds3_get_link_status, /* get link status */ lmc_dummy_set_1, /* set link status */ lmc_ds3_set_crc_length, /* set CRC length */ lmc_dummy_set_1, /* set T1 or E1 circuit type */ lmc_ds3_watchdog};lmc_media_t lmc_hssi_media = { lmc_hssi_init, /* special media init stuff */ lmc_hssi_default, /* reset to default state */ lmc_hssi_set_status, /* reset status to state provided */ lmc_hssi_set_clock, /* set clock source */ lmc_dummy_set2_1, /* set line speed */ lmc_dummy_set_1, /* set cable length */ lmc_dummy_set_1, /* set scrambler */ lmc_hssi_get_link_status, /* get link status */ lmc_hssi_set_link_status, /* set link status */ lmc_hssi_set_crc_length, /* set CRC length */ lmc_dummy_set_1, /* set T1 or E1 circuit type */ lmc_hssi_watchdog};lmc_media_t lmc_ssi_media = { lmc_ssi_init, /* special media init stuff */ lmc_ssi_default, /* reset to default state */ lmc_ssi_set_status, /* reset status to state provided */ lmc_ssi_set_clock, /* set clock source */ lmc_ssi_set_speed, /* set line speed */ lmc_dummy_set_1, /* set cable length */ lmc_dummy_set_1, /* set scrambler */ lmc_ssi_get_link_status, /* get link status */ lmc_ssi_set_link_status, /* set link status */ lmc_ssi_set_crc_length, /* set CRC length */ lmc_dummy_set_1, /* set T1 or E1 circuit type */ lmc_ssi_watchdog};lmc_media_t lmc_t1_media = { lmc_t1_init, /* special media init stuff */ lmc_t1_default, /* reset to default state */ lmc_t1_set_status, /* reset status to state provided */ lmc_t1_set_clock, /* set clock source */ lmc_dummy_set2_1, /* set line speed */ lmc_dummy_set_1, /* set cable length */ lmc_dummy_set_1, /* set scrambler */ lmc_t1_get_link_status, /* get link status */ lmc_dummy_set_1, /* set link status */ lmc_t1_set_crc_length, /* set CRC length */ lmc_t1_set_circuit_type, /* set T1 or E1 circuit type */ lmc_t1_watchdog};static voidlmc_dummy_set_1 (lmc_softc_t * const sc, int a){}static voidlmc_dummy_set2_1 (lmc_softc_t * const sc, lmc_ctl_t * a){}/* * HSSI methods */static voidlmc_hssi_init (lmc_softc_t * const sc){ sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC5200; lmc_gpio_mkoutput (sc, LMC_GEP_HSSI_CLOCK);}static voidlmc_hssi_default (lmc_softc_t * const sc){ sc->lmc_miireg16 = LMC_MII16_LED_ALL; sc->lmc_media->set_link_status (sc, LMC_LINK_DOWN); sc->lmc_media->set_clock_source (sc, LMC_CTL_CLOCK_SOURCE_EXT); sc->lmc_media->set_crc_length (sc, LMC_CTL_CRC_LENGTH_16);}/* * Given a user provided state, set ourselves up to match it. This will * always reset the card if needed. */static voidlmc_hssi_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl){ if (ctl == NULL) { sc->lmc_media->set_clock_source (sc, sc->ictl.clock_source); lmc_set_protocol (sc, NULL); return; } /* * check for change in clock source */ if (ctl->clock_source && !sc->ictl.clock_source) { sc->lmc_media->set_clock_source (sc, LMC_CTL_CLOCK_SOURCE_INT); sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_INT; } else if (!ctl->clock_source && sc->ictl.clock_source) { sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT; sc->lmc_media->set_clock_source (sc, LMC_CTL_CLOCK_SOURCE_EXT); } lmc_set_protocol (sc, ctl);}/* * 1 == internal, 0 == external */static voidlmc_hssi_set_clock (lmc_softc_t * const sc, int ie){ int old; old = sc->ictl.clock_source; if (ie == LMC_CTL_CLOCK_SOURCE_EXT) { sc->lmc_gpio |= LMC_GEP_HSSI_CLOCK; LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT; if(old != ie) printk (LMC_PRINTF_FMT ": clock external\n", LMC_PRINTF_ARGS); } else { sc->lmc_gpio &= ~(LMC_GEP_HSSI_CLOCK); LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT; if(old != ie) printk (LMC_PRINTF_FMT ": clock internal\n", LMC_PRINTF_ARGS); }}/* * return hardware link status. * 0 == link is down, 1 == link is up. */static intlmc_hssi_get_link_status (lmc_softc_t * const sc){ /* * We're using the same code as SSI since * they're practically the same */ return lmc_ssi_get_link_status(sc);}static voidlmc_hssi_set_link_status (lmc_softc_t * const sc, int state){ if (state == LMC_LINK_UP) sc->lmc_miireg16 |= LMC_MII16_HSSI_TA; else sc->lmc_miireg16 &= ~LMC_MII16_HSSI_TA; lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16);}/* * 0 == 16bit, 1 == 32bit */static voidlmc_hssi_set_crc_length (lmc_softc_t * const sc, int state){ if (state == LMC_CTL_CRC_LENGTH_32) { /* 32 bit */ sc->lmc_miireg16 |= LMC_MII16_HSSI_CRC; sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32; } else { /* 16 bit */ sc->lmc_miireg16 &= ~LMC_MII16_HSSI_CRC; sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16; } lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16);}static voidlmc_hssi_watchdog (lmc_softc_t * const sc){ /* HSSI is blank */}/* * DS3 methods *//* * Set cable length */static voidlmc_ds3_set_100ft (lmc_softc_t * const sc, int ie){ if (ie == LMC_CTL_CABLE_LENGTH_GT_100FT) { sc->lmc_miireg16 &= ~LMC_MII16_DS3_ZERO; sc->ictl.cable_length = LMC_CTL_CABLE_LENGTH_GT_100FT; } else if (ie == LMC_CTL_CABLE_LENGTH_LT_100FT) { sc->lmc_miireg16 |= LMC_MII16_DS3_ZERO; sc->ictl.cable_length = LMC_CTL_CABLE_LENGTH_LT_100FT; } lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16);}static voidlmc_ds3_default (lmc_softc_t * const sc){ sc->lmc_miireg16 = LMC_MII16_LED_ALL; sc->lmc_media->set_link_status (sc, LMC_LINK_DOWN); sc->lmc_media->set_cable_length (sc, LMC_CTL_CABLE_LENGTH_LT_100FT); sc->lmc_media->set_scrambler (sc, LMC_CTL_OFF); sc->lmc_media->set_crc_length (sc, LMC_CTL_CRC_LENGTH_16);}/* * Given a user provided state, set ourselves up to match it. This will * always reset the card if needed. */static voidlmc_ds3_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl){ if (ctl == NULL) { sc->lmc_media->set_cable_length (sc, sc->ictl.cable_length); sc->lmc_media->set_scrambler (sc, sc->ictl.scrambler_onoff); lmc_set_protocol (sc, NULL); return; } /* * check for change in cable length setting */ if (ctl->cable_length && !sc->ictl.cable_length) lmc_ds3_set_100ft (sc, LMC_CTL_CABLE_LENGTH_GT_100FT); else if (!ctl->cable_length && sc->ictl.cable_length) lmc_ds3_set_100ft (sc, LMC_CTL_CABLE_LENGTH_LT_100FT); /* * Check for change in scrambler setting (requires reset) */ if (ctl->scrambler_onoff && !sc->ictl.scrambler_onoff) lmc_ds3_set_scram (sc, LMC_CTL_ON); else if (!ctl->scrambler_onoff && sc->ictl.scrambler_onoff) lmc_ds3_set_scram (sc, LMC_CTL_OFF); lmc_set_protocol (sc, ctl);}static voidlmc_ds3_init (lmc_softc_t * const sc){ int i; sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC5245; /* writes zeros everywhere */ for (i = 0; i < 21; i++) { lmc_mii_writereg (sc, 0, 17, i); lmc_mii_writereg (sc, 0, 18, 0); } /* set some essential bits */ lmc_mii_writereg (sc, 0, 17, 1); lmc_mii_writereg (sc, 0, 18, 0x25); /* ser, xtx */ lmc_mii_writereg (sc, 0, 17, 5); lmc_mii_writereg (sc, 0, 18, 0x80); /* emode */ lmc_mii_writereg (sc, 0, 17, 14); lmc_mii_writereg (sc, 0, 18, 0x30); /* rcgen, tcgen */ /* clear counters and latched bits */ for (i = 0; i < 21; i++) { lmc_mii_writereg (sc, 0, 17, i); lmc_mii_readreg (sc, 0, 18); }}/* * 1 == DS3 payload scrambled, 0 == not scrambled */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -