aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/amazon/files/drivers/net/ethernet
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/amazon/files/drivers/net/ethernet')
-rw-r--r--target/linux/amazon/files/drivers/net/ethernet/admmod.c1493
-rw-r--r--target/linux/amazon/files/drivers/net/ethernet/amazon_sw.c899
2 files changed, 0 insertions, 2392 deletions
diff --git a/target/linux/amazon/files/drivers/net/ethernet/admmod.c b/target/linux/amazon/files/drivers/net/ethernet/admmod.c
deleted file mode 100644
index a11ee1d393..0000000000
--- a/target/linux/amazon/files/drivers/net/ethernet/admmod.c
+++ /dev/null
@@ -1,1493 +0,0 @@
-/******************************************************************************
- Copyright (c) 2004, Infineon Technologies. All rights reserved.
-
- No Warranty
- Because the program is licensed free of charge, there is no warranty for
- the program, to the extent permitted by applicable law. Except when
- otherwise stated in writing the copyright holders and/or other parties
- provide the program "as is" without warranty of any kind, either
- expressed or implied, including, but not limited to, the implied
- warranties of merchantability and fitness for a particular purpose. The
- entire risk as to the quality and performance of the program is with
- you. should the program prove defective, you assume the cost of all
- necessary servicing, repair or correction.
-
- In no event unless required by applicable law or agreed to in writing
- will any copyright holder, or any other party who may modify and/or
- redistribute the program as permitted above, be liable to you for
- damages, including any general, special, incidental or consequential
- damages arising out of the use or inability to use the program
- (including but not limited to loss of data or data being rendered
- inaccurate or losses sustained by you or third parties or a failure of
- the program to operate with any other programs), even if such holder or
- other party has been advised of the possibility of such damages.
- ******************************************************************************
- Module : admmod.c
- Date : 2004-09-01
- Description : JoeLin
- Remarks:
-
- Revision:
- MarsLin, add to support VLAN
-
- *****************************************************************************/
-//000001.joelin 2005/06/02 add"ADM6996_MDC_MDIO_MODE" define,
-// if define ADM6996_MDC_MDIO_MODE==> ADM6996LC and ADM6996I will be in MDIO/MDC(SMI)(16 bit) mode,
-// amazon should contrl ADM6996 by MDC/MDIO pin
-// if undef ADM6996_MDC_MDIO_MODE==> ADM6996 will be in EEProm(32 bit) mode,
-// amazon should contrl ADM6996 by GPIO15,16,17,18 pin
-/* 507281:linmars 2005/07/28 support MDIO/EEPROM config mode */
-/* 509201:linmars remove driver testing codes */
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/proc_fs.h>
-#include <linux/delay.h>
-#include <asm/uaccess.h>
-#include <linux/init.h>
-#include <linux/ioctl.h>
-#include <asm/atomic.h>
-#include <asm-mips/amazon/amazon.h>
-#include <asm-mips/amazon/adm6996.h>
-//#include <linux/amazon/adm6996.h>
-
-
-unsigned int ifx_sw_conf[ADM_SW_MAX_PORT_NUM+1] = \
- {ADM_SW_PORT0_CONF, ADM_SW_PORT1_CONF, ADM_SW_PORT2_CONF, \
- ADM_SW_PORT3_CONF, ADM_SW_PORT4_CONF, ADM_SW_PORT5_CONF};
-unsigned int ifx_sw_bits[8] = \
- {0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff};
-unsigned int ifx_sw_vlan_port[6] = {0, 2, 4, 6, 7, 8};
-//050613:fchang
-/* 507281:linmars start */
-#ifdef CONFIG_SWITCH_ADM6996_MDIO
-#define ADM6996_MDC_MDIO_MODE 1 //000001.joelin
-#else
-#undef ADM6996_MDC_MDIO_MODE
-#endif
-/* 507281:linmars end */
-#define adm6996i 0
-#define adm6996lc 1
-#define adm6996l 2
-unsigned int adm6996_mode=adm6996i;
-/*
- initialize GPIO pins.
- output mode, low
-*/
-void ifx_gpio_init(void)
-{
- //GPIO16,17,18 direction:output
- //GPIO16,17,18 output 0
-
- AMAZON_SW_REG(AMAZON_GPIO_P1_DIR) |= (GPIO_MDIO|GPIO_MDCS|GPIO_MDC);
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT) =AMAZON_SW_REG(AMAZON_GPIO_P1_IN)& ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC);
-
-}
-
-/* read one bit from mdio port */
-int ifx_sw_mdio_readbit(void)
-{
- //int val;
-
- //val = (AMAZON_SW_REG(GPIO_conf0_REG) & GPIO0_INPUT_MASK) >> 8;
- //return val;
- //GPIO16
- return AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&1;
-}
-
-/*
- MDIO mode selection
- 1 -> output
- 0 -> input
-
- switch input/output mode of GPIO 0
-*/
-void ifx_mdio_mode(int mode)
-{
-// AMAZON_SW_REG(GPIO_conf0_REG) = mode ? GPIO_ENABLEBITS :
-// ((GPIO_ENABLEBITS | MDIO_INPUT) & ~MDIO_OUTPUT_EN);
- mode?(AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)|=GPIO_MDIO):
- (AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)&=~GPIO_MDIO);
- /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_DIR);
- mode?(r|=GPIO_MDIO):(r&=~GPIO_MDIO);
- AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)=r;*/
-}
-
-void ifx_mdc_hi(void)
-{
- //GPIO_SET_HI(GPIO_MDC);
- //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDC;
- /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
- r|=GPIO_MDC;
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
-
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDC;
-}
-
-void ifx_mdio_hi(void)
-{
- //GPIO_SET_HI(GPIO_MDIO);
- //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDIO;
- /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
- r|=GPIO_MDIO;
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
-
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDIO;
-}
-
-void ifx_mdcs_hi(void)
-{
- //GPIO_SET_HI(GPIO_MDCS);
- //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDCS;
- /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
- r|=GPIO_MDCS;
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
-
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDCS;
-}
-
-void ifx_mdc_lo(void)
-{
- //GPIO_SET_LOW(GPIO_MDC);
- //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDC;
- /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
- r&=~GPIO_MDC;
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
-
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDC);
-}
-
-void ifx_mdio_lo(void)
-{
- //GPIO_SET_LOW(GPIO_MDIO);
- //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDIO;
- /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
- r&=~GPIO_MDIO;
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
-
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDIO);
-}
-
-void ifx_mdcs_lo(void)
-{
- //GPIO_SET_LOW(GPIO_MDCS);
- //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDCS;
- /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT);
- r&=~GPIO_MDCS;
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/
-
- AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDCS);
-}
-
-/*
- mdc pulse
- 0 -> 1 -> 0
-*/
-static void ifx_sw_mdc_pulse(void)
-{
- ifx_mdc_lo();
- udelay(ADM_SW_MDC_DOWN_DELAY);
- ifx_mdc_hi();
- udelay(ADM_SW_MDC_UP_DELAY);
- ifx_mdc_lo();
-}
-
-/*
- mdc toggle
- 1 -> 0
-*/
-static void ifx_sw_mdc_toggle(void)
-{
- ifx_mdc_hi();
- udelay(ADM_SW_MDC_UP_DELAY);
- ifx_mdc_lo();
- udelay(ADM_SW_MDC_DOWN_DELAY);
-}
-
-/*
- enable eeprom write
- For ATC 93C66 type EEPROM; accessing ADM6996 internal EEPROM type registers
-*/
-static void ifx_sw_eeprom_write_enable(void)
-{
- unsigned int op;
-
- ifx_mdcs_lo();
- ifx_mdc_lo();
- ifx_mdio_hi();
- udelay(ADM_SW_CS_DELAY);
- /* enable chip select */
- ifx_mdcs_hi();
- udelay(ADM_SW_CS_DELAY);
- /* start bit */
- ifx_mdio_hi();
- ifx_sw_mdc_pulse();
-
- /* eeprom write enable */
- op = ADM_SW_BIT_MASK_4;
- while (op)
- {
- if (op & ADM_SW_EEPROM_WRITE_ENABLE)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 3);
- while (op)
- {
- ifx_mdio_lo();
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
- /* disable chip select */
- ifx_mdcs_lo();
- udelay(ADM_SW_CS_DELAY);
- ifx_sw_mdc_pulse();
-}
-
-/*
- disable eeprom write
-*/
-static void ifx_sw_eeprom_write_disable(void)
-{
- unsigned int op;
-
- ifx_mdcs_lo();
- ifx_mdc_lo();
- ifx_mdio_hi();
- udelay(ADM_SW_CS_DELAY);
- /* enable chip select */
- ifx_mdcs_hi();
- udelay(ADM_SW_CS_DELAY);
-
- /* start bit */
- ifx_mdio_hi();
- ifx_sw_mdc_pulse();
- /* eeprom write disable */
- op = ADM_SW_BIT_MASK_4;
- while (op)
- {
- if (op & ADM_SW_EEPROM_WRITE_DISABLE)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 3);
- while (op)
- {
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
- /* disable chip select */
- ifx_mdcs_lo();
- udelay(ADM_SW_CS_DELAY);
- ifx_sw_mdc_pulse();
-}
-
-/*
- read registers from ADM6996
- serial registers start at 0x200 (addr bit 9 = 1b)
- EEPROM registers -> 16bits; Serial registers -> 32bits
-*/
-#ifdef ADM6996_MDC_MDIO_MODE //smi mode//000001.joelin
-static int ifx_sw_read_adm6996i_smi(unsigned int addr, unsigned int *dat)
-{
- addr=(addr<<16)&0x3ff0000;
- AMAZON_SW_REG(AMAZON_SW_MDIO_ACC) =(0xC0000000|addr);
- while ((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x80000000){};
- *dat=((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x0FFFF);
- return 0;
-}
-#endif
-
-static int ifx_sw_read_adm6996i(unsigned int addr, unsigned int *dat)
-{
- unsigned int op;
-
- ifx_gpio_init();
-
- ifx_mdcs_hi();
- udelay(ADM_SW_CS_DELAY);
-
- ifx_mdcs_lo();
- ifx_mdc_lo();
- ifx_mdio_lo();
-
- udelay(ADM_SW_CS_DELAY);
-
- /* preamble, 32 bit 1 */
- ifx_mdio_hi();
- op = ADM_SW_BIT_MASK_32;
- while (op)
- {
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* command start (01b) */
- op = ADM_SW_BIT_MASK_2;
- while (op)
- {
- if (op & ADM_SW_SMI_START)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* read command (10b) */
- op = ADM_SW_BIT_MASK_2;
- while (op)
- {
- if (op & ADM_SW_SMI_READ)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* send address A9 ~ A0 */
- op = ADM_SW_BIT_MASK_10;
- while (op)
- {
- if (op & addr)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* turnaround bits */
- op = ADM_SW_BIT_MASK_2;
- ifx_mdio_hi();
- while (op)
- {
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- udelay(ADM_SW_MDC_DOWN_DELAY);
-
- /* set MDIO pin to input mode */
- ifx_mdio_mode(ADM_SW_MDIO_INPUT);
-
- /* start read data */
- *dat = 0;
-//adm6996i op = ADM_SW_BIT_MASK_32;
- op = ADM_SW_BIT_MASK_16;//adm6996i
- while (op)
- {
- *dat <<= 1;
- if (ifx_sw_mdio_readbit()) *dat |= 1;
- ifx_sw_mdc_toggle();
-
- op >>= 1;
- }
-
- /* set MDIO to output mode */
- ifx_mdio_mode(ADM_SW_MDIO_OUTPUT);
-
- /* dummy clock */
- op = ADM_SW_BIT_MASK_4;
- ifx_mdio_lo();
- while(op)
- {
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- ifx_mdc_lo();
- ifx_mdio_lo();
- ifx_mdcs_hi();
-
- /* EEPROM registers */
-//adm6996i if (!(addr & 0x200))
-//adm6996i {
-//adm6996i if (addr % 2)
-//adm6996i *dat >>= 16;
-//adm6996i else
-//adm6996i *dat &= 0xffff;
-//adm6996i }
-
- return 0;
-}
-//adm6996
-static int ifx_sw_read_adm6996l(unsigned int addr, unsigned int *dat)
-{
- unsigned int op;
-
- ifx_gpio_init();
-
- ifx_mdcs_hi();
- udelay(ADM_SW_CS_DELAY);
-
- ifx_mdcs_lo();
- ifx_mdc_lo();
- ifx_mdio_lo();
-
- udelay(ADM_SW_CS_DELAY);
-
- /* preamble, 32 bit 1 */
- ifx_mdio_hi();
- op = ADM_SW_BIT_MASK_32;
- while (op)
- {
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* command start (01b) */
- op = ADM_SW_BIT_MASK_2;
- while (op)
- {
- if (op & ADM_SW_SMI_START)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* read command (10b) */
- op = ADM_SW_BIT_MASK_2;
- while (op)
- {
- if (op & ADM_SW_SMI_READ)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* send address A9 ~ A0 */
- op = ADM_SW_BIT_MASK_10;
- while (op)
- {
- if (op & addr)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* turnaround bits */
- op = ADM_SW_BIT_MASK_2;
- ifx_mdio_hi();
- while (op)
- {
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- udelay(ADM_SW_MDC_DOWN_DELAY);
-
- /* set MDIO pin to input mode */
- ifx_mdio_mode(ADM_SW_MDIO_INPUT);
-
- /* start read data */
- *dat = 0;
- op = ADM_SW_BIT_MASK_32;
- while (op)
- {
- *dat <<= 1;
- if (ifx_sw_mdio_readbit()) *dat |= 1;
- ifx_sw_mdc_toggle();
-
- op >>= 1;
- }
-
- /* set MDIO to output mode */
- ifx_mdio_mode(ADM_SW_MDIO_OUTPUT);
-
- /* dummy clock */
- op = ADM_SW_BIT_MASK_4;
- ifx_mdio_lo();
- while(op)
- {
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- ifx_mdc_lo();
- ifx_mdio_lo();
- ifx_mdcs_hi();
-
- /* EEPROM registers */
- if (!(addr & 0x200))
- {
- if (addr % 2)
- *dat >>= 16;
- else
- *dat &= 0xffff;
- }
-
- return 0;
-}
-
-static int ifx_sw_read(unsigned int addr, unsigned int *dat)
-{
-#ifdef ADM6996_MDC_MDIO_MODE //smi mode ////000001.joelin
- ifx_sw_read_adm6996i_smi(addr,dat);
-#else
- if (adm6996_mode==adm6996i) ifx_sw_read_adm6996i(addr,dat);
- else ifx_sw_read_adm6996l(addr,dat);
-#endif
- return 0;
-
-}
-
-/*
- write register to ADM6996 eeprom registers
-*/
-//for adm6996i -start
-#ifdef ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin
-static int ifx_sw_write_adm6996i_smi(unsigned int addr, unsigned int dat)
-{
-
- AMAZON_SW_REG(AMAZON_SW_MDIO_ACC) = ((addr<<16)&0x3ff0000)|dat|0x80000000;
- while ((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x80000000){};
-
- return 0;
-
-}
-#endif //ADM6996_MDC_MDIO_MODE //000001.joelin
-
-static int ifx_sw_write_adm6996i(unsigned int addr, unsigned int dat)
-{
- unsigned int op;
-
- ifx_gpio_init();
-
- ifx_mdcs_hi();
- udelay(ADM_SW_CS_DELAY);
-
- ifx_mdcs_lo();
- ifx_mdc_lo();
- ifx_mdio_lo();
-
- udelay(ADM_SW_CS_DELAY);
-
- /* preamble, 32 bit 1 */
- ifx_mdio_hi();
- op = ADM_SW_BIT_MASK_32;
- while (op)
- {
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* command start (01b) */
- op = ADM_SW_BIT_MASK_2;
- while (op)
- {
- if (op & ADM_SW_SMI_START)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* write command (01b) */
- op = ADM_SW_BIT_MASK_2;
- while (op)
- {
- if (op & ADM_SW_SMI_WRITE)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* send address A9 ~ A0 */
- op = ADM_SW_BIT_MASK_10;
- while (op)
- {
- if (op & addr)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* turnaround bits */
- op = ADM_SW_BIT_MASK_2;
- ifx_mdio_hi();
- while (op)
- {
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- udelay(ADM_SW_MDC_DOWN_DELAY);
-
- /* set MDIO pin to output mode */
- ifx_mdio_mode(ADM_SW_MDIO_OUTPUT);
-
-
- /* start write data */
- op = ADM_SW_BIT_MASK_16;
- while (op)
- {
- if (op & dat)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_toggle();
- op >>= 1;
- }
-
- // /* set MDIO to output mode */
- // ifx_mdio_mode(ADM_SW_MDIO_OUTPUT);
-
- /* dummy clock */
- op = ADM_SW_BIT_MASK_4;
- ifx_mdio_lo();
- while(op)
- {
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- ifx_mdc_lo();
- ifx_mdio_lo();
- ifx_mdcs_hi();
-
- /* EEPROM registers */
-//adm6996i if (!(addr & 0x200))
-//adm6996i {
-//adm6996i if (addr % 2)
-//adm6996i *dat >>= 16;
-//adm6996i else
-//adm6996i *dat &= 0xffff;
-//adm6996i }
-
- return 0;
-}
-//for adm6996i-end
-static int ifx_sw_write_adm6996l(unsigned int addr, unsigned int dat)
-{
- unsigned int op;
-
- ifx_gpio_init();
-
- /* enable write */
- ifx_sw_eeprom_write_enable();
-
- /* chip select */
- ifx_mdcs_hi();
- udelay(ADM_SW_CS_DELAY);
-
- /* issue write command */
- /* start bit */
- ifx_mdio_hi();
- ifx_sw_mdc_pulse();
-
- /* EEPROM write command */
- op = ADM_SW_BIT_MASK_2;
- while (op)
- {
- if (op & ADM_SW_EEPROM_WRITE)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_pulse();
- op >>= 1;
- }
-
- /* send address A7 ~ A0 */
- op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 1);
-
- while (op)
- {
- if (op & addr)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_toggle();
- op >>= 1;
- }
-
- /* start write data */
- op = ADM_SW_BIT_MASK_16;
- while (op)
- {
- if (op & dat)
- ifx_mdio_hi();
- else
- ifx_mdio_lo();
-
- ifx_sw_mdc_toggle();
- op >>= 1;
- }
-
- /* disable cs & wait 1 clock */
- ifx_mdcs_lo();
- udelay(ADM_SW_CS_DELAY);
- ifx_sw_mdc_toggle();
-
- ifx_sw_eeprom_write_disable();
-
- return 0;
-}
-
-static int ifx_sw_write(unsigned int addr, unsigned int dat)
-{
-#ifdef ADM6996_MDC_MDIO_MODE //smi mode ////000001.joelin
- ifx_sw_write_adm6996i_smi(addr,dat);
-#else //000001.joelin
- if (adm6996_mode==adm6996i) ifx_sw_write_adm6996i(addr,dat);
- else ifx_sw_write_adm6996l(addr,dat);
-#endif //000001.joelin
- return 0;
-}
-
-/*
- do switch PHY reset
-*/
-int ifx_sw_reset(void)
-{
- /* reset PHY */
- ifx_sw_write(ADM_SW_PHY_RESET, 0);
-
- return 0;
-}
-
-/* 509201:linmars start */
-#if 0
-/*
- check port status
-*/
-int ifx_check_port_status(int port)
-{
- unsigned int val;
-
- if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM))
- {
- ifx_printf(("error on port number (%d)!!\n", port));
- return -1;
- }
-
- ifx_sw_read(ifx_sw_conf[port], &val);
- if (ifx_sw_conf[port]%2) val >>= 16;
- /* only 16bits are effective */
- val &= 0xFFFF;
-
- ifx_printf(("Port %d status (%.8x): \n", port, val));
-
- if (val & ADM_SW_PORT_FLOWCTL)
- ifx_printf(("\t802.3x flow control supported!\n"));
- else
- ifx_printf(("\t802.3x flow control not supported!\n"));
-
- if (val & ADM_SW_PORT_AN)
- ifx_printf(("\tAuto negotiation ON!\n"));
- else
- ifx_printf(("\tAuto negotiation OFF!\n"));
-
- if (val & ADM_SW_PORT_100M)
- ifx_printf(("\tLink at 100M!\n"));
- else
- ifx_printf(("\tLink at 10M!\n"));
-
- if (val & ADM_SW_PORT_FULL)
- ifx_printf(("\tFull duplex!\n"));
- else
- ifx_printf(("\tHalf duplex!\n"));
-
- if (val & ADM_SW_PORT_DISABLE)
- ifx_printf(("\tPort disabled!\n"));
- else
- ifx_printf(("\tPort enabled!\n"));
-
- if (val & ADM_SW_PORT_TOS)
- ifx_printf(("\tTOS enabled!\n"));
- else
- ifx_printf(("\tTOS disabled!\n"));
-
- if (val & ADM_SW_PORT_PPRI)
- ifx_printf(("\tPort priority first!\n"));
- else
- ifx_printf(("\tVLAN or TOS priority first!\n"));
-
- if (val & ADM_SW_PORT_MDIX)
- ifx_printf(("\tAuto MDIX!\n"));
- else
- ifx_printf(("\tNo auto MDIX\n"));
-
- ifx_printf(("\tPVID: %d\n", \
- ((val >> ADM_SW_PORT_PVID_SHIFT)&ifx_sw_bits[ADM_SW_PORT_PVID_BITS])));
-
- return 0;
-}
-/*
- initialize a VLAN
- clear all VLAN bits
-*/
-int ifx_sw_vlan_init(int vlanid)
-{
- ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, 0);
-
- return 0;
-}
-
-/*
- add a port to certain vlan
-*/
-int ifx_sw_vlan_add(int port, int vlanid)
-{
- int reg = 0;
-
- if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM) || (vlanid < 0) ||
- (vlanid > ADM_SW_MAX_VLAN_NUM))
- {
- ifx_printf(("Port number or VLAN number ERROR!!\n"));
- return -1;
- }
- ifx_sw_read(ADM_SW_VLAN0_CONF + vlanid, &reg);
- reg |= (1 << ifx_sw_vlan_port[port]);
- ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, reg);
-
- return 0;
-}
-
-/*
- delete a given port from certain vlan
-*/
-int ifx_sw_vlan_del(int port, int vlanid)
-{
- unsigned int reg = 0;
-
- if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM) || (vlanid < 0) || (vlanid > ADM_SW_MAX_VLAN_NUM))
- {
- ifx_printf(("Port number or VLAN number ERROR!!\n"));
- return -1;
- }
- ifx_sw_read(ADM_SW_VLAN0_CONF + vlanid, &reg);
- reg &= ~(1 << ifx_sw_vlan_port[port]);
- ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, reg);
-
- return 0;
-}
-
-/*
- default VLAN setting
-
- port 0~3 as untag port and PVID = 1
- VLAN1: port 0~3 and port 5 (MII)
-*/
-static int ifx_sw_init(void)
-{
- ifx_printf(("Setting default ADM6996 registers... \n"));
-
- /* MAC clone, 802.1q based VLAN */
- ifx_sw_write(ADM_SW_VLAN_MODE, 0xff30);
- /* auto MDIX, PVID=1, untag */
- ifx_sw_write(ADM_SW_PORT0_CONF, 0x840f);
- ifx_sw_write(ADM_SW_PORT1_CONF, 0x840f);
- ifx_sw_write(ADM_SW_PORT2_CONF, 0x840f);
- ifx_sw_write(ADM_SW_PORT3_CONF, 0x840f);
- /* auto MDIX, PVID=2, untag */
- ifx_sw_write(ADM_SW_PORT5_CONF, 0x880f);
- /* port 0~3 & 5 as VLAN1 */
- ifx_sw_write(ADM_SW_VLAN0_CONF+1, 0x0155);
-
- return 0;
-}
-#endif
-/* 509201:linmars end */
-
-int adm_open(struct inode *node, struct file *filp)
-{
- return 0;
-}
-
-ssize_t adm_read(struct file *filep, char *buf, size_t count, loff_t *ppos)
-{
- return count;
-}
-
-ssize_t adm_write(struct file *filep, const char *buf, size_t count, loff_t *ppos)
-{
- return count;
-}
-
-/* close */
-int adm_release(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
-/* IOCTL function */
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
-static long adm_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
-#else
-static int adm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long args)
-#endif
-{
- PREGRW uREGRW;
- unsigned int rtval;
- unsigned int val; //6996i
- unsigned int control[6] ; //6996i
- unsigned int status[6] ; //6996i
-
- PMACENTRY mMACENTRY;//adm6996i
- PPROTOCOLFILTER uPROTOCOLFILTER ;///adm6996i
-
- if (_IOC_TYPE(cmd) != ADM_MAGIC)
- {
- printk("adm_ioctl: IOC_TYPE(%x) != ADM_MAGIC(%x)! \n", _IOC_TYPE(cmd), ADM_MAGIC);
- return (-EINVAL);
- }
-
- if(_IOC_NR(cmd) >= KEY_IOCTL_MAX_KEY)
- {
- printk(KERN_WARNING "adm_ioctl: IOC_NR(%x) invalid! \n", _IOC_NR(cmd));
- return (-EINVAL);
- }
-
- switch (cmd)
- {
- case ADM_IOCTL_REGRW:
- {
- uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL);
- rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW));
- if (rtval != 0)
- {
- printk("ADM_IOCTL_REGRW: copy from user FAILED!! \n");
- return (-EFAULT);
- }
-
- switch(uREGRW->mode)
- {
- case REG_READ:
- uREGRW->value = 0x12345678;//inl(uREGRW->addr);
- copy_to_user((PREGRW)args, uREGRW, sizeof(REGRW));
- break;
- case REG_WRITE:
- //outl(uREGRW->value, uREGRW->addr);
- break;
-
- default:
- printk("No such Register Read/Write function!! \n");
- return (-EFAULT);
- }
- kfree(uREGRW);
- break;
- }
-
- case ADM_SW_IOCTL_REGRW:
- {
- unsigned int val = 0xff;
-
- uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL);
- rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW));
- if (rtval != 0)
- {
- printk("ADM_IOCTL_REGRW: copy from user FAILED!! \n");
- return (-EFAULT);
- }
-
- switch(uREGRW->mode)
- {
- case REG_READ:
- ifx_sw_read(uREGRW->addr, &val);
- uREGRW->value = val;
- copy_to_user((PREGRW)args, uREGRW, sizeof(REGRW));
- break;
-
- case REG_WRITE:
- ifx_sw_write(uREGRW->addr, uREGRW->value);
- break;
- default:
- printk("No such Register Read/Write function!! \n");
- return (-EFAULT);
- }
- kfree(uREGRW);
- break;
- }
-/* 509201:linmars start */
-#if 0
- case ADM_SW_IOCTL_PORTSTS:
- for (rtval = 0; rtval < ADM_SW_MAX_PORT_NUM+1; rtval++)
- ifx_check_port_status(rtval);
- break;
- case ADM_SW_IOCTL_INIT:
- ifx_sw_init();
- break;
-#endif
-/* 509201:linmars end */
-//adm6996i
- case ADM_SW_IOCTL_MACENTRY_ADD:
- case ADM_SW_IOCTL_MACENTRY_DEL:
- case ADM_SW_IOCTL_MACENTRY_GET_INIT:
- case ADM_SW_IOCTL_MACENTRY_GET_MORE:
-
-
- mMACENTRY = (PMACENTRY)kmalloc(sizeof(MACENTRY), GFP_KERNEL);
- rtval = copy_from_user(mMACENTRY, (PMACENTRY)args, sizeof(MACENTRY));
- if (rtval != 0)
- {
- printk("ADM_SW_IOCTL_MACENTRY: copy from user FAILED!! \n");
- return (-EFAULT);
- }
- control[0]=(mMACENTRY->mac_addr[1]<<8)+mMACENTRY->mac_addr[0] ;
- control[1]=(mMACENTRY->mac_addr[3]<<8)+mMACENTRY->mac_addr[2] ;
- control[2]=(mMACENTRY->mac_addr[5]<<8)+mMACENTRY->mac_addr[4] ;
- control[3]=(mMACENTRY->fid&0xf)+((mMACENTRY->portmap&0x3f)<<4);
- if (((mMACENTRY->info_type)&0x01)) control[4]=(mMACENTRY->ctrl.info_ctrl)+0x1000; //static ,info control
- else control[4]=((mMACENTRY->ctrl.age_timer)&0xff);//not static ,agetimer
- if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) {
- //initial the pointer to the first address
- val=0x8000;//busy ,status5[15]
- while(val&0x8000){ //check busy ?
- ifx_sw_read(0x125, &val);
- }
- control[5]=0x030;//initial the first address
- ifx_sw_write(0x11f,control[5]);
-
-
- val=0x8000;//busy ,status5[15]
- while(val&0x8000){ //check busy ?
- ifx_sw_read(0x125, &val);
- }
-
- } //if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)
- if (cmd==ADM_SW_IOCTL_MACENTRY_ADD) control[5]=0x07;//create a new address
- else if (cmd==ADM_SW_IOCTL_MACENTRY_DEL) control[5]=0x01f;//erased an existed address
- else if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE))
- control[5]=0x02c;//search by the mac address field
-
- val=0x8000;//busy ,status5[15]
- while(val&0x8000){ //check busy ?
- ifx_sw_read(0x125, &val);
- }
- ifx_sw_write(0x11a,control[0]);
- ifx_sw_write(0x11b,control[1]);
- ifx_sw_write(0x11c,control[2]);
- ifx_sw_write(0x11d,control[3]);
- ifx_sw_write(0x11e,control[4]);
- ifx_sw_write(0x11f,control[5]);
- val=0x8000;//busy ,status5[15]
- while(val&0x8000){ //check busy ?
- ifx_sw_read(0x125, &val);
- }
- val=((val&0x7000)>>12);//result ,status5[14:12]
- mMACENTRY->result=val;
-
- if (!val) {
- printk(" Command OK!! \n");
- if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) {
- ifx_sw_read(0x120,&(status[0]));
- ifx_sw_read(0x121,&(status[1]));
- ifx_sw_read(0x122,&(status[2]));
- ifx_sw_read(0x123,&(status[3]));
- ifx_sw_read(0x124,&(status[4]));
- ifx_sw_read(0x125,&(status[5]));
-
-
- mMACENTRY->mac_addr[0]=(status[0]&0x00ff) ;
- mMACENTRY->mac_addr[1]=(status[0]&0xff00)>>8 ;
- mMACENTRY->mac_addr[2]=(status[1]&0x00ff) ;
- mMACENTRY->mac_addr[3]=(status[1]&0xff00)>>8 ;
- mMACENTRY->mac_addr[4]=(status[2]&0x00ff) ;
- mMACENTRY->mac_addr[5]=(status[2]&0xff00)>>8 ;
- mMACENTRY->fid=(status[3]&0xf);
- mMACENTRY->portmap=((status[3]>>4)&0x3f);
- if (status[5]&0x2) {//static info_ctrl //status5[1]????
- mMACENTRY->ctrl.info_ctrl=(status[4]&0x00ff);
- mMACENTRY->info_type=1;
- }
- else {//not static age_timer
- mMACENTRY->ctrl.age_timer=(status[4]&0x00ff);
- mMACENTRY->info_type=0;
- }
-//status5[13]???? mMACENTRY->occupy=(status[5]&0x02)>>1;//status5[1]
- mMACENTRY->occupy=(status[5]&0x02000)>>13;//status5[13] ???
- mMACENTRY->bad=(status[5]&0x04)>>2;//status5[2]
- }//if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE))
-
- }
- else if (val==0x001)
- printk(" All Entry Used!! \n");
- else if (val==0x002)
- printk(" Entry Not Found!! \n");
- else if (val==0x003)
- printk(" Try Next Entry!! \n");
- else if (val==0x005)
- printk(" Command Error!! \n");
- else
- printk(" UnKnown Error!! \n");
-
- copy_to_user((PMACENTRY)args, mMACENTRY,sizeof(MACENTRY));
-
- break;
-
- case ADM_SW_IOCTL_FILTER_ADD:
- case ADM_SW_IOCTL_FILTER_DEL:
- case ADM_SW_IOCTL_FILTER_GET:
-
- uPROTOCOLFILTER = (PPROTOCOLFILTER)kmalloc(sizeof(PROTOCOLFILTER), GFP_KERNEL);
- rtval = copy_from_user(uPROTOCOLFILTER, (PPROTOCOLFILTER)args, sizeof(PROTOCOLFILTER));
- if (rtval != 0)
- {
- printk("ADM_SW_IOCTL_FILTER_ADD: copy from user FAILED!! \n");
- return (-EFAULT);
- }
-
- if(cmd==ADM_SW_IOCTL_FILTER_DEL) { //delete filter
- uPROTOCOLFILTER->ip_p=00; //delet filter
- uPROTOCOLFILTER->action=00; //delete filter
- } //delete filter
-
- ifx_sw_read(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), &val);//rx68~rx6b,protocol filter0~7
-
- if (((uPROTOCOLFILTER->protocol_filter_num)%2)==00){
- if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= val&0x00ff;//get filter ip_p
- else val=(val&0xff00)|(uPROTOCOLFILTER->ip_p);//set filter ip_p
- }
- else {
- if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= (val>>8);//get filter ip_p
- else val=(val&0x00ff)|((uPROTOCOLFILTER->ip_p)<<8);//set filter ip_p
- }
- if(cmd!=ADM_SW_IOCTL_FILTER_GET) ifx_sw_write(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), val);//write rx68~rx6b,protocol filter0~7
-
- ifx_sw_read(0x95, &val); //protocol filter action
- if(cmd==ADM_SW_IOCTL_FILTER_GET) {
- uPROTOCOLFILTER->action= ((val>>(uPROTOCOLFILTER->protocol_filter_num*2))&0x3);//get filter action
- copy_to_user((PPROTOCOLFILTER)args, uPROTOCOLFILTER, sizeof(PROTOCOLFILTER));
-
- }
- else {
- val=(val&(~(0x03<<(uPROTOCOLFILTER->protocol_filter_num*2))))|(((uPROTOCOLFILTER->action)&0x03)<<(uPROTOCOLFILTER->protocol_filter_num*2));
- // printk("%d----\n",val);
- ifx_sw_write(0x95, val); //write protocol filter action
- }
-
- break;
-//adm6996i
-
- /* others */
- default:
- return -EFAULT;
- }
- /* end of switch */
- return 0;
-}
-
-/* Santosh: handle IGMP protocol filter ADD/DEL/GET */
-int adm_process_protocol_filter_request (unsigned int cmd, PPROTOCOLFILTER uPROTOCOLFILTER)
-{
- unsigned int val; //6996i
-
- if(cmd==ADM_SW_IOCTL_FILTER_DEL) { //delete filter
- uPROTOCOLFILTER->ip_p=00; //delet filter
- uPROTOCOLFILTER->action=00; //delete filter
- } //delete filter
-
- ifx_sw_read(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), &val);//rx68~rx6b,protocol filter0~7
-
- if (((uPROTOCOLFILTER->protocol_filter_num)%2)==00){
- if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= val&0x00ff;//get filter ip_p
- else val=(val&0xff00)|(uPROTOCOLFILTER->ip_p);//set filter ip_p
- }
- else {
- if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= (val>>8);//get filter ip_p
- else val=(val&0x00ff)|((uPROTOCOLFILTER->ip_p)<<8);//set filter ip_p
- }
- if(cmd!=ADM_SW_IOCTL_FILTER_GET) ifx_sw_write(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), val);//write rx68~rx6b,protocol filter0~7
-
- ifx_sw_read(0x95, &val); //protocol filter action
- if(cmd==ADM_SW_IOCTL_FILTER_GET) {
- uPROTOCOLFILTER->action= ((val>>(uPROTOCOLFILTER->protocol_filter_num*2))&0x3);//get filter action
- }
- else {
- val=(val&(~(0x03<<(uPROTOCOLFILTER->protocol_filter_num*2))))|(((uPROTOCOLFILTER->action)&0x03)<<(uPROTOCOLFILTER->protocol_filter_num*2));
- ifx_sw_write(0x95, val); //write protocol filter action
- }
-
- return 0;
-}
-
-
-/* Santosh: function for MAC ENTRY ADD/DEL/GET */
-
-int adm_process_mac_table_request (unsigned int cmd, PMACENTRY mMACENTRY)
-{
- unsigned int val; //6996i
- unsigned int control[6] ; //6996i
- unsigned int status[6] ; //6996i
-
- // printk ("adm_process_mac_table_request: enter\n");
-
- control[0]=(mMACENTRY->mac_addr[1]<<8)+mMACENTRY->mac_addr[0] ;
- control[1]=(mMACENTRY->mac_addr[3]<<8)+mMACENTRY->mac_addr[2] ;
- control[2]=(mMACENTRY->mac_addr[5]<<8)+mMACENTRY->mac_addr[4] ;
- control[3]=(mMACENTRY->fid&0xf)+((mMACENTRY->portmap&0x3f)<<4);
-
- if (((mMACENTRY->info_type)&0x01)) control[4]=(mMACENTRY->ctrl.info_ctrl)+0x1000; //static ,info control
- else control[4]=((mMACENTRY->ctrl.age_timer)&0xff);//not static ,agetimer
- if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) {
- //initial the pointer to the first address
- val=0x8000;//busy ,status5[15]
- while(val&0x8000){ //check busy ?
- ifx_sw_read(0x125, &val);
- }
- control[5]=0x030;//initial the first address
- ifx_sw_write(0x11f,control[5]);
-
-
- val=0x8000;//busy ,status5[15]
- while(val&0x8000){ //check busy ?
- ifx_sw_read(0x125, &val);
- }
-
- } //if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)
- if (cmd==ADM_SW_IOCTL_MACENTRY_ADD) control[5]=0x07;//create a new address
- else if (cmd==ADM_SW_IOCTL_MACENTRY_DEL) control[5]=0x01f;//erased an existed address
- else if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE))
- control[5]=0x02c;//search by the mac address field
-
- val=0x8000;//busy ,status5[15]
- while(val&0x8000){ //check busy ?
- ifx_sw_read(0x125, &val);
- }
- ifx_sw_write(0x11a,control[0]);
- ifx_sw_write(0x11b,control[1]);
- ifx_sw_write(0x11c,control[2]);
- ifx_sw_write(0x11d,control[3]);
- ifx_sw_write(0x11e,control[4]);
- ifx_sw_write(0x11f,control[5]);
- val=0x8000;//busy ,status5[15]
- while(val&0x8000){ //check busy ?
- ifx_sw_read(0x125, &val);
- }
- val=((val&0x7000)>>12);//result ,status5[14:12]
- mMACENTRY->result=val;
-
- if (!val) {
- printk(" Command OK!! \n");
- if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) {
- ifx_sw_read(0x120,&(status[0]));
- ifx_sw_read(0x121,&(status[1]));
- ifx_sw_read(0x122,&(status[2]));
- ifx_sw_read(0x123,&(status[3]));
- ifx_sw_read(0x124,&(status[4]));
- ifx_sw_read(0x125,&(status[5]));
-
-
- mMACENTRY->mac_addr[0]=(status[0]&0x00ff) ;
- mMACENTRY->mac_addr[1]=(status[0]&0xff00)>>8 ;
- mMACENTRY->mac_addr[2]=(status[1]&0x00ff) ;
- mMACENTRY->mac_addr[3]=(status[1]&0xff00)>>8 ;
- mMACENTRY->mac_addr[4]=(status[2]&0x00ff) ;
- mMACENTRY->mac_addr[5]=(status[2]&0xff00)>>8 ;
- mMACENTRY->fid=(status[3]&0xf);
- mMACENTRY->portmap=((status[3]>>4)&0x3f);
- if (status[5]&0x2) {//static info_ctrl //status5[1]????
- mMACENTRY->ctrl.info_ctrl=(status[4]&0x00ff);
- mMACENTRY->info_type=1;
- }
- else {//not static age_timer
- mMACENTRY->ctrl.age_timer=(status[4]&0x00ff);
- mMACENTRY->info_type=0;
- }
-//status5[13]???? mMACENTRY->occupy=(status[5]&0x02)>>1;//status5[1]
- mMACENTRY->occupy=(status[5]&0x02000)>>13;//status5[13] ???
- mMACENTRY->bad=(status[5]&0x04)>>2;//status5[2]
- }//if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE))
-
- }
- else if (val==0x001)
- printk(" All Entry Used!! \n");
- else if (val==0x002)
- printk(" Entry Not Found!! \n");
- else if (val==0x003)
- printk(" Try Next Entry!! \n");
- else if (val==0x005)
- printk(" Command Error!! \n");
- else
- printk(" UnKnown Error!! \n");
-
- // printk ("adm_process_mac_table_request: Exit\n");
- return 0;
-}
-
-/* Santosh: End of function for MAC ENTRY ADD/DEL*/
-struct file_operations adm_ops =
-{
- read: adm_read,
- write: adm_write,
- open: adm_open,
- release: adm_release,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
- unlocked_ioctl: adm_ioctl
-#else
- ioctl: adm_ioctl
-#endif
-};
-
-int adm_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data)
-{
- int len = 0;
-
- len += sprintf(buf+len, " ************ Registers ************ \n");
- *eof = 1;
- return len;
-}
-
-int __init init_adm6996_module(void)
-{
- unsigned int val = 000;
- unsigned int val1 = 000;
-
- printk("Loading ADM6996 driver... \n");
-
- /* if running on adm5120 */
- /* set GPIO 0~2 as adm6996 control pins */
- //outl(0x003f3f00, 0x12000028);
- /* enable switch port 5 (MII) as RMII mode (5120MAC <-> 6996MAC) */
- //outl(0x18a, 0x12000030);
- /* group adm5120 port 1 ~ 5 as VLAN0, port 5 & 6(CPU) as VLAN1 */
- //outl(0x417e, 0x12000040);
- /* end adm5120 fixup */
-#ifdef ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin
- register_chrdev(69, "adm6996", &adm_ops);
- AMAZON_SW_REG(AMAZON_SW_MDIO_CFG) = 0x27be;
- AMAZON_SW_REG(AMAZON_SW_EPHY) = 0xfc;
- adm6996_mode=adm6996i;
- ifx_sw_read(0xa0, &val);
- ifx_sw_read(0xa1, &val1);
- val=((val1&0x0f)<<16)|val;
- printk ("\nADM6996 SMI Mode-");
- printk ("Chip ID:%5x \n ", val);
-#else //000001.joelin
-
- AMAZON_SW_REG(AMAZON_SW_MDIO_CFG) = 0x2c50;
- AMAZON_SW_REG(AMAZON_SW_EPHY) = 0xff;
-
- AMAZON_SW_REG(AMAZON_GPIO_P1_ALTSEL0) &= ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC);
- AMAZON_SW_REG(AMAZON_GPIO_P1_ALTSEL1) &= ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC);
- AMAZON_SW_REG(AMAZON_GPIO_P1_OD) |= (GPIO_MDIO|GPIO_MDCS|GPIO_MDC);
-
- ifx_gpio_init();
- register_chrdev(69, "adm6996", &adm_ops);
- mdelay(100);
-
- /* create proc entries */
- // create_proc_read_entry("admide", 0, NULL, admide_proc, NULL);
-
-//joelin adm6996i support start
- adm6996_mode=adm6996i;
- ifx_sw_read(0xa0, &val);
- adm6996_mode=adm6996l;
- ifx_sw_read(0x200, &val1);
-// printk ("\n %0x \n",val1);
- if ((val&0xfff0)==0x1020) {
- printk ("\n ADM6996I .. \n");
- adm6996_mode=adm6996i;
- }
- else if ((val1&0xffffff00)==0x71000) {//71010 or 71020
- printk ("\n ADM6996LC .. \n");
- adm6996_mode=adm6996lc;
- }
- else {
- printk ("\n ADM6996L .. \n");
- adm6996_mode=adm6996l;
- }
-#endif //ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin
-
- if ((adm6996_mode==adm6996lc)||(adm6996_mode==adm6996i)){
-#if 0 /* removed by MarsLin */
- ifx_sw_write(0x29,0xc000);
- ifx_sw_write(0x30,0x0985);
-#else
- ifx_sw_read(0xa0, &val);
- if (val == 0x1021) // for both 6996LC and 6996I, only AB version need the patch
- ifx_sw_write(0x29, 0x9000);
- ifx_sw_write(0x30,0x0985);
-#endif
- }
-//joelin adm6996i support end
- return 0;
-}
-
-void __exit cleanup_adm6996_module(void)
-{
- printk("Free ADM device driver... \n");
-
- unregister_chrdev(69, "adm6996");
-
- /* remove proc entries */
- // remove_proc_entry("admide", NULL);
-}
-
-/* MarsLin, add start */
-#if defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT) || defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT_MODULE)
- #define SET_BIT(reg, mask) reg |= (mask)
- #define CLEAR_BIT(reg, mask) reg &= (~mask)
- static int ifx_hw_reset(void)
- {
- CLEAR_BIT((*AMAZON_GPIO_P0_ALTSEL0),0x2000);
- CLEAR_BIT((*AMAZON_GPIO_P0_ALTSEL1),0x2000);
- SET_BIT((*AMAZON_GPIO_P0_OD),0x2000);
- SET_BIT((*AMAZON_GPIO_P0_DIR), 0x2000);
- CLEAR_BIT((*AMAZON_GPIO_P0_OUT), 0x2000);
- mdelay(500);
- SET_BIT((*AMAZON_GPIO_P0_OUT), 0x2000);
- cleanup_adm6996_module();
- return init_adm6996_module();
- }
- int (*adm6996_hw_reset)(void) = ifx_hw_reset;
- EXPORT_SYMBOL(adm6996_hw_reset);
- EXPORT_SYMBOL(adm6996_mode);
- int (*adm6996_sw_read)(unsigned int addr, unsigned int *data) = ifx_sw_read;
- EXPORT_SYMBOL(adm6996_sw_read);
- int (*adm6996_sw_write)(unsigned int addr, unsigned int data) = ifx_sw_write;
- EXPORT_SYMBOL(adm6996_sw_write);
-#endif
-/* MarsLin, add end */
-
-/* Santosh: for IGMP proxy/snooping, Begin */
-EXPORT_SYMBOL (adm_process_mac_table_request);
-EXPORT_SYMBOL (adm_process_protocol_filter_request);
-/* Santosh: for IGMP proxy/snooping, End */
-
-MODULE_DESCRIPTION("ADMtek 6996 Driver");
-MODULE_AUTHOR("Joe Lin <joe.lin@infineon.com>");
-MODULE_LICENSE("GPL");
-
-module_init(init_adm6996_module);
-module_exit(cleanup_adm6996_module);
-
diff --git a/target/linux/amazon/files/drivers/net/ethernet/amazon_sw.c b/target/linux/amazon/files/drivers/net/ethernet/amazon_sw.c
deleted file mode 100644
index d18b439cea..0000000000
--- a/target/linux/amazon/files/drivers/net/ethernet/amazon_sw.c
+++ /dev/null
@@ -1,899 +0,0 @@
-/*
- * This program 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 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-//-----------------------------------------------------------------------
-/*
- * Description:
- * Driver for Infineon Amazon 3 port switch
- */
-//-----------------------------------------------------------------------
-/* Author: Wu Qi Ming[Qi-Ming.Wu@infineon.com]
- * Created: 7-April-2004
- */
-//-----------------------------------------------------------------------
-/* History
- * Changed on: Jun 28, 2004
- * Changed by: peng.liu@infineon.com
- * Reason: add hardware flow control (HFC) (CONFIG_NET_HW_FLOWCONTROL)
- *
- * Changed on: Apr 6, 2005
- * Changed by: mars.lin@infineon.com
- * Reason : supoort port identification
- */
-
-
-// copyright 2004-2005 infineon.com
-
-// copyright 2007 john crispin <blogic@openwrt.org>
-// copyright 2007 felix fietkau <nbd@openwrt.org>
-// copyright 2009 hauke mehrtens <hauke@hauke-m.de>
-
-
-// TODO
-// port vlan code from bcrm target... the tawainese code was scrapped due to crappyness
-// check all the mmi reg settings and possibly document them better
-// verify the ethtool code
-// remove the while(1) stuff
-// further clean up and rework ... but it works for now
-// check the mode[]=bridge stuff
-// verify that the ethaddr can be set from u-boot
-
-
-#ifndef __KERNEL__
-#define __KERNEL__
-#endif
-
-
-#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
-#define MODVERSIONS
-#endif
-
-#if defined(MODVERSIONS) && !defined(__GENKSYMS__)
-#include <linux/modversions.h>
-#endif
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/mii.h>
-#include <asm/uaccess.h>
-#include <linux/in.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/skbuff.h>
-#include <linux/in6.h>
-#include <linux/proc_fs.h>
-#include <linux/mm.h>
-#include <linux/ethtool.h>
-#include <asm/checksum.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include <asm/amazon/amazon.h>
-#include <asm/amazon/amazon_dma.h>
-#include <asm/amazon/amazon_sw.h>
-
-// how many mii ports are there ?
-#define AMAZON_SW_INT_NO 2
-
-#define ETHERNET_PACKET_DMA_BUFFER_SIZE 1536
-
-/***************************************** Module Parameters *************************************/
-static char mode[] = "bridge";
-module_param_array(mode, charp, NULL, 0);
-
-static int timeout = 1 * HZ;
-module_param(timeout, int, 0);
-
-int switch_init(struct net_device *dev);
-void switch_tx_timeout(struct net_device *dev);
-
-static struct net_device *switch_devs[2];
-
-int add_mac_table_entry(u64 entry_value)
-{
- int i;
- u32 data1, data2;
-
- AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) = ~7;
-
- for (i = 0; i < 32; i++) {
- AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0x80000000 | 0x20 | i;
- while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {};
- data1 = AMAZON_SW_REG32(AMAZON_SW_DATA1);
- data2 = AMAZON_SW_REG32(AMAZON_SW_DATA2);
- if ((data1 & (0x00700000)) != 0x00700000)
- continue;
- AMAZON_SW_REG32(AMAZON_SW_DATA1) = (u32) (entry_value >> 32);
- AMAZON_SW_REG32(AMAZON_SW_DATA2) = (u32) entry_value & 0xffffffff;
- AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0xc0000020 | i;
- while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {};
- break;
- }
- AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) |= 7;
- if (i >= 32)
- return -1;
- return OK;
-}
-
-u64 read_mac_table_entry(int index)
-{
- u32 data1, data2;
- u64 value;
- AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0x80000000 | 0x20 | index;
- while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {};
- data1 = AMAZON_SW_REG32(AMAZON_SW_DATA1) & 0xffffff;
- data2 = AMAZON_SW_REG32(AMAZON_SW_DATA2);
- value = (u64) data1 << 32 | (u64) data2;
- return value;
-}
-
-int write_mac_table_entry(int index, u64 value)
-{
- u32 data1, data2;
- data1 = (u32) (value >> 32);
- data2 = (u32) value & 0xffffffff;
- AMAZON_SW_REG32(AMAZON_SW_DATA1) = data1;
- AMAZON_SW_REG32(AMAZON_SW_DATA2) = data2;
- AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0xc0000020 | index;
- while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {};
- return OK;
-}
-
-u32 get_mdio_reg(int phy_addr, int reg_num)
-{
- u32 value;
- AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = (3 << 30) | ((phy_addr & 0x1f) << 21) | ((reg_num & 0x1f) << 16);
- while (AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & (1 << 31)) {};
- value = AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & 0xffff;
- return value;
-}
-
-int set_mdio_reg(int phy_addr, int reg_num, u32 value)
-{
- AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = (2 << 30) | ((phy_addr & 0x1f) << 21) | ((reg_num & 0x1f) << 16) | (value & 0xffff);
- while (AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & (1 << 31)) {};
- return OK;
-}
-
-int auto_negotiate(int phy_addr)
-{
- u32 value = 0;
- value = get_mdio_reg(phy_addr, MDIO_BASE_CONTROL_REG);
- set_mdio_reg(phy_addr, MDIO_BASE_CONTROL_REG, (value | RESTART_AUTO_NEGOTIATION | AUTO_NEGOTIATION_ENABLE | PHY_RESET));
- return OK;
-}
-
-/*
- In this version of switch driver, we split the dma channels for the switch.
- 2 for port0 and 2 for port1. So that we can do internal bridging if necessary.
- In switch mode, packets coming in from port0 or port1 is able to do Destination
- address lookup. Packets coming from port0 with destination address of port1 should
- not go to pmac again. The switch hardware should be able to do the switch in the hard
- ware level. Packets coming from the pmac should not do the DA look up in that the
- desination is already known for the kernel. It only needs to go to the correct NIC to
- find its way out.
- */
-int amazon_sw_chip_init(void)
-{
- u32 tmp1;
- int i = 0;
-
- /* Aging tick select: 5mins */
- tmp1 = 0xa0;
- if (strcmp(mode, "bridge") == 0) {
- // bridge mode, set militarised mode to 1, no learning!
- tmp1 |= 0xC00;
- } else {
- // enable learning for P0 and P1,
- tmp1 |= 3;
- }
-
- /* unknown broadcast/multicast/unicast to all ports */
- AMAZON_SW_REG32(AMAZON_SW_UN_DEST) = 0x1ff;
-
- AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) = tmp1;
-
- /* OCS:1 set OCS bit, split the two NIC in rx direction EDL:1 (enable DA lookup) */
-#if defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT) || defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT_MODULE)
- AMAZON_SW_REG32(AMAZON_SW_P2_PCTL) = 0x700;
-#else
- AMAZON_SW_REG32(AMAZON_SW_P2_PCTL) = 0x401;
-#endif
-
- /* EPC: 1 split the two NIC in tx direction CRC is generated */
- AMAZON_SW_REG32(AMAZON_SW_P2_CTL) = 0x6;
-
- // for bi-directional
- AMAZON_SW_REG32(AMAZON_SW_P0_WM) = 0x14141412;
- AMAZON_SW_REG32(AMAZON_SW_P1_WM) = 0x14141412;
- AMAZON_SW_REG32(AMAZON_SW_P2_WM) = 0x28282826;
- AMAZON_SW_REG32(AMAZON_SW_GBL_WM) = 0x0;
-
- AMAZON_SW_REG32(AMAZON_CGU_PLL0SR) = (AMAZON_SW_REG32(AMAZON_CGU_PLL0SR)) | 0x58000000;
- // clock for PHY
- AMAZON_SW_REG32(AMAZON_CGU_IFCCR) = (AMAZON_SW_REG32(AMAZON_CGU_IFCCR)) | 0x80000004;
- // enable power for PHY
- AMAZON_SW_REG32(AMAZON_PMU_PWDCR) = (AMAZON_SW_REG32(AMAZON_PMU_PWDCR)) | AMAZON_PMU_PWDCR_EPHY;
- // set reverse MII, enable MDIO statemachine
- AMAZON_SW_REG32(AMAZON_SW_MDIO_CFG) = 0x800027bf;
- while (1)
- if (((AMAZON_SW_REG32(AMAZON_SW_MDIO_CFG)) & 0x80000000) == 0)
- break;
- AMAZON_SW_REG32(AMAZON_SW_EPHY) = 0xff;
-
- // auto negotiation
- AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = 0x83e08000;
- auto_negotiate(0x1f);
-
- /* enable all ports */
- AMAZON_SW_REG32(AMAZON_SW_PS_CTL) = 0x7;
- for (i = 0; i < 32; i++)
- write_mac_table_entry(i, 1 << 50);
- return 0;
-}
-
-static unsigned char my_ethaddr[MAX_ADDR_LEN];
-/* need to get the ether addr from u-boot */
-static int __init ethaddr_setup(char *line)
-{
- char *ep;
- int i;
-
- memset(my_ethaddr, 0, MAX_ADDR_LEN);
- for (i = 0; i < 6; i++) {
- my_ethaddr[i] = line ? simple_strtoul(line, &ep, 16) : 0;
- if (line)
- line = (*ep) ? ep + 1 : ep;
- }
- printk(KERN_INFO "amazon_mii0: mac address %2x-%2x-%2x-%2x-%2x-%2x \n", my_ethaddr[0], my_ethaddr[1], my_ethaddr[2], my_ethaddr[3], my_ethaddr[4], my_ethaddr[5]);
- return 0;
-}
-
-__setup("ethaddr=", ethaddr_setup);
-
-static void open_rx_dma(struct net_device *dev)
-{
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
- struct dma_device_info *dma_dev = priv->dma_device;
- int i;
-
- for (i = 0; i < dma_dev->num_rx_chan; i++)
- dma_dev->rx_chan[i].control = 1;
- dma_device_update_rx(dma_dev);
-}
-
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-static void close_rx_dma(struct net_device *dev)
-{
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
- struct dma_device_info *dma_dev = priv->dma_device;
- int i;
-
- for (i = 0; i < dma_dev->num_rx_chan; i++)
- dma_dev->rx_chan[i].control = 0;
- dma_device_update_rx(dma_dev);
-}
-
-void amazon_xon(struct net_device *dev)
-{
- unsigned long flag;
- local_irq_save(flag);
- open_rx_dma(dev);
- local_irq_restore(flag);
-}
-#endif
-
-int switch_open(struct net_device *dev)
-{
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
- if (!strcmp(dev->name, "eth1")) {
- priv->mdio_phy_addr = PHY0_ADDR;
- }
- open_rx_dma(dev);
-
-#ifdef CONFIG_NET_HW_FLOWCONTROL
- if ((priv->fc_bit = netdev_register_fc(dev, amazon_xon)) == 0) {
- printk(KERN_WARNING "amazon_mii0: Hardware Flow Control register fails\n");
- }
-#endif
-
- netif_start_queue(dev);
- return OK;
-}
-
-int switch_release(struct net_device *dev)
-{
- int i;
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
- struct dma_device_info *dma_dev = priv->dma_device;
-
- for (i = 0; i < dma_dev->num_tx_chan; i++)
- dma_dev->tx_chan[i].control = 0;
- for (i = 0; i < dma_dev->num_rx_chan; i++)
- dma_dev->rx_chan[i].control = 0;
-
- dma_device_update(dma_dev);
-
-#ifdef CONFIG_NET_HW_FLOWCONTROL
- if (priv->fc_bit) {
- netdev_unregister_fc(priv->fc_bit);
- }
-#endif
- netif_stop_queue(dev);
-
- return OK;
-}
-
-
-void switch_rx(struct net_device *dev, int len, struct sk_buff *skb)
-{
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
-#ifdef CONFIG_NET_HW_FLOWCONTROL
- int mit_sel = 0;
-#endif
- skb->dev = dev;
- skb->protocol = eth_type_trans(skb, dev);
-
-#ifdef CONFIG_NET_HW_FLOWCONTROL
- mit_sel = netif_rx(skb);
- switch (mit_sel) {
- case NET_RX_SUCCESS:
- case NET_RX_CN_LOW:
- case NET_RX_CN_MOD:
- break;
- case NET_RX_CN_HIGH:
- break;
- case NET_RX_DROP:
- if ((priv->fc_bit)
- && (!test_and_set_bit(priv->fc_bit, &netdev_fc_xoff))) {
- close_rx_dma(dev);
- }
- break;
- }
-#else
- netif_rx(skb);
-#endif
- priv->stats.rx_packets++;
- priv->stats.rx_bytes += len;
- return;
-}
-
-int asmlinkage switch_hw_tx(char *buf, int len, struct net_device *dev)
-{
- struct switch_priv *priv = netdev_priv(dev);
- struct dma_device_info *dma_dev = priv->dma_device;
-
- dma_dev->current_tx_chan = 0;
- return dma_device_write(dma_dev, buf, len, priv->skb);
-}
-
-int asmlinkage switch_tx(struct sk_buff *skb, struct net_device *dev)
-{
- int len;
- char *data;
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
-
- len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
- data = skb->data;
- priv->skb = skb;
- dev->trans_start = jiffies;
-
- if (switch_hw_tx(data, len, dev) != len) {
- dev_kfree_skb_any(skb);
- return OK;
- }
-
- priv->stats.tx_packets++;
- priv->stats.tx_bytes += len;
- return OK;
-}
-
-void switch_tx_timeout(struct net_device *dev)
-{
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
- priv->stats.tx_errors++;
- netif_wake_queue(dev);
- return;
-}
-
-void negotiate(struct net_device *dev)
-{
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
- unsigned short data = get_mdio_reg(priv->mdio_phy_addr, MDIO_ADVERTISMENT_REG);
-
- data &= ~(MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD);
-
- switch (priv->current_speed_selection) {
- case 10:
- if (priv->current_duplex == full)
- data |= MDIO_ADVERT_10_FD;
- else if (priv->current_duplex == half)
- data |= MDIO_ADVERT_10_HD;
- else
- data |= MDIO_ADVERT_10_HD | MDIO_ADVERT_10_FD;
- break;
-
- case 100:
- if (priv->current_duplex == full)
- data |= MDIO_ADVERT_100_FD;
- else if (priv->current_duplex == half)
- data |= MDIO_ADVERT_100_HD;
- else
- data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD;
- break;
-
- case 0: /* Auto */
- if (priv->current_duplex == full)
- data |= MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD;
- else if (priv->current_duplex == half)
- data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_10_HD;
- else
- data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD;
- break;
-
- default: /* assume autoneg speed and duplex */
- data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD;
- }
-
- set_mdio_reg(priv->mdio_phy_addr, MDIO_ADVERTISMENT_REG, data);
-
- /* Renegotiate with link partner */
-
- data = get_mdio_reg(priv->mdio_phy_addr, MDIO_BASE_CONTROL_REG);
- data |= MDIO_BC_NEGOTIATE;
-
- set_mdio_reg(priv->mdio_phy_addr, MDIO_BASE_CONTROL_REG, data);
-
-}
-
-
-void set_duplex(struct net_device *dev, enum duplex new_duplex)
-{
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
- if (new_duplex != priv->current_duplex) {
- priv->current_duplex = new_duplex;
- negotiate(dev);
- }
-}
-
-void set_speed(struct net_device *dev, unsigned long speed)
-{
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
- priv->current_speed_selection = speed;
- negotiate(dev);
-}
-
-static int switch_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
-{
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
- struct ethtool_cmd ecmd;
-
- if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd)))
- return -EFAULT;
-
- switch (ecmd.cmd) {
- case ETHTOOL_GSET:
- memset((void *) &ecmd, 0, sizeof(ecmd));
- ecmd.supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
- ecmd.port = PORT_TP;
- ecmd.transceiver = XCVR_EXTERNAL;
- ecmd.phy_address = priv->mdio_phy_addr;
-
- ecmd.speed = priv->current_speed;
-
- ecmd.duplex = priv->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
-
- ecmd.advertising = ADVERTISED_TP;
- if (priv->current_duplex == autoneg && priv->current_speed_selection == 0)
- ecmd.advertising |= ADVERTISED_Autoneg;
- else {
- ecmd.advertising |= ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
- if (priv->current_speed_selection == 10)
- ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full);
- else if (priv->current_speed_selection == 100)
- ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full);
- if (priv->current_duplex == half)
- ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full);
- else if (priv->current_duplex == full)
- ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half);
- }
- ecmd.autoneg = AUTONEG_ENABLE;
- if (copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd)))
- return -EFAULT;
- break;
-
- case ETHTOOL_SSET:
- if (!capable(CAP_NET_ADMIN)) {
- return -EPERM;
- }
- if (ecmd.autoneg == AUTONEG_ENABLE) {
- set_duplex(dev, autoneg);
- set_speed(dev, 0);
- } else {
- set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full);
- set_speed(dev, ecmd.speed == SPEED_10 ? 10 : 100);
- }
- break;
-
- case ETHTOOL_GDRVINFO:
- {
- struct ethtool_drvinfo info;
- memset((void *) &info, 0, sizeof(info));
- strncpy(info.driver, "AMAZONE", sizeof(info.driver) - 1);
- strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1);
- strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1);
- info.regdump_len = 0;
- info.eedump_len = 0;
- info.testinfo_len = 0;
- if (copy_to_user(ifr->ifr_data, &info, sizeof(info)))
- return -EFAULT;
- }
- break;
- case ETHTOOL_NWAY_RST:
- if (priv->current_duplex == autoneg && priv->current_speed_selection == 0)
- negotiate(dev);
- break;
- default:
- return -EOPNOTSUPP;
- break;
- }
- return 0;
-}
-
-
-
-int mac_table_tools_ioctl(struct net_device *dev, struct mac_table_req *req)
-{
- int cmd;
- int i;
- cmd = req->cmd;
- switch (cmd) {
- case RESET_MAC_TABLE:
- for (i = 0; i < 32; i++) {
- write_mac_table_entry(i, 0);
- }
- break;
- case READ_MAC_ENTRY:
- req->entry_value = read_mac_table_entry(req->index);
- break;
- case WRITE_MAC_ENTRY:
- write_mac_table_entry(req->index, req->entry_value);
- break;
- case ADD_MAC_ENTRY:
- add_mac_table_entry(req->entry_value);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-/*
- the ioctl for the switch driver is developed in the conventional way
- the control type falls into some basic categories, among them, the
- SIOCETHTOOL is the traditional eth interface. VLAN_TOOLS and
- MAC_TABLE_TOOLS are designed specifically for amazon chip. User
- should be aware of the data structures used in these interfaces.
-*/
-int switch_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
- struct data_req *switch_data_req = (struct data_req *) ifr->ifr_data;
- struct mac_table_req *switch_mac_table_req;
- switch (cmd) {
- case SIOCETHTOOL:
- switch_ethtool_ioctl(dev, ifr);
- break;
- case SIOCGMIIPHY: /* Get PHY address */
- break;
- case SIOCGMIIREG: /* Read MII register */
- break;
- case SIOCSMIIREG: /* Write MII register */
- break;
- case SET_ETH_SPEED_10: /* 10 Mbps */
- break;
- case SET_ETH_SPEED_100: /* 100 Mbps */
- break;
- case SET_ETH_SPEED_AUTO: /* Auto negotiate speed */
- break;
- case SET_ETH_DUPLEX_HALF: /* Half duplex. */
- break;
- case SET_ETH_DUPLEX_FULL: /* Full duplex. */
- break;
- case SET_ETH_DUPLEX_AUTO: /* Autonegotiate duplex */
- break;
- case SET_ETH_REG:
- AMAZON_SW_REG32(switch_data_req->index) = switch_data_req->value;
- break;
- case MAC_TABLE_TOOLS:
- switch_mac_table_req = (struct mac_table_req *) ifr->ifr_data;
- mac_table_tools_ioctl(dev, switch_mac_table_req);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-struct net_device_stats *switch_stats(struct net_device *dev)
-{
- struct switch_priv *priv = (struct switch_priv *) netdev_priv(dev);
- return &priv->stats;
-}
-
-int switch_change_mtu(struct net_device *dev, int new_mtu)
-{
- if (new_mtu >= 1516)
- new_mtu = 1516;
- dev->mtu = new_mtu;
- return 0;
-}
-
-int switch_hw_receive(struct net_device *dev, struct dma_device_info *dma_dev)
-{
- u8 *buf = NULL;
- int len = 0;
- struct sk_buff *skb = NULL;
-
- len = dma_device_read(dma_dev, &buf, (void **) &skb);
-
- if (len >= 0x600) {
- printk(KERN_WARNING "amazon_mii0: packet too large %d\n", len);
- goto switch_hw_receive_err_exit;
- }
-
- /* remove CRC */
- len -= 4;
- if (skb == NULL) {
- printk(KERN_WARNING "amazon_mii0: cannot restore pointer\n");
- goto switch_hw_receive_err_exit;
- }
- if (len > (skb->end - skb->tail)) {
- printk(KERN_WARNING "amazon_mii0: BUG, len:%d end:%p tail:%p\n", (len + 4), skb->end, skb->tail);
- goto switch_hw_receive_err_exit;
- }
- skb_put(skb, len);
- skb->dev = dev;
- switch_rx(dev, len, skb);
- return OK;
-
- switch_hw_receive_err_exit:
- if (skb)
- dev_kfree_skb_any(skb);
- return -EIO;
-}
-
-int dma_intr_handler(struct dma_device_info *dma_dev, int status)
-{
- struct net_device *dev;
-
- dev = dma_dev->priv;
- switch (status) {
- case RCV_INT:
- switch_hw_receive(dev, dma_dev);
- break;
- case TX_BUF_FULL_INT:
- netif_stop_queue(dev);
- break;
- case TRANSMIT_CPT_INT:
- netif_wake_queue(dev);
- break;
- }
- return OK;
-}
-
-/* reserve 2 bytes in front of data pointer*/
-u8 *dma_buffer_alloc(int len, int *byte_offset, void **opt)
-{
- u8 *buffer = NULL;
- struct sk_buff *skb = NULL;
- skb = dev_alloc_skb(ETHERNET_PACKET_DMA_BUFFER_SIZE);
- if (skb == NULL) {
- return NULL;
- }
- buffer = (u8 *) (skb->data);
- skb_reserve(skb, 2);
- *(int *) opt = (int) skb;
- *byte_offset = 2;
- return buffer;
-}
-
-int dma_buffer_free(u8 * dataptr, void *opt)
-{
- struct sk_buff *skb = NULL;
- if (opt == NULL) {
- kfree(dataptr);
- } else {
- skb = (struct sk_buff *) opt;
- dev_kfree_skb_any(skb);
- }
- return OK;
-}
-
-int init_dma_device(_dma_device_info * dma_dev, struct net_device *dev)
-{
- int i;
- int num_tx_chan, num_rx_chan;
- if (strcmp(dma_dev->device_name, "switch1") == 0) {
- num_tx_chan = 1;
- num_rx_chan = 2;
- } else {
- num_tx_chan = 1;
- num_rx_chan = 2;
- }
- dma_dev->priv = dev;
-
- dma_dev->weight = 1;
- dma_dev->num_tx_chan = num_tx_chan;
- dma_dev->num_rx_chan = num_rx_chan;
- dma_dev->ack = 1;
- dma_dev->tx_burst_len = 4;
- dma_dev->rx_burst_len = 4;
- for (i = 0; i < dma_dev->num_tx_chan; i++) {
- dma_dev->tx_chan[i].weight = QOS_DEFAULT_WGT;
- dma_dev->tx_chan[i].desc_num = 10;
- dma_dev->tx_chan[i].packet_size = 0;
- dma_dev->tx_chan[i].control = 0;
- }
- for (i = 0; i < num_rx_chan; i++) {
- dma_dev->rx_chan[i].weight = QOS_DEFAULT_WGT;
- dma_dev->rx_chan[i].desc_num = 10;
- dma_dev->rx_chan[i].packet_size = ETHERNET_PACKET_DMA_BUFFER_SIZE;
- dma_dev->rx_chan[i].control = 0;
- }
- dma_dev->intr_handler = dma_intr_handler;
- dma_dev->buffer_alloc = dma_buffer_alloc;
- dma_dev->buffer_free = dma_buffer_free;
- return 0;
-}
-
-int switch_set_mac_address(struct net_device *dev, void *p)
-{
- struct sockaddr *addr = p;
- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
- return OK;
-}
-
-static const struct net_device_ops amazon_mii_ops = {
- .ndo_init = switch_init,
- .ndo_open = switch_open,
- .ndo_stop = switch_release,
- .ndo_start_xmit = switch_tx,
- .ndo_do_ioctl = switch_ioctl,
- .ndo_get_stats = switch_stats,
- .ndo_change_mtu = switch_change_mtu,
- .ndo_set_mac_address = switch_set_mac_address,
- .ndo_tx_timeout = switch_tx_timeout,
-};
-
-int switch_init(struct net_device *dev)
-{
- u64 retval = 0;
- int i;
- int result;
- struct switch_priv *priv;
- ether_setup(dev); /* assign some of the fields */
- printk(KERN_INFO "amazon_mii0: %s up using ", dev->name);
- dev->watchdog_timeo = timeout;
-
- priv = netdev_priv(dev);
- priv->dma_device = (struct dma_device_info *) kmalloc(sizeof(struct dma_device_info), GFP_KERNEL);
- if (priv->num == 0) {
- sprintf(priv->dma_device->device_name, "switch1");
- } else if (priv->num == 1) {
- sprintf(priv->dma_device->device_name, "switch2");
- }
- printk("\"%s\"\n", priv->dma_device->device_name);
- init_dma_device(priv->dma_device, dev);
- result = dma_device_register(priv->dma_device);
-
- /* read the mac address from the mac table and put them into the mac table. */
- for (i = 0; i < 6; i++) {
- retval += my_ethaddr[i];
- }
- /* ethaddr not set in u-boot ? */
- if (retval == 0) {
- dev->dev_addr[0] = 0x00;
- dev->dev_addr[1] = 0x20;
- dev->dev_addr[2] = 0xda;
- dev->dev_addr[3] = 0x86;
- dev->dev_addr[4] = 0x23;
- dev->dev_addr[5] = 0x74 + (unsigned char) priv->num;
- } else {
- for (i = 0; i < 6; i++) {
- dev->dev_addr[i] = my_ethaddr[i];
- }
- dev->dev_addr[5] += +(unsigned char) priv->num;
- }
- return OK;
-}
-
-static int amazon_mii_probe(struct platform_device *dev)
-{
- int i = 0, result, device_present = 0;
- struct switch_priv *priv;
-
- for (i = 0; i < AMAZON_SW_INT_NO; i++) {
- switch_devs[i] = alloc_etherdev(sizeof(struct switch_priv));
- switch_devs[i]->netdev_ops = &amazon_mii_ops;
- strcpy(switch_devs[i]->name, "eth%d");
- priv = (struct switch_priv *) netdev_priv(switch_devs[i]);
- priv->num = i;
- if ((result = register_netdev(switch_devs[i])))
- printk(KERN_WARNING "amazon_mii0: error %i registering device \"%s\"\n", result, switch_devs[i]->name);
- else
- device_present++;
- }
- amazon_sw_chip_init();
- return device_present ? 0 : -ENODEV;
-}
-
-static int amazon_mii_remove(struct platform_device *dev)
-{
- int i;
- struct switch_priv *priv;
- for (i = 0; i < AMAZON_SW_INT_NO; i++) {
- priv = netdev_priv(switch_devs[i]);
- if (priv->dma_device) {
- dma_device_unregister(priv->dma_device);
- kfree(priv->dma_device);
- }
- kfree(netdev_priv(switch_devs[i]));
- unregister_netdev(switch_devs[i]);
- }
- return 0;
-}
-
-static struct platform_driver amazon_mii_driver = {
- .probe = amazon_mii_probe,
- .remove = amazon_mii_remove,
- .driver = {
- .name = "amazon_mii0",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init amazon_mii_init(void)
-{
- int ret = platform_driver_register(&amazon_mii_driver);
- if (ret)
- printk(KERN_WARNING "amazon_mii0: Error registering platfom driver!\n");
- return ret;
-}
-
-static void __exit amazon_mii_cleanup(void)
-{
- platform_driver_unregister(&amazon_mii_driver);
-}
-
-module_init(amazon_mii_init);
-module_exit(amazon_mii_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Wu Qi Ming");
-MODULE_DESCRIPTION("ethernet driver for AMAZON boards");
-