aboutsummaryrefslogtreecommitdiffstats
path: root/package/linux/kernel-patches/027-drivers_net_port_based_qos
diff options
context:
space:
mode:
Diffstat (limited to 'package/linux/kernel-patches/027-drivers_net_port_based_qos')
-rw-r--r--package/linux/kernel-patches/027-drivers_net_port_based_qos1173
1 files changed, 1173 insertions, 0 deletions
diff --git a/package/linux/kernel-patches/027-drivers_net_port_based_qos b/package/linux/kernel-patches/027-drivers_net_port_based_qos
new file mode 100644
index 0000000000..bb3ad6f6dc
--- /dev/null
+++ b/package/linux/kernel-patches/027-drivers_net_port_based_qos
@@ -0,0 +1,1173 @@
+diff -Nur linux-mips-cvs/drivers/net/port_based_qos/Atan.c linux-broadcom/drivers/net/port_based_qos/Atan.c
+--- linux-mips-cvs/drivers/net/port_based_qos/Atan.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-broadcom/drivers/net/port_based_qos/Atan.c 2005-01-31 13:13:14.000000000 +0100
+@@ -0,0 +1,177 @@
++#include "Atan.h"
++#include "c47xx.h"
++
++extern void conf_gpio(int x);
++
++/*----------------------------------------------------------------------------
++Write specified data to eeprom
++entry: *src = pointer to specified data to write
++ len = number of short(2 bytes) to be written
++*/
++void write_eeprom( short RegNumber, unsigned short *data, int len )
++{
++ int i2;
++ unsigned short s_addr, s_data;
++ unsigned short *src;
++
++ src = data;
++ SetEEpromToSendState();
++// the write enable(WEN) instruction must be executed before any device
++// programming can be done
++
++ s_data = 0x04c0;
++ SendAddrToEEprom(s_data); //00000001 0011000000B
++ SetCSToLowForEEprom();
++
++ s_addr = 0x0500 | (RegNumber & 0x0ff); //00000001 01dddddddd
++ s_data = *src;
++
++ for (i2 = len; i2 > 0 ; i2 --)
++ {
++ SendAddrToEEprom(s_addr); //00000001 01dddddd
++ SendDataToEEprom(s_data); //dddddddd dddddddd
++ SetCSToLowForEEprom();
++ SetCSToLowForEEprom();
++ //WriteWait();
++ s_addr ++;
++ src ++;
++ s_data = *src;
++ }
++// after all data has been written to EEprom , the write disable(WDS)
++// instruction must be executed
++ SetCSToHighForEEprom();
++ s_data = 0x0400;
++ SendAddrToEEprom(s_data); //00000001 00000000B
++ SetCSToLowForEEprom();
++ SetCSToLowForEEprom();
++}
++
++void SetEEpromToSendState()
++{
++ conf_gpio(0x0);
++ conf_gpio(0x0);
++ conf_gpio(B_ECS);
++ conf_gpio(B_ECS);
++
++// ;cs __-- ,bit 2
++// ;sck ____ ,bit 3
++// ;di ____ ,bit 5
++// ;do ____ ,bit 4
++// ;
++}
++
++void ResetEEpromToSendState()
++{
++ conf_gpio(0x0);
++ conf_gpio(0x0);
++ conf_gpio(0x0);
++ conf_gpio(0x0);
++
++// ;cs ____ ,bit 2
++// ;sck ____ ,bit 3
++// ;di ____ ,bit 5
++// ;do ____ ,bit 4
++// ;
++}
++
++void SetCSToLowForEEprom()
++{
++ conf_gpio(0x0);
++ conf_gpio(B_ECK);
++ conf_gpio(B_ECK);
++ conf_gpio(0x0);
++
++// ;cs ____ ,bit 2
++// ;sck _--_ ,bit 3
++// ;di ____ ,bit 5
++// ;do ____ ,bit 4
++// ;
++}
++
++void SetCSToHighForEEprom()
++{
++ conf_gpio(B_ECS);
++ conf_gpio(B_ECS|B_ECK);
++ conf_gpio(B_ECS|B_ECK);
++ conf_gpio(B_ECS);
++
++// ;cs ---- ,bit 2
++// ;sck _--_ ,bit 3
++// ;di ____ ,bit 5
++// ;do ____ ,bit 4
++// ;
++}
++
++void send_1ToEEprom()
++{
++ conf_gpio(B_ECS|B_EDI);
++ conf_gpio(B_ECS|B_ECK|B_EDI);
++ conf_gpio(B_ECS|B_ECK|B_EDI);
++ conf_gpio(B_ECS|B_EDI);
++
++// ;cs ---- ,bit 2
++// ;sck _--_ ,bit 3
++// ;di ---- ,bit 5
++// ;do ____ ,bit 4
++// ;
++}
++
++void send_0ToEEprom()
++{
++ conf_gpio(B_ECS);
++ conf_gpio(B_ECS|B_ECK);
++ conf_gpio(B_ECS|B_ECK);
++ conf_gpio(B_ECS);
++
++// ;cs ---- ,bit 2
++// ;sck _--_ ,bit 3
++// ;di ____ ,bit 5
++// ;do ____ ,bit 4
++// ;
++}
++
++#if 0
++void WriteWait()
++{
++ unsigned int status;
++
++ SetCSToLowForEEprom();
++ SetCSToHighForEEprom();
++ do {
++ SetCSToHighForEEprom();
++ //status = ReadGPIOData(EDO);
++ status = gpio & B_EDO; // read EDO bit
++ }
++ while (!status); // wait for write - ready
++ SetCSToLowForEEprom();
++}
++#endif
++
++void SendDataToEEprom(short s_data)
++{
++ int data_mask;
++
++ for (data_mask = 0x8000; data_mask != 0; )
++ {
++ if (s_data & data_mask)
++ send_1ToEEprom();
++ else
++ send_0ToEEprom();
++ data_mask = data_mask >> 1;
++ }
++}
++
++void SendAddrToEEprom(short s_data)
++{
++ int data_mask;
++
++ for (data_mask = 0x0400 ;data_mask != 0; )
++ {
++ if (s_data & data_mask)
++ send_1ToEEprom();
++ else
++ send_0ToEEprom();
++ data_mask = data_mask >> 1;
++ }
++}
++
+diff -Nur linux-mips-cvs/drivers/net/port_based_qos/Atan.h linux-broadcom/drivers/net/port_based_qos/Atan.h
+--- linux-mips-cvs/drivers/net/port_based_qos/Atan.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-broadcom/drivers/net/port_based_qos/Atan.h 2005-01-31 13:13:14.000000000 +0100
+@@ -0,0 +1,18 @@
++#ifndef _ATAN_H_
++#define _ATAN_H_
++
++#define SINGLECOLOUR 0x1
++#define DUALCOLOUR 0x2
++
++void write_eeprom(short,unsigned short *,int);
++void SetEEpromToSendState(void);
++void ResetEEpromToSendState(void);
++void SetCSToLowForEEprom(void);
++void SetCSToHighForEEprom(void);
++void send_1ToEEprom(void);
++void send_0ToEEprom(void);
++//void WriteWait(void);
++void SendAddrToEEprom(short);
++void SendDataToEEprom(short);
++
++#endif
+diff -Nur linux-mips-cvs/drivers/net/port_based_qos/Makefile linux-broadcom/drivers/net/port_based_qos/Makefile
+--- linux-mips-cvs/drivers/net/port_based_qos/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-broadcom/drivers/net/port_based_qos/Makefile 2005-01-31 13:13:14.000000000 +0100
+@@ -0,0 +1,27 @@
++# Copyright 2001, Cybertan Corporation
++# All Rights Reserved.
++#
++# This is UNPUBLISHED PROPRIETARY SOURCE CODE of Cybertan Corporation;
++# the contents of this file may not be disclosed to third parties, copied or
++# duplicated in any form, in whole or in part, without the prior written
++# permission of Cybertan Corporation.
++#
++#
++# $Id$
++#
++
++O_TARGET := port_based_qos_mod.o
++
++PORT_BASED_QOS_MOD_OBJS := port_based_qos.o Atan.o c47xx.o eeprom.o
++
++export-objs :=
++obj-y := $(PORT_BASED_QOS_MOD_OBJS)
++obj-m := $(O_TARGET)
++
++SRCBASE := $(TOPDIR)/../..
++EXTRA_CFLAGS += -I$(SRCBASE)/include -Wall -I$(SRCBASE)/
++
++vpath %.c $(SRCBASE)/shared
++
++include $(TOPDIR)/Rules.make
++
+diff -Nur linux-mips-cvs/drivers/net/port_based_qos/c47xx.c linux-broadcom/drivers/net/port_based_qos/c47xx.c
+--- linux-mips-cvs/drivers/net/port_based_qos/c47xx.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-broadcom/drivers/net/port_based_qos/c47xx.c 2005-01-31 13:13:14.000000000 +0100
+@@ -0,0 +1,85 @@
++#include <typedefs.h>
++#include <sbutils.h>
++#include <bcmdevs.h>
++#include <osl.h>
++#include <bcmnvram.h>
++#include <bcmutils.h>
++
++#include <sbpci.h>
++#include <sbchipc.h>
++#include <sbconfig.h>
++#include <sbextif.h>
++#include <sbmips.h>
++#include "c47xx.h"
++extern uint32 sb_gpioouten(void *sbh, uint32 mask, uint32 val);
++extern uint32 sb_gpioout(void *sbh, uint32 mask, uint32 val);
++extern uint32 sb_gpioin(void *sbh);
++extern uint32 sb_gpiointmask(void *sbh, uint32 mask, uint32 val);
++
++#define OUTENMASK B_RESET|B_ECS|B_ECK|B_EDI
++#define CFGMASK B_ECS|B_ECK|B_EDI
++#define BIT(x) (1 << (x))
++#define ASSERT(exp) do {} while (0)
++
++void
++conf_gpio(int x)
++{
++ ASSERT(sbh);
++
++ /* Enable all of output pins */
++ sb_gpioouten(sbh, OUTENMASK, OUTENMASK);
++
++ /* We don't want the B_RESET pin changed, unless
++ * it tries to set the B_RESET pin.
++ */
++ if (x & B_RESET)
++ sb_gpioout(sbh, OUTENMASK, x);
++ else
++ sb_gpioout(sbh, CFGMASK, x);
++
++}
++
++void
++gpio_line_set(int x, unsigned int value)
++{
++ ASSERT(sbh);
++
++ if (value == 1)
++ sb_gpioout(sbh, BIT(x), BIT(x));
++ else if (value == 0)
++ sb_gpioout(sbh, BIT(x), 0);
++}
++
++void
++gpio_line_get(int x, int *value)
++{
++ ASSERT(sbh);
++
++ *value = (sb_gpioin(sbh) >> x) & 0x1;
++}
++
++void
++gpio_line_config_in(int x)
++{
++ ASSERT(sbh);
++
++ sb_gpioouten(sbh, BIT(x), 0);
++ sb_gpiointmask(sbh, BIT(x), BIT(x));
++}
++
++void
++gpio_line_config_out(int x)
++{
++ ASSERT(sbh);
++
++ sb_gpiointmask(sbh, BIT(x), 0);
++ sb_gpioouten(sbh, BIT(x), BIT(x));
++}
++
++void
++gpio_line_config_out_all(int x)
++{
++ ASSERT(sbh);
++
++ sb_gpioouten(sbh, OUTENMASK, OUTENMASK);
++}
+diff -Nur linux-mips-cvs/drivers/net/port_based_qos/c47xx.h linux-broadcom/drivers/net/port_based_qos/c47xx.h
+--- linux-mips-cvs/drivers/net/port_based_qos/c47xx.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-broadcom/drivers/net/port_based_qos/c47xx.h 2005-01-31 13:13:14.000000000 +0100
+@@ -0,0 +1,23 @@
++#ifndef _C47XX_H_
++#define _C47XX_H_
++
++extern void *bcm947xx_sbh;
++#define sbh bcm947xx_sbh
++
++#define GPIO0 0
++#define GPIO1 1
++#define GPIO2 2
++#define GPIO3 3
++#define GPIO4 4
++#define GPIO5 5
++#define GPIO6 6
++#define GPIO7 7
++#define GPIO8 8
++
++#define B_RESET 1<<GPIO0
++#define B_ECS 1<<GPIO2
++#define B_ECK 1<<GPIO3
++#define B_EDO 1<<GPIO4
++#define B_EDI 1<<GPIO5
++
++#endif
+diff -Nur linux-mips-cvs/drivers/net/port_based_qos/eeprom.c linux-broadcom/drivers/net/port_based_qos/eeprom.c
+--- linux-mips-cvs/drivers/net/port_based_qos/eeprom.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-broadcom/drivers/net/port_based_qos/eeprom.c 2005-01-31 13:13:14.000000000 +0100
+@@ -0,0 +1,355 @@
++#include <linux/delay.h>
++
++#define EEDO_PIN 4
++#define EECS_PIN 2
++#define EECK_PIN 3
++#define EEDI_PIN 5
++#define RESET_PIN 0
++
++static void SetCSToLowForEEprom(void);
++//static void SetCSToHighForEEprom(void);
++static void send1ToEEprom(void);
++static void send0ToEEprom(void);
++static void InitSerialInterface(void);
++static void SerialPulse(void);
++static void WriteDataToRegister(unsigned short RegNumber, unsigned short data);
++void ReadDataFromRegister(unsigned short addr, unsigned short *hidata, unsigned short *lodata,int select_count);
++static void WriteDataToEEprom(unsigned short addr, unsigned short data);
++static void WriteCmdToEEprom(unsigned short cmd);
++extern void gpio_line_set(int x, unsigned int value);
++extern void gpio_line_get(int x, int *value);
++extern void gpio_line_config_out(int x);
++extern void gpio_line_config_in(int x);
++extern void gpio_line_config_out_all(void);
++// ;cs __-- ,bit 3
++// ;sck ____ ,bit 4
++// ;di ____ ,bit 5
++// ;do ____ ,bit 6
++// ;
++
++static void SetEEpromToSendState(void)
++{
++ gpio_line_set(EECS_PIN, 0);
++ gpio_line_set(EECK_PIN, 0);
++ gpio_line_set(EEDI_PIN, 1);
++// gpio_line_set(EEDO_PIN, 1); /* high impedance */
++
++ mdelay(1);
++ gpio_line_set(EECS_PIN, 1);
++// gpio_line_set(EEDO_PIN, 1); /* high impedance */
++}
++
++#if 0
++static void EEpromInit(void)
++{
++ gpio_line_set(EECS_PIN, 0);
++ gpio_line_set(EECK_PIN, 0);
++ gpio_line_set(EEDI_PIN, 1);
++ gpio_line_set(EEDO_PIN, 1); /* high impedance */
++
++ mdelay(1);
++}
++
++// ;cs ____ ,bit 3
++// ;sck ____ ,bit 4
++// ;di ____ ,bit 5
++// ;do ____ ,bit 6
++// ;
++static void ResetEEpromToSendState(void)
++{
++ gpio_line_set(EECS_PIN, 0);
++ gpio_line_set(EEDI_PIN, 0);
++ //gpio_line_set(EEDO_PIN, 0);
++ gpio_line_set(EECK_PIN, 0);
++}
++#endif /* 0 */
++
++// ;cs ____ ,bit 3
++// ;sck _--_ ,bit 4
++// ;di ____ ,bit 5
++// ;do ____ ,bit 6
++// ;
++static void SetCSToLowForEEprom(void)
++{
++ /* minimum tcs is 1us */
++ gpio_line_set(EECS_PIN, 0);
++ gpio_line_set(EECS_PIN, 0);
++
++ gpio_line_set(EECK_PIN, 0);
++ gpio_line_set(EECK_PIN, 1);
++ gpio_line_set(EECK_PIN, 1);
++ gpio_line_set(EECK_PIN, 1);
++ gpio_line_set(EECK_PIN, 1);
++ gpio_line_set(EECK_PIN, 0);
++
++ gpio_line_set(EECS_PIN, 1);
++
++ udelay(10);
++}
++
++#if 0
++// ;cs ---- ,bit 3
++// ;sck _--_ ,bit 4
++// ;di ____ ,bit 5
++// ;do ____ ,bit 6
++// ;
++static void SetCSToHighForEEprom(void)
++{
++ gpio_line_set(EECS_PIN, 1);
++
++ /* min tskh and tskl is 1us */
++ gpio_line_set(EECK_PIN, 1);
++ udelay(2);
++ gpio_line_set(EECK_PIN, 0);
++}
++#endif /* 0 */
++
++// ;cs ---- ,bit 3
++// ;sck _--_ ,bit 4
++// ;di ---- ,bit 5
++// ;do ____ ,bit 6
++// ;
++static void send1ToEEprom(void)
++{
++//printf("send1ToEEprom(1)...");
++ gpio_line_set(EEDI_PIN, 1);
++
++ gpio_line_set(EECK_PIN, 0);
++ udelay(1);
++ gpio_line_set(EECK_PIN, 1);
++ gpio_line_set(EECK_PIN, 1);
++ gpio_line_set(EECK_PIN, 1);
++ udelay(1);
++ gpio_line_set(EECK_PIN, 0);
++}
++
++// ;cs ---- ,bit 3
++// ;sck _--_ ,bit 4
++// ;di ____ ,bit 5
++// ;do ____ ,bit 6
++// ;
++static void send0ToEEprom(void)
++{
++//printf("send0ToEEprom(0)...");
++ gpio_line_set(EEDI_PIN, 0);
++
++ gpio_line_set(EECK_PIN, 0);
++ udelay(1);
++ gpio_line_set(EECK_PIN, 1);
++ gpio_line_set(EECK_PIN, 1);
++ gpio_line_set(EECK_PIN, 1);
++ udelay(1);
++ gpio_line_set(EECK_PIN, 0);
++}
++
++static void WriteDataToEEprom(unsigned short addr, unsigned short data)
++{
++ unsigned short addr_mask, data_mask;
++
++ SetEEpromToSendState();
++ for (addr_mask = 0x400; addr_mask != 0; )
++ {
++ if (addr & addr_mask)
++ send1ToEEprom();
++ else
++ send0ToEEprom();
++ addr_mask = addr_mask >> 1;
++ }
++ for (data_mask = 0x8000; data_mask != 0; )
++ {
++ if (data & data_mask)
++ send1ToEEprom();
++ else
++ send0ToEEprom();
++ data_mask = data_mask >> 1;
++ }
++ SetCSToLowForEEprom();
++}
++
++static void WriteCmdToEEprom(unsigned short cmd)
++{
++ unsigned short cmd_mask;
++
++ SetEEpromToSendState();
++ for (cmd_mask = 0x0400 ;cmd_mask != 0; )
++ {
++ if (cmd & cmd_mask)
++ send1ToEEprom();
++ else
++ send0ToEEprom();
++ cmd_mask = cmd_mask >> 1;
++ }
++ SetCSToLowForEEprom();
++}
++
++/*
++ * Write data to configure registers through EEPROM interface, even we do not have
++ * an external EEPROM connectted, ADM6996 got a virtual AT39C66 inside
++ */
++static void WriteDataToRegister(unsigned short RegNumber, unsigned short data)
++{
++ unsigned short cmd, addr;
++
++ printk("WriteDataToRegister(RegNumber=0x%x, data=0x%x)\n", RegNumber, data);
++
++// the write enable(WEN) instruction must be executed before any device
++// programming can be done
++ cmd = 0x04c0;
++ WriteCmdToEEprom(cmd); //00000001 0011000000B
++
++ addr = 0x0500 | (RegNumber & 0x0ff); //00000001 01dddddddd
++ WriteDataToEEprom(addr, data); //00000001 01dddddd
++
++
++// after all data has been written to EEprom , the write disable(WDS)
++// instruction must be executed
++ cmd = 0x0400;
++ WriteCmdToEEprom(cmd); //00000001 00000000B
++}
++
++static void SerialDelay(int count)
++{
++ udelay(count);
++}
++
++static void InitSerialInterface(void)
++{
++ gpio_line_set(EECK_PIN, 0);
++ gpio_line_set(EEDI_PIN, 0);
++}
++
++static void SerialPulse(void)
++{
++ gpio_line_set(EECK_PIN, 0);
++ gpio_line_set(EECK_PIN, 1);
++ SerialDelay(10);
++ gpio_line_set(EECK_PIN, 1);
++ gpio_line_set(EECK_PIN, 0);
++}
++/*
++ * Since there is no EEPROM is our board, read from EEPROM need to obey the timing alike
++ * MII interface, EECK = MDC, EEDI = MDIO, please refer to section 4.3 of ADM6996 datasheet
++ */
++void ReadDataFromRegister(unsigned short addr, unsigned short *hidata, unsigned short *lodata, int select_count)
++{
++ unsigned short addr_mask, data_mask;
++ int value, i;
++ unsigned char StartBits, Opcode, TAbits;
++
++ gpio_line_config_out_all();
++ mdelay(1);
++ /* initialize serial interface */
++ gpio_line_set(EECS_PIN, 0);
++ InitSerialInterface();
++
++ /* Preamble, 35 bits */
++ gpio_line_set(EECK_PIN, 0);
++ gpio_line_set(EEDI_PIN, 1);
++ for (i = 0; i < 35; i++)
++ {
++ gpio_line_set(EECK_PIN, 1);
++ SerialDelay(10);
++ gpio_line_set(EECK_PIN, 0);
++ SerialDelay(10);
++ }
++
++ /* Start bits, 2-bit(01b) */
++ InitSerialInterface();
++ StartBits = 0x01;
++ for (i = 0; i < 2; i++)
++ {
++ value = (StartBits & 2) ? 1 : 0;
++ gpio_line_set(EEDI_PIN, value);
++ SerialDelay(1);
++ SerialPulse();
++ StartBits <<= 1;
++ }
++
++ /* Opcode, read = 10b */
++ InitSerialInterface();
++ Opcode = 0x02;
++ for (i = 0; i < 2; i++)
++ {
++ value = (Opcode & 0x02) ? 1 : 0;
++ gpio_line_set(EEDI_PIN, value);
++ SerialDelay(1);
++ SerialPulse();
++ Opcode <<= 1;
++ }
++
++ /* 10 bits register address */
++ /* 1-bit Table Select, 2-bit Device Address, 7-bit Register Address */
++ InitSerialInterface();
++ if (select_count)
++ addr = (addr & 0x7f) | 0x200;
++ else
++ addr = addr & 0x7f ;
++ for (addr_mask = 0x200; addr_mask != 0; addr_mask >>= 1)
++ {
++ value = (addr & addr_mask) ? 1 : 0;
++ gpio_line_set(EEDI_PIN, value);
++ SerialDelay(1);
++ SerialPulse();
++ }
++
++ /* TA, turnaround 2-bit */
++ InitSerialInterface();
++ TAbits = 0x02;
++ gpio_line_config_in(EEDI_PIN);
++ for (i = 0; i < 2; i++)
++ {
++ gpio_line_set(EECK_PIN, 1);
++ SerialDelay(4);
++ gpio_line_get(EEDI_PIN, &value);
++ SerialDelay(4);
++ TAbits <<= 1;
++ gpio_line_set(EECK_PIN, 1);
++ }
++
++
++ /* Latch data from serial management EEDI pin */
++ *hidata = 0;
++ gpio_line_set(EECK_PIN, 0);
++ for (data_mask = 0x8000; data_mask != 0; data_mask >>= 1)
++ {
++ SerialDelay(4);
++ gpio_line_set(EECK_PIN, 1);
++ gpio_line_get(EEDI_PIN, &value);
++ if (value)
++ {
++ *hidata |= data_mask;
++ }
++ gpio_line_set(EECK_PIN, 0);
++ SerialDelay(4);
++ }
++ *lodata = 0;
++ gpio_line_set(EECK_PIN, 0);
++ for (data_mask = 0x8000; data_mask != 0; data_mask >>= 1)
++ {
++ SerialDelay(4);
++ gpio_line_set(EECK_PIN, 1);
++ gpio_line_get(EEDI_PIN, &value);
++ if (value)
++ {
++ *lodata |= data_mask;
++ }
++ gpio_line_set(EECK_PIN, 0);
++ SerialDelay(4);
++ }
++
++ SerialDelay(2);
++
++ /* Idle, EECK must send at least one clock at idle time */
++ SerialPulse();
++ gpio_line_set(EECK_PIN, 0);
++ SerialDelay(10);
++ gpio_line_set(EECK_PIN, 1);
++ SerialDelay(10);
++ gpio_line_set(EECK_PIN, 0);
++ SerialPulse();
++
++ gpio_line_config_out(EEDI_PIN);
++ gpio_line_set(EECS_PIN, 1);
++
++ printk("ReadDataFromRegister(addr=0x%x, hidata=0x%x, lodata=0x%x)\n", addr, *hidata, *lodata);
++}
+diff -Nur linux-mips-cvs/drivers/net/port_based_qos/port_based_qos.c linux-broadcom/drivers/net/port_based_qos/port_based_qos.c
+--- linux-mips-cvs/drivers/net/port_based_qos/port_based_qos.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-broadcom/drivers/net/port_based_qos/port_based_qos.c 2005-01-31 13:13:14.000000000 +0100
+@@ -0,0 +1,460 @@
++ /*
++ * Remaining issues:
++ * + stats support
++ * + multicast support
++ * + media sense
++ * + half/full duplex
++ * - random MAC addr.
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/ethtool.h>
++#include <linux/mii.h>
++#include <asm/io.h>
++
++#include <linux/sysctl.h>
++#include <cy_conf.h>
++
++#define MODULE_NAME "port_based_qos_mod"
++#define DEVICE_NAME "qos"
++#define MODULE_VERSION "0.0.1"
++
++extern void ReadDataFromRegister(unsigned short addr, unsigned short *hidata, unsigned short *lodata,int select_count);
++
++#ifdef PERFORMANCE_SUPPORT
++static struct ctl_table_header *qos_sysctl_header;
++static unsigned long qos[28];
++
++static ctl_table mytable[] = {
++ { 2000, "qos",
++ qos, sizeof(qos),
++ 0644, NULL,
++ proc_dointvec },
++ { 0 }
++};
++
++static unsigned short statis_addr_map[7][6] ={
++ {0x04, 0x06, 0x08, 0x0a, 0x0b, 0x0c},
++ {0x16, 0x18, 0x1a, 0x1c, 0x1d, 0x1e},
++ {0x0d, 0x0f, 0x11, 0x13, 0x14, 0x15},
++ {0x1f, 0x21, 0x23, 0x25, 0x26, 0x27},
++ {0x31, 0x33, 0x35, 0x37, 0x38, 0x39},
++ {0x28, 0x2a, 0x2c, 0x2e, 0x2f, 0x30},
++ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01}
++};
++
++unsigned long get_statistic_from_serial(unsigned short port, unsigned short item)
++{
++ unsigned short hidata, lodata;
++
++ ReadDataFromRegister(statis_addr_map[item][port], &hidata, &lodata, 1);
++ return ((hidata << 16) | lodata);
++}
++#endif
++
++#ifdef HW_QOS_SUPPORT
++struct port_qos_t{
++ int addr;
++ int content_mask;
++ int *content_set;
++};
++
++void WriteDataToRegister_(unsigned short reg_idx, unsigned short content_idx);
++extern void write_eeprom(short,short *,int);
++
++#define BANDWIDTH_1_BIT 2
++#define BANDWIDTH_2_BIT 4
++#define BANDWIDTH_3_BIT 6
++#define BANDWIDTH_4_BIT 7
++
++#define PORT_CONFIG_1 0x3
++#define PORT_CONFIG_2 0x5
++#define PORT_CONFIG_3 0x7
++#define PORT_CONFIG_4 0x8
++#define BANDWIDTH_CTL_123 0x31
++#define BANDWIDTH_CTL_4 0x32
++#define BANDWIDTH_CTL_ENABLE 0x33
++#define DISCARD_MODE 0x10
++#define TOS_PRIO_MAP 0xf
++
++#define PRIORITY_MASK 0xfc7f
++#define PRIORITY_DISABLE_MASK 0xfc7e
++#define FLOW_CTL_MASK 0xfffe
++#define RATE_LIMIT_MASK_1 0xff8f
++#define RATE_LIMIT_MASK_2 0xf8ff
++#define RATE_LIMIT_MASK_3 0x8fff
++#define RATE_LIMIT_MASK_4 0xfff8
++#define BANDWIDTH_CTL_MASK 0xff2b
++#define DISCARD_MASK 0x0fff
++
++#define BANDWIDTH_ENABLE_1 1 << BANDWIDTH_1_BIT//04
++#define BANDWIDTH_ENABLE_2 1 << BANDWIDTH_2_BIT//10
++#define BANDWIDTH_ENABLE_3 1 << BANDWIDTH_3_BIT//40
++#define BANDWIDTH_ENABLE_4 1 << BANDWIDTH_4_BIT//80
++#define BANDWIDTH_CTL_MASK_1 0xffff^BANDWIDTH_ENABLE_1//0xfffb
++#define BANDWIDTH_CTL_MASK_2 0xffff^BANDWIDTH_ENABLE_2//0xffef
++#define BANDWIDTH_CTL_MASK_3 0xffff^BANDWIDTH_ENABLE_3//0xffbf
++#define BANDWIDTH_CTL_MASK_4 0xffff^BANDWIDTH_ENABLE_4//0xff7f
++
++/*static int disable_content[] = {0x0};
++//static int enable_content[] = {0xd4, 0x0cff};//bit 7,6,4,2; Q1=11(50%),Q0=00(0%)*/
++//static int sw_content[] = {0x0,0x0c00};//bit 7,6,4,2; Q1=11(50%),Q0=00(0%)
++static int sw_content[] = {0x0,0xc000};//bit 7,6,4,2; Q1=11(50%),Q0=00(0%)
++static int port_priority_content[] = {0x080,0x380};//Q0,Q3
++//static int port_priority_content[] = {0x300,0x0};//Q1,Q0
++static int port_flow_ctl_content[] = {0x0,0x1};
++static int port_rate_limit_content_1[] = {0x0,0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70};
++static int port_rate_limit_content_2[] = {0x0,0x000,0x100,0x200,0x300,0x400,0x500,0x600,0x700};
++static int port_rate_limit_content_3[] = {0x0,0x0000,0x1000,0x2000,0x3000,0x4000,0x5000,0x6000,0x7000};
++static int port_rate_limit_content_4[] = {0x0,0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7};
++static int port_rate_limit_enable_1[] = {0x0, BANDWIDTH_ENABLE_1};
++static int port_rate_limit_enable_2[] = {0x0, BANDWIDTH_ENABLE_2};
++static int port_rate_limit_enable_3[] = {0x0, BANDWIDTH_ENABLE_3};
++static int port_rate_limit_enable_4[] = {0x0, BANDWIDTH_ENABLE_4};
++
++static struct port_qos_t port_mii_disable[] = {
++ { BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK, sw_content},
++ //{ DISCARD_MODE, DISCARD_MASK, sw_content},
++ { PORT_CONFIG_1, PRIORITY_MASK, sw_content},//port_priority_1
++ { PORT_CONFIG_2, PRIORITY_MASK, sw_content},//port_priority_2
++ { PORT_CONFIG_3, PRIORITY_MASK, sw_content},//port_priority_3
++ { PORT_CONFIG_4, PRIORITY_MASK, sw_content},//port_priority_4
++ { PORT_CONFIG_1, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_1
++ { PORT_CONFIG_2, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_2
++ { PORT_CONFIG_3, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_3
++ { PORT_CONFIG_4, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_4
++ { -1}
++};
++
++static struct port_qos_t port_mii_enable[] = {
++ //{ BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK, enable_content},
++ //{ DISCARD_MODE, DISCARD_MASK, sw_content},
++ { -1}
++};
++
++struct port_qos_t *port_mii_sw_array[] = {port_mii_disable, port_mii_enable};
++
++/*static struct port_qos_t port_mii_addr[] = {
++ { PORT_CONFIG_1, PRIORITY_MASK, port_priority_content},//port_priority_1
++ { PORT_CONFIG_1, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_1
++ //{ "port_frame_type_1", 0x3},
++ { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_14, port_rate_limit_content_14},//port_rate_limit_1
++ { PORT_CONFIG_2, PRIORITY_MASK, port_priority_content},//port_priority_2
++ { PORT_CONFIG_2, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_2
++ //{ "port_frame_type_2", 0x5},
++ { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_2, port_rate_limit_content_2},//port_rate_limit_2
++ { PORT_CONFIG_3, PRIORITY_MASK, port_priority_content},//port_priority_3
++ { PORT_CONFIG_3, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_3
++ //{ "port_frame_type_3", 0x7},
++ { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_3, port_rate_limit_content_3},//port_rate_limit_3
++ //{ "port_priority_4", 0x8, 0x380},
++ { PORT_CONFIG_4, PRIORITY_MASK, port_priority_content},//port_priority_4
++ { PORT_CONFIG_4, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_4
++ //{ "port_frame_type_4", 0x8},
++ { BANDWIDTH_CTL_4, RATE_LIMIT_MASK_14, port_rate_limit_content_14},//port_rate_limit_4
++ { -1}
++};*/
++
++static struct port_qos_t priority_1[] = {
++ { PORT_CONFIG_1, PRIORITY_MASK, port_priority_content},//port_priority_1
++ { -1}
++};
++static struct port_qos_t flow_control_1[] = {
++ { PORT_CONFIG_1, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_1
++ { -1}
++};
++static struct port_qos_t rate_limit_1[] = {
++ { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_1, port_rate_limit_content_1},//port_rate_limit_1
++ { BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_1, port_rate_limit_enable_1},//port_rate_limit_4
++ { -1}
++};
++static struct port_qos_t priority_2[] = {
++ { PORT_CONFIG_2, PRIORITY_MASK, port_priority_content},//port_priority_2
++ { -1}
++};
++static struct port_qos_t flow_control_2[] = {
++ { PORT_CONFIG_2, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_2
++ { -1}
++};
++static struct port_qos_t rate_limit_2[] = {
++ { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_2, port_rate_limit_content_2},//port_rate_limit_2
++ { BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_2, port_rate_limit_enable_2},//port_rate_limit_4
++ { -1}
++};
++static struct port_qos_t priority_3[] = {
++ { PORT_CONFIG_3, PRIORITY_MASK, port_priority_content},//port_priority_3
++ { -1}
++};
++static struct port_qos_t flow_control_3[] = {
++ { PORT_CONFIG_3, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_3
++ { -1}
++};
++static struct port_qos_t rate_limit_3[] = {
++ { BANDWIDTH_CTL_123, RATE_LIMIT_MASK_3, port_rate_limit_content_3},//port_rate_limit_3
++ { BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_3, port_rate_limit_enable_3},//port_rate_limit_4
++ { -1}
++};
++static struct port_qos_t priority_4[] = {
++ { PORT_CONFIG_4, PRIORITY_MASK, port_priority_content},//port_priority_4
++ { -1}
++};
++static struct port_qos_t flow_control_4[] = {
++ { PORT_CONFIG_4, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_4
++ { -1}
++};
++static struct port_qos_t rate_limit_4[] = {
++ { BANDWIDTH_CTL_4, RATE_LIMIT_MASK_4, port_rate_limit_content_4},//port_rate_limit_4
++ { BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_4, port_rate_limit_enable_4},//port_rate_limit_4
++ { -1}
++};
++
++static struct port_qos_t *port_mii_addr[] = {
++ priority_1,
++ flow_control_1,
++ rate_limit_1,
++ priority_2,
++ flow_control_2,
++ rate_limit_2,
++ priority_3,
++ flow_control_3,
++ rate_limit_3,
++ priority_4,
++ flow_control_4,
++ rate_limit_4,
++ NULL
++};
++
++void WriteDataToRegister_(unsigned short reg_idx, unsigned short content_idx)
++{
++ short RegNumber;
++ unsigned short data, hidata=0x0, lodata=0x0;
++ int i;
++ struct port_qos_t *port_qos = port_mii_addr[reg_idx];
++
++ //printk("\nWriteDataToRegister_:reg_idx=%d content_idx=%d\n", reg_idx, content_idx);
++ if (!port_qos)
++ port_qos = port_mii_sw_array[content_idx];
++
++ for (i=0; port_qos[i].addr != -1; i++)
++ {
++ RegNumber = port_qos[i].addr;
++ ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
++
++ if (!(RegNumber % 2)) /* even port number use lower word */
++ hidata = lodata;
++
++ data = (hidata & port_qos[i].content_mask) | (((i > 0) && (content_idx > 1))? port_qos[i].content_set[1] : port_qos[i].content_set[content_idx]);
++
++ write_eeprom(RegNumber, &data, 1);
++ ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
++ }
++ ReadDataFromRegister(0xf, &hidata, &lodata, 0);
++
++ /*RegNumber = port_mii_addr[reg_idx].addr;
++ if (RegNumber == -1)//Disable or Enable
++ {
++ struct port_qos_t *port_mii_sw = port_mii_sw_array[content_idx];
++
++ printk("\nWriteDataToRegister_:reg_idx=%d content_idx=%d\n", reg_idx, content_idx);
++ for (i=0; port_mii_sw[i].addr != -1; i++)
++ {
++ RegNumber = port_mii_sw[i].addr;
++
++ ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
++
++ if (!(RegNumber % 2))
++ hidata = lodata;
++
++ data = (hidata & port_mii_sw[i].content_mask) | port_mii_sw[i].content_set[i];
++
++ write_eeprom(RegNumber, &data, 1);
++
++ ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
++ printk("\n============== %s===============\n", (content_idx==0)?"disable":"enable");
++ }
++ }
++ else
++ {
++ ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
++
++ if (!(RegNumber % 2))
++ hidata = lodata;
++
++ data = (hidata & port_mii_addr[reg_idx].content_mask) | port_mii_addr[reg_idx].content_set[content_idx];
++
++ write_eeprom(RegNumber, &data, 1);
++ ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
++ }*/
++}
++#endif
++
++static int dev_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
++{
++ struct mii_ioctl_data *data = (struct mii_ioctl_data *)req->ifr_data;
++#ifdef PERFORMANCE_SUPPORT
++ int item, port;
++
++ unsigned long status_item;
++#endif
++
++ switch (cmd)
++ {
++ case SIOCGMIIPHY: /* Get address of MII PHY in use. */
++ case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
++
++ /* Fall through to the SIOCGMIIREG, taken from eepro100 and rtl
++ * drivers */
++#ifdef PERFORMANCE_SUPPORT
++ case SIOCGMIIREG: /* Read MII PHY register. */
++ for (item=0; item<6; item++)
++ for (port=1; port<5; port++){
++ qos[(item * 4) + (port-1)] = get_statistic_from_serial(port, item);
++ }
++
++ status_item = get_statistic_from_serial(0, 6);
++
++ qos[24] = (0x1 & (status_item >> 8));
++ qos[25] = (0x1 & (status_item >> 16));
++ qos[26] = (0x1 & (status_item >> 24));
++ qos[27] = (0x1 & (status_item >> 28));
++
++ return 0;
++#endif
++
++ case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
++#ifdef HW_QOS_SUPPORT
++ case SIOCSMIIREG: /* Write MII PHY register. */
++ {
++ printk("\n x phy_id=%x\n", data->phy_id);
++ printk("\n x reg_num=%x\n", data->reg_num);
++ printk("\n x val_in=%x\n", data->val_in);
++ printk("\n x val_out=%x\n", data->val_out);
++
++ WriteDataToRegister_(data->phy_id, data->val_in);
++ return 0;
++ }
++#endif
++ case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
++ default:
++ return -EOPNOTSUPP;
++ }
++}
++
++static int __devinit qos_eth_probe(struct net_device *dev)
++{
++
++ SET_MODULE_OWNER(dev);
++
++ ether_setup(dev);
++
++ strcpy(dev->name, DEVICE_NAME "0");
++
++ dev->do_ioctl = dev_do_ioctl;
++
++ return 0;
++}
++
++#ifdef HW_QOS_SUPPORT
++static char *port_option_name[] = {
++ "port_priority_1",
++ "port_flow_control_1",
++ //{ "port_frame_type_1",
++ "port_rate_limit_1",
++ "port_priority_2",
++ "port_flow_control_2",
++ //{ "port_frame_type_2",
++ "port_rate_limit_2",
++ "port_priority_3",
++ "port_flow_control_3",
++ //{ "port_frame_type_3",
++ "port_rate_limit_3",
++ "port_priority_4",
++ //{ "port_priority_4", PORT_CONFIG_4, PRIORITY_MASK, port_priority_content},
++ "port_flow_control_4",
++ //{ "port_frame_type_4",
++ "port_rate_limit_4",
++ "QoS",
++ NULL
++};
++
++extern char *nvram_get(const char *name);
++extern uint bcm_atoi(char *s);
++
++static int set_port_option(struct net_device *dev, unsigned short port_addr, char *option_content)
++{
++ struct ifreq ifr;
++ struct mii_ioctl_data stats;
++
++ stats.phy_id=port_addr;
++ stats.val_in=bcm_atoi(option_content);
++
++ ifr.ifr_data = (void *)&stats;
++
++ return dev_do_ioctl(dev, &ifr, SIOCSMIIREG);
++}
++
++
++void
++restore_default_from_NV(struct net_device *dev)
++{
++ unsigned short i;
++ char *value = NULL;
++
++ for (i = 0; port_option_name[i]; i++)
++ {
++ if((value = nvram_get(port_option_name[i])))
++ set_port_option(dev, i, value);
++ }
++ return;
++}
++#endif
++
++static struct net_device qos_devices;
++
++/* Module initialization and cleanup */
++int init_module(void)
++{
++ int res;
++ struct net_device *dev;
++
++ printk("Initializing " MODULE_NAME " driver " MODULE_VERSION "\n");
++
++ dev = &qos_devices;
++
++ dev->init = qos_eth_probe;
++
++ if ((res = register_netdev(dev)))
++ printk("Failed to register netdev. res = %d\n", res);
++
++#ifdef PERFORMANCE_SUPPORT
++ qos_sysctl_header = register_sysctl_table(mytable, 0);
++#endif
++#ifdef HW_QOS_SUPPORT
++ restore_default_from_NV(dev);
++ write_eeprom(TOS_PRIO_MAP, &sw_content[0], 1);/* disable TOS priority map*/
++#endif
++ return 0;
++}
++
++void cleanup_module(void)
++{
++ struct net_device *dev = &qos_devices;
++ if (dev->priv != NULL)
++ {
++ unregister_netdev(dev);
++ kfree(dev->priv);
++ dev->priv = NULL;
++ }
++
++#ifdef PERFORMANCE_SUPPORT
++ unregister_sysctl_table(qos_sysctl_header);
++#endif
++}
++