mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-12-01 03:24:58 +02:00
1174 lines
32 KiB
Plaintext
1174 lines
32 KiB
Plaintext
|
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
|
||
|
+}
|
||
|
+
|