From 9ca5fbcb63a8dcaee0527f96afb91dc4b4bd8fa9 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 22 Nov 2023 01:08:11 +0000
Subject: [PATCH] add ip1811 driver
---
kernel/drivers/net/ethernet/ip1811/ip1811reg.h | 231
kernel/drivers/net/ethernet/ip1811/ip1811ds.h | 746 +
kernel/drivers/net/ethernet/ip1811/ip218.h | 29
kernel/drivers/net/ethernet/ip1811/ip1811op.h | 427 +
kernel/drivers/net/ethernet/ip1811/list.h | 517 +
kernel/drivers/net/ethernet/ip1811/port_config.h | 16
kernel/drivers/net/ethernet/ip1811/zconf.h | 506 +
kernel/drivers/net/ethernet/ip1811/include/types.h | 17
kernel/drivers/net/ethernet/ip1811/libcommon.h | 53
kernel/drivers/net/ethernet/ip1811/Makefile | 4
kernel/drivers/net/ethernet/ip1811/include/port_config.h | 16
kernel/drivers/net/ethernet/ip1811/system_config.h | 36
kernel/drivers/net/ethernet/Makefile | 1
kernel/drivers/net/ethernet/ip1811/types.h | 17
kernel/drivers/net/ethernet/ip1811/driver_load | 29
kernel/drivers/net/ethernet/ip1811/include/list.h | 517 +
kernel/drivers/net/ethernet/ip1811/ip1811.h | 1323 +++
kernel/drivers/net/ethernet/ip1811/include/zconf.h | 506 +
kernel/drivers/net/ethernet/ip1811/include/zlib.h | 1744 ++++
kernel/drivers/net/ethernet/ip1811/include/Makefile | 7
kernel/drivers/net/ethernet/ip1811/include/system_config.h | 36
kernel/drivers/net/ethernet/ip1811/Makefile_ | 50
kernel/drivers/net/ethernet/ip1811/ip1811.c | 482 +
kernel/drivers/net/ethernet/ip1811/ip1811fdat.c | 466 +
kernel/drivers/net/ethernet/ip1811/include/libcommon.h | 53
kernel/drivers/net/ethernet/ip1811/zlib.h | 1744 ++++
kernel/drivers/net/ethernet/ip1811/ip1811fdat.h | 550 +
kernel/drivers/net/ethernet/ip1811/ip1811func.c | 13309 ++++++++++++++++++++++++++++++++++
28 files changed, 23,432 insertions(+), 0 deletions(-)
diff --git a/kernel/drivers/net/ethernet/Makefile b/kernel/drivers/net/ethernet/Makefile
index b45d5f6..0ae0282 100644
--- a/kernel/drivers/net/ethernet/Makefile
+++ b/kernel/drivers/net/ethernet/Makefile
@@ -95,3 +95,4 @@
obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/
obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/
obj-$(CONFIG_NET_VENDOR_SYNOPSYS) += synopsys/
+obj-y += ip1811/
diff --git a/kernel/drivers/net/ethernet/ip1811/Makefile b/kernel/drivers/net/ethernet/ip1811/Makefile
new file mode 100644
index 0000000..c5f76e2
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/Makefile
@@ -0,0 +1,4 @@
+DRIVER_NAME = ip1811drv
+obj-m := $(DRIVER_NAME).o
+$(DRIVER_NAME)-objs := ip1811.o ip1811fdat.o ip1811func.o
+
diff --git a/kernel/drivers/net/ethernet/ip1811/Makefile_ b/kernel/drivers/net/ethernet/ip1811/Makefile_
new file mode 100644
index 0000000..e7bd479
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/Makefile_
@@ -0,0 +1,50 @@
+# Comment/uncomment the following line to disable/enable debugging
+#DEBFLAGS = -g # "-O" is needed to expand inlines
+EXTRA_CFLAGS += $(DEBFLAGS)
+
+# assign extra include path
+INCLUDEPATH ?= -I$(PWD)/../include
+EXTRA_CFLAGS += $(INCLUDEPATH)
+
+# Use MDC/MDIO to access external switch register.
+EXTRA_CFLAGS += -DACCESS_REG_BY_MDIO
+
+DRIVER_NAME = ip1811drv
+
+WORK_FN_FILE_SIZE =$(shell (ls -l $(1) | awk '{print $$5}'))
+PWD := $(shell pwd)
+EXE = $(DRIVER_NAME).ko
+
+KERNELDIR ?= /home/zdb/rk3568/rk356_linux4.19/kernel
+#KERNELDIR ?= ../../build/linux
+
+#CROSS_COMPILE :=mips-linux-
+CROSS_COMPILE := aarch64-linux-gnu-
+
+
+obj-m := $(DRIVER_NAME).o
+$(DRIVER_NAME)-objs := ip1811.o ip1811fdat.o ip1811func.o
+
+.PHONY: all
+all:
+ @echo "EXTRA_CFLGAS=[$(EXTRA_CFLAGS)]"
+ @echo " Making $@ ..."
+ $(MAKE) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNELDIR) M=$(PWD) modules
+ @make show_size
+ cp *.h $(INC)
+
+
+.PHONY: show_size
+show_size:
+ @echo "Info: generate AP $@ with size = $(call WORK_FN_FILE_SIZE,$(EXE))"
+
+.PHONY: clean
+clean:
+ rm -rf *.o .*.d *~ core .depend .*.cmd *.ko* *.mod.c .tmp_versions modules.order Module.symvers
+
+depend .depend dep:
+ $(CC) $(CFLAGS) -M *.c > .depend
+
+ifeq (.depend,$(wildcard .depend))
+ include .depend
+endif
diff --git a/kernel/drivers/net/ethernet/ip1811/driver_load b/kernel/drivers/net/ethernet/ip1811/driver_load
new file mode 100644
index 0000000..b611408
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/driver_load
@@ -0,0 +1,29 @@
+#!/bin/sh
+module="ip1811"
+mname="ip1811drv"
+device="ip1811_cdev"
+mode="664"
+
+# Group: since distributions do it differently, look for wheel or use staff
+if grep '^staff:' /etc/group > /dev/null; then
+ group="staff"
+else
+ group="wheel"
+fi
+
+# invoke insmod with all arguments we got
+# and use a pathname, as newer modutils don't look in . by default
+#/sbin/insmod -f ./$module.ko $* || exit 1
+insmod $mname.ko
+
+major=`cat /proc/devices | awk "\\$2==\"$device\" {print \\$1}"`
+
+# Remove stale nodes and replace them, then give gid and perms
+# Usually the script is shorter, it's simple that has several devices in it.
+
+#rm -f /dev/${device}[rn]
+mknod /dev/${module} c $major 0
+#mknod /dev/${device}r c $major 0
+#mknod /dev/${device}n c $major 1
+#chgrp $group /dev/${device}[rn]
+#chmod $mode /dev/${device}[rn]
diff --git a/kernel/drivers/net/ethernet/ip1811/include/Makefile b/kernel/drivers/net/ethernet/ip1811/include/Makefile
new file mode 100644
index 0000000..b441bc8
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/include/Makefile
@@ -0,0 +1,7 @@
+
+INCLUDEPATH = $(shell cd ../../linux/include; pwd)
+
+.PHONY: all
+all:
+ @echo "Copying include/*.h ..."
+ cp *.h $(INCLUDEPATH)
diff --git a/kernel/drivers/net/ethernet/ip1811/include/libcommon.h b/kernel/drivers/net/ethernet/ip1811/include/libcommon.h
new file mode 100644
index 0000000..3aaa686
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/include/libcommon.h
@@ -0,0 +1,53 @@
+#ifndef __LIB_COMMON_H__
+#define __LIB_COMMON_H__
+#include <sys/types.h>//for u_int8_t
+
+#undef OK
+#define OK 0
+
+#undef ERROR
+#define ERROR -1
+
+#undef FALSE
+#define FALSE 0
+
+#undef TRUE
+#define TRUE 1
+
+#undef DISABLE
+#define DISABLE 0
+
+#undef ENABLE
+#define ENABLE 1
+
+#define FREE_SAFE(a) if(a!=NULL){free(a);a=NULL;}
+
+#define SV_WDT_WDT_TIME (100)//Unit depends on WORKQUEUE_DELAY_TIME defined in supervisor.c
+
+/************************************************************
+ * Name: getSysUptime
+ * Description: get system uptime from proc file
+ * Parameters: None
+ * Return value:failed: -1
+ * success: float type uptime
+ * **********************************************************/
+float getSysUptime(void);
+long getSysUptime_10ms(void);
+void daemonize(void);
+int lock_file(char *filename);
+int unlock_file(int fd, char *filename);
+
+void get_switch_mac(u_int8_t* macaddr);
+void get_switch_ip(u_int8_t *ip);
+void get_switch_netmask(u_int8_t *mask);
+void get_gateway_ip(u_int8_t *ip);
+void get_gateway_ipv6(u_int8_t *ipv6);
+void DER_OID_decoder(unsigned char *input_OID, unsigned int OIDLen, char *outputString);
+char popen_d(char *cmd, char *ret, unsigned int ret_len);
+void printfd(char *file, char *buf);
+char ipStr2Array(char *ip, char *buf);
+int do_fork_execvp(char *argv[]);
+int supervisor_wdt_add(char *command, const char *func_name, int wdt_life_time);
+int supervisor_wdt_del(char *command);
+int supervisor_wdt_reset(char *command);
+#endif//__LIB_COMMON_H__
diff --git a/kernel/drivers/net/ethernet/ip1811/include/list.h b/kernel/drivers/net/ethernet/ip1811/include/list.h
new file mode 100644
index 0000000..0bbafbf
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/include/list.h
@@ -0,0 +1,517 @@
+/**
+ *
+ * I grub it from linux kernel source code and fix it for user space
+ * program. Of course, this is a GPL licensed header file.
+ *
+ * Here is a recipe to cook list.h for user space program
+ *
+ * 1. copy list.h from linux/include/list.h
+ * 2. remove
+ * - #ifdef __KERNE__ and its #endif
+ * - all #include line
+ * - prefetch() and rcu related functions
+ * 3. add macro offsetof() and container_of
+ *
+ * - kazutomo@mcs.anl.gov
+ */
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+#include <stddef.h>
+/**
+ * @name from other kernel headers
+ */
+/*@{*/
+
+/**
+ * Get offset of a member
+ */
+//#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+/**
+ * Casts a member of a structure out to the containing structure
+ * @param ptr the pointer to the member.
+ * @param type the type of the container struct this is embedded in.
+ * @param member the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+/*@}*/
+
+
+/*
+ * These are non-NULL pointers that will result in page faults
+ * under normal circumstances, used to verify that nobody uses
+ * non-initialized list entries.
+ */
+#define LIST_POISON1 ((void *) 0x00100100)
+#define LIST_POISON2 ((void *) 0x00200200)
+
+/**
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+#define INIT_LIST_HEAD(ptr) do { \
+ (ptr)->next = (ptr); (ptr)->prev = (ptr); \
+} while (0)
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head->prev, head);
+}
+
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = LIST_POISON1;
+ entry->prev = LIST_POISON2;
+}
+
+
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+ return head->next == head;
+}
+
+static inline void __list_splice(struct list_head *list,
+ struct list_head *head)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+ struct list_head *at = head->next;
+
+ first->prev = head;
+ head->next = first;
+
+ last->next = at;
+ at->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ */
+
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); \
+ pos = pos->next)
+
+/**
+ * __list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
+ pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop counter.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use as a start point in
+ * list_for_each_entry_continue
+ * @pos: the type * to use as a start point
+ * @head: the head of the list
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_prepare_entry(pos, head, member) \
+ ((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - iterate over list of given type
+ * continuing after existing point
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_continue(pos, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue - iterate over list of given type
+ * continuing after existing point safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against
+ * removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member), \
+ n = list_entry(pos->member.prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+
+
+
+/*
+ * Double linked lists with a single pointer list head.
+ * Mostly useful for hash tables where the two pointer list head is
+ * too wasteful.
+ * You lose the ability to access the tail in O(1).
+ */
+
+struct hlist_head {
+ struct hlist_node *first;
+};
+
+struct hlist_node {
+ struct hlist_node *next, **pprev;
+};
+
+#define HLIST_HEAD_INIT { .first = NULL }
+#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
+#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
+#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
+
+static inline int hlist_unhashed(const struct hlist_node *h)
+{
+ return !h->pprev;
+}
+
+static inline int hlist_empty(const struct hlist_head *h)
+{
+ return !h->first;
+}
+
+static inline void __hlist_del(struct hlist_node *n)
+{
+ struct hlist_node *next = n->next;
+ struct hlist_node **pprev = n->pprev;
+ *pprev = next;
+ if (next)
+ next->pprev = pprev;
+}
+
+static inline void hlist_del(struct hlist_node *n)
+{
+ __hlist_del(n);
+ n->next = LIST_POISON1;
+ n->pprev = LIST_POISON2;
+}
+
+
+static inline void hlist_del_init(struct hlist_node *n)
+{
+ if (n->pprev) {
+ __hlist_del(n);
+ INIT_HLIST_NODE(n);
+ }
+}
+
+static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
+{
+ struct hlist_node *first = h->first;
+ n->next = first;
+ if (first)
+ first->pprev = &n->next;
+ h->first = n;
+ n->pprev = &h->first;
+}
+
+
+
+/* next must be != NULL */
+static inline void hlist_add_before(struct hlist_node *n,
+ struct hlist_node *next)
+{
+ n->pprev = next->pprev;
+ n->next = next;
+ next->pprev = &n->next;
+ *(n->pprev) = n;
+}
+
+static inline void hlist_add_after(struct hlist_node *n,
+ struct hlist_node *next)
+{
+ next->next = n->next;
+ n->next = next;
+ next->pprev = &n->next;
+
+ if(next->next)
+ next->next->pprev = &next->next;
+}
+
+
+
+#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
+
+#define hlist_for_each(pos, head) \
+ for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
+ pos = pos->next)
+
+#define hlist_for_each_safe(pos, n, head) \
+ for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
+ pos = n)
+
+/**
+ * hlist_for_each_entry - iterate over list of given type
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry(tpos, pos, head, member) \
+ for (pos = (head)->first; \
+ pos && ({ prefetch(pos->next); 1;}) && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = pos->next)
+
+/**
+ * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_continue(tpos, pos, member) \
+ for (pos = (pos)->next; \
+ pos && ({ prefetch(pos->next); 1;}) && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = pos->next)
+
+/**
+ * hlist_for_each_entry_from - iterate over a hlist continuing from existing point
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_from(tpos, pos, member) \
+ for (; pos && ({ prefetch(pos->next); 1;}) && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = pos->next)
+
+/**
+ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @n: another &struct hlist_node to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
+ for (pos = (head)->first; \
+ pos && ({ n = pos->next; 1; }) && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = n)
+
+
+#endif
diff --git a/kernel/drivers/net/ethernet/ip1811/include/port_config.h b/kernel/drivers/net/ethernet/ip1811/include/port_config.h
new file mode 100644
index 0000000..96e556e
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/include/port_config.h
@@ -0,0 +1,16 @@
+#ifndef __PORT_CONFIG_H__
+#define __PORT_CONFIG_H__
+#include "portnumber.h"
+
+#define MAX_PORT_NUM get_MaxPort()
+#define GIGA_PORT_START get_GPStart()
+#define GIGA_PORT_END get_GPEnd()
+
+#define MAX_IPORT_CNT SWITCH_MAX_IPORT_CNT
+#define ALL_PORTS_LIST (~(-1 << MAX_PORT_NUM))
+#define GIGA_PORT_NUM (GIGA_PORT_END - GIGA_PORT_START)
+#define CPU_PORT_NUM MAX_IPORT_CNT
+#define MAX_TP_PORT_NUM (GIGA_PORT_START -1)
+
+#endif
+
diff --git a/kernel/drivers/net/ethernet/ip1811/include/system_config.h b/kernel/drivers/net/ethernet/ip1811/include/system_config.h
new file mode 100644
index 0000000..b80d6f5
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/include/system_config.h
@@ -0,0 +1,36 @@
+
+#ifndef __SYSTEM_CONFIG_H__
+#define __SYSTEM_CONFIG_H__
+///////////////////////////////////////////////
+//// board config
+///////////////////////////////////////////////
+
+//#define SYSTEM_CONFIG__FPGA
+//#define SYSTEM_CONFIG__ASIC//this is ASIC_135
+//#define SYSTEM_CONFIG__ASIC125
+//#define SYSTEM_CONFIG__ASIC_135
+#define SYSTEM_CONFIG__ASIC_150
+
+
+#define SYSTEM_CONFIG__SERVER_MODE
+//#define SYSTEM_CONFIG__PCI_MODE
+
+
+///////////////////////////////////////////////
+//// DRAM parameter - ref: sdram_support_list
+///////////////////////////////////////////////
+
+#define SYSTEM_CONFIG_DRAM__ARCH_4CH
+//#define SYSTEM_CONFIG_DRAM__USED_2CHIPS
+//#define SYSTEM_CONFIG_FLASH__USED_2CHIPS
+
+//#define SYSTEM_CONFIG_DRAM__NT5SV16M16CS_6K
+//#define SYSTEM_CONFIG_DRAM__PMS308416BTR_6
+//#define SYSTEM_CONFIG_DRAM__IS42S16320D
+#define SYSTEM_CONFIG_DRAM__W9825G6KH_6I
+//#define SYSTEM_CONFIG_DRAM__A3V56S30
+
+//#define SYS_CONFIG_WITH_IP102_PHY
+
+#endif
+
diff --git a/kernel/drivers/net/ethernet/ip1811/include/types.h b/kernel/drivers/net/ethernet/ip1811/include/types.h
new file mode 100644
index 0000000..bfcfab4
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/include/types.h
@@ -0,0 +1,17 @@
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+typedef char s8;
+typedef short s16;
+typedef int s32;
+typedef long long s64;
+
+#define BIT(x) (1UL<<(x))
+
+#define err (-1)
+
+#endif
diff --git a/kernel/drivers/net/ethernet/ip1811/include/zconf.h b/kernel/drivers/net/ethernet/ip1811/include/zconf.h
new file mode 100644
index 0000000..8912fe6
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/include/zconf.h
@@ -0,0 +1,506 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2012 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateResetKeep z_inflateResetKeep
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+/* ./configure may #define Z_U4 here */
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# else
+# if (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# else
+# if (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+# endif
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#if 1 /* was set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#if 1 /* was set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#ifdef _WIN32
+# include <stddef.h> /* for wchar_t */
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/kernel/drivers/net/ethernet/ip1811/include/zlib.h b/kernel/drivers/net/ethernet/ip1811/include/zlib.h
new file mode 100644
index 0000000..3edf3ac
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/include/zlib.h
@@ -0,0 +1,1744 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.7, May 2nd, 2012
+
+ Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.7"
+#define ZLIB_VERNUM 0x1270
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 7
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed data.
+ This version of the library supports only one compression method (deflation)
+ but other algorithms will be added later and will have the same stream
+ interface.
+
+ Compression can be done in a single step if the buffers are large enough,
+ or can be done by repeated calls of the compression function. In the latter
+ case, the application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never crash
+ even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ z_const Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total number of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total number of bytes output so far */
+
+ z_const char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has dropped
+ to zero. It must update next_out and avail_out when avail_out has dropped
+ to zero. The application must initialize zalloc, zfree and opaque before
+ calling the init function. All other fields are set by the compression
+ library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this if
+ the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
+ returned by zalloc for objects of exactly 65536 bytes *must* have their
+ offset normalized to zero. The default allocation function provided by this
+ library ensures this (see zutil.c). To reduce memory requirements and avoid
+ any allocation of 64K objects, at the expense of compression ratio, compile
+ the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or progress
+ reports. After compression, total_in holds the total size of the
+ uncompressed data and may be saved for use in the decompressor (particularly
+ if the decompressor wants to decompress everything in a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+#define Z_TREES 6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is not
+ compatible with the zlib.h header file used by the application. This check
+ is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller. If
+ zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+ allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at all
+ (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
+ requests a default compromise between speed and compression (currently
+ equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if level is not a valid compression level, or
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION). msg is set to null
+ if there is no error message. deflateInit does not perform any compression:
+ this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications). Some
+ output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating avail_in or avail_out accordingly; avail_out should
+ never be zero before the call. The application can consume the compressed
+ output when it wants, for example when the output buffer is full (avail_out
+ == 0), or after each call of deflate(). If deflate returns Z_OK and with
+ zero avail_out, it must be called again after making room in the output
+ buffer because there might be more output pending.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumulate before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In
+ particular avail_in is zero after the call if enough output space has been
+ provided before the call.) Flushing may degrade compression for some
+ compression algorithms and so it should be used only when necessary. This
+ completes the current deflate block and follows it with an empty stored block
+ that is three bits plus filler bits to the next byte, followed by four bytes
+ (00 00 ff ff).
+
+ If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+ output buffer, but the output is not aligned to a byte boundary. All of the
+ input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+ This completes the current deflate block and follows it with an empty fixed
+ codes block that is 10 bits long. This assures that enough bytes are output
+ in order for the decompressor to finish the block before the empty fixed code
+ block.
+
+ If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+ for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+ seven bits of the current block are held to be written as the next byte after
+ the next deflate block is completed. In this case, the decompressor may not
+ be provided enough bits at this point in order to complete decompression of
+ the data provided so far to the compressor. It may need to wait for the next
+ block to be emitted. This is for advanced applications that need to control
+ the emission of deflate blocks.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there was
+ enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the stream
+ are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least the
+ value returned by deflateBound (see below). Then deflate is guaranteed to
+ return Z_STREAM_END. If not enough output space is provided, deflate will
+ not return Z_STREAM_END, and it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect the
+ compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case, msg
+ may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the
+ exact value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit() does not process any header information -- that is deferred
+ until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing will
+ resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there is
+ no more input data or no more space in the output buffer (see below about
+ the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating the next_* and avail_* values accordingly. The
+ application can consume the uncompressed output when it wants, for example
+ when the output buffer is full (avail_out == 0), or after each call of
+ inflate(). If inflate returns Z_OK and with zero avail_out, it must be
+ called again after making room in the output buffer because there might be
+ more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+ Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate()
+ stop if and when it gets to the next deflate block boundary. When decoding
+ the zlib or gzip format, this will cause inflate() to return immediately
+ after the header and before the first block. When doing a raw inflate,
+ inflate() will go ahead and process the first block, and will return when it
+ gets to the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64 if
+ inflate() is currently decoding the last block in the deflate stream, plus
+ 128 if inflate() returned immediately after decoding an end-of-block code or
+ decoding the complete header up to just before the first byte of the deflate
+ stream. The end-of-block will not be indicated until all of the uncompressed
+ data from that block has been written to strm->next_out. The number of
+ unused bits may in general be greater than seven, except when bit 7 of
+ data_type is set, in which case the number of unused bits will be less than
+ eight. data_type is set as noted here every time inflate() returns for all
+ flush options, and so can be used to determine the amount of currently
+ consumed input in bits.
+
+ The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+ end of each deflate block header is reached, before any actual data in that
+ block is decoded. This allows the caller to determine the length of the
+ deflate block header for later use in random access within a deflate block.
+ 256 is added to the value of strm->data_type when inflate() returns
+ immediately after reaching the end of the deflate block header.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step (a
+ single call of inflate), the parameter flush should be set to Z_FINISH. In
+ this case all pending input is processed and all pending output is flushed;
+ avail_out must be large enough to hold all of the uncompressed data for the
+ operation to complete. (The size of the uncompressed data may have been
+ saved by the compressor for this purpose.) The use of Z_FINISH is not
+ required to perform an inflation in one step. However it may be used to
+ inform inflate that a faster approach can be used for the single inflate()
+ call. Z_FINISH also informs inflate to not maintain a sliding window if the
+ stream completes, which reduces inflate's memory footprint. If the stream
+ does not complete, either because not all of the stream is provided or not
+ enough output space is provided, then a sliding window will be allocated and
+ inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+ been used.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the effects of the flush parameter in this implementation are
+ on the return value of inflate() as noted below, when inflate() returns early
+ when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+ memory for a sliding window when Z_FINISH is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the Adler-32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically, if requested when
+ initializing with inflateInit2(). Any information contained in the gzip
+ header is not retained, so applications that need that information should
+ instead use raw inflate, see inflateInit2() below, or inflateBack() and
+ perform their own processing of the gzip header and trailer. When processing
+ gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+ producted so far. The CRC-32 is checked against the gzip trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may
+ then call inflateSync() to look for a good compression block if a partial
+ recovery of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by the
+ caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero), no
+ header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but is
+ slow and reduces compression ratio; memLevel=9 uses maximum memory for
+ optimal speed. The default value is 8. See zconf.h for total memory usage
+ as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
+ fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
+ strategy parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set appropriately.
+ Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+ decoder for special applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+ method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+ incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
+ set to null if there is no error message. deflateInit2 does not perform any
+ compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. When using the zlib format, this
+ function must be called immediately after deflateInit, deflateInit2 or
+ deflateReset, and before any call of deflate. When doing raw deflate, this
+ function must be called either before any call of deflate, or immediately
+ after the completion of a deflate block, i.e. after all input has been
+ consumed and all output has been delivered when using any of the flush
+ options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
+ compressor and decompressor must use exactly the same dictionary (see
+ inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size
+ provided in deflateInit or deflateInit2. Thus the strings most likely to be
+ useful should be put at the end of the dictionary, not at the front. In
+ addition, the current implementation of deflate will use at most the window
+ size minus 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if not at a block boundary for raw deflate). deflateSetDictionary does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and can
+ consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state. The
+ stream will keep the same compression level and any other attributes that
+ may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different strategy.
+ If the compression level is changed, the input available so far is
+ compressed with the old level (and may be flushed); the new level will take
+ effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to be
+ compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+ strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit() or
+ deflateInit2(), and after deflateSetHeader(), if used. This would be used
+ to allocate an output buffer for deflation in a single pass, and so would be
+ called before deflate(). If that first deflate() call is provided the
+ sourceLen input bytes, an output buffer allocated to the size returned by
+ deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+ to return Z_STREAM_END. Note that it is possible for the compressed size to
+ be larger than the value returned by deflateBound() if flush options other
+ than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+ unsigned *pending,
+ int *bits));
+/*
+ deflatePending() returns the number of bytes and bits of output that have
+ been generated, but not yet provided in the available output. The bytes not
+ provided would be due to the available output space having being consumed.
+ The number of bits of output not provided are between 0 and 7, where they
+ await more bits to join them in order to fill out a full byte. If pending
+ or bits are Z_NULL, then those values are not set.
+
+ deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the bits
+ leftover from a previous deflate stream when appending to it. As such, this
+ function can only be used for raw deflate, and must be used before the first
+ deflate() call after a deflateInit2() or deflateReset(). bits must be less
+ than or equal to 16, and that many of the least significant bits of value
+ will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+ room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be zero to request that inflate use the window size in
+ the zlib header of the compressed stream.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
+ crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit2 does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit2() does not process any header information -- that is
+ deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called at any
+ time to set the dictionary. If the provided dictionary is smaller than the
+ window and there is already data in the window, then the provided dictionary
+ will amend what's there. The application must insure that the dictionary
+ that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a possible full flush point (see above
+ for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+ All full flush points have this pattern, but not all occurences of this
+ pattern are full flush points.
+
+ inflateSync returns Z_OK if a possible full flush point has been found,
+ Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+ has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+ In the success case, the application may save the current current value of
+ total_in which indicates where valid compressed data was found. In the
+ error case, the application may repeatedly call inflateSync, providing more
+ input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state. The
+ stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+ int windowBits));
+/*
+ This function is the same as inflateReset, but it also permits changing
+ the wrap and window size requests. The windowBits parameter is interpreted
+ the same as it is for inflateInit2.
+
+ inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+ the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ If bits is negative, then the input stream bit buffer is emptied. Then
+ inflatePrime() can be called again to put bits in the buffer. This is used
+ to clear out bits leftover after feeding inflate a block description prior
+ to feeding inflate codes.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+ This function returns two values, one in the lower 16 bits of the return
+ value, and the other in the remaining upper bits, obtained by shifting the
+ return value down 16 bits. If the upper value is -1 and the lower value is
+ zero, then inflate() is currently decoding information outside of a block.
+ If the upper value is -1 and the lower value is non-zero, then inflate is in
+ the middle of a stored block, with the lower value equaling the number of
+ bytes from the input remaining to copy. If the upper value is not -1, then
+ it is the number of bits back from the current bit position in the input of
+ the code (literal or length/distance pair) currently being processed. In
+ that case the lower value is the number of bytes already emitted for that
+ code.
+
+ A code is being processed if inflate is waiting for more input to complete
+ decoding of the code, or if it has completed decoding but is waiting for
+ more output space to write the literal or match data.
+
+ inflateMark() is used to mark locations in the input data for random
+ access, which may be at bit positions, and to note those cases where the
+ output of a code may span boundaries of random access blocks. The current
+ location in the input stream can be determined from avail_in and data_type
+ as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+ inflateMark returns the value noted above or -1 << 16 if the provided
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
+ used to force inflate() to return immediately after header processing is
+ complete and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When any
+ of extra, name, or comment are not Z_NULL and the respective field is not
+ present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+ allocated, or Z_VERSION_ERROR if the version of the library does not match
+ the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is more efficient than inflate() for
+ file i/o applications in that it avoids copying between the output and the
+ sliding window by simply making the window itself the output buffer. This
+ function trusts the application to not change the output buffer passed by
+ the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free the
+ allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects only
+ the raw deflate stream to decompress. This is different from the normal
+ behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+ in the deflate stream (in which case strm->msg is set to indicate the nature
+ of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+ In the case of Z_BUF_ERROR, an input or output error can be distinguished
+ using strm->next_in which will be Z_NULL only if in() returned an error. If
+ strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+ non-zero. (in() will always be called before out(), so strm->next_in is
+ assured to be defined if out() returns non-zero.) Note that inflateBack()
+ cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the basic
+ stream-oriented functions. To simplify the interface, some default options
+ are assumed (compression level and memory usage, standard memory allocation
+ functions). The source code of these utility functions can be modified if
+ you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before a
+ compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit, destLen
+ is the actual size of the uncompressed buffer.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
+ the case where there is not enough room, uncompress() will fill the output
+ buffer with the uncompressed data up to that point.
+*/
+
+ /* gzip file access functions */
+
+/*
+ This library supports reading and writing files in gzip (.gz) format with
+ an interface similar to that of stdio, using the functions that start with
+ "gz". The gzip format is different from the zlib format. gzip is a gzip
+ wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+ Opens a gzip (.gz) file for reading or writing. The mode parameter is as
+ in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+ a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+ compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+ for fixed code compression as in "wb9F". (See the description of
+ deflateInit2 for more information about the strategy parameter.) 'T' will
+ request transparent writing or appending with no compression and not using
+ the gzip format.
+
+ "a" can be used instead of "w" to request that the gzip stream that will
+ be written be appended to the file. "+" will result in an error, since
+ reading and writing to the same gzip file is not supported. The addition of
+ "x" when writing will create the file exclusively, which fails if the file
+ already exists. On systems that support it, the addition of "e" when
+ reading or writing will set the flag to close the file on an execve() call.
+
+ These functions, as well as gzip, will read and decode a sequence of gzip
+ streams in a file. The append function of gzopen() can be used to create
+ such a file. (Also see gzflush() for another way to do this.) When
+ appending, gzopen does not test whether the file begins with a gzip stream,
+ nor does it look for the end of the gzip streams to begin appending. gzopen
+ will simply append a gzip stream to the existing file.
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression. When
+ reading, this will be detected automatically by looking for the magic two-
+ byte gzip header.
+
+ gzopen returns NULL if the file could not be opened, if there was
+ insufficient memory to allocate the gzFile state, or if an invalid mode was
+ specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+ errno can be checked to determine if the reason gzopen failed was that the
+ file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen associates a gzFile with the file descriptor fd. File descriptors
+ are obtained from calls like open, dup, creat, pipe or fileno (if the file
+ has been previously opened with fopen). The mode parameter is as in gzopen.
+
+ The next call of gzclose on the returned gzFile will also close the file
+ descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+ fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+ mode);. The duplicated descriptor should be saved to avoid a leak, since
+ gzdopen does not close fd if it fails. If you are using fileno() to get the
+ file descriptor from a FILE *, then you will have to use dup() to avoid
+ double-close()ing the file descriptor. Both gzclose() and fclose() will
+ close the associated file descriptor, so they need to have different file
+ descriptors.
+
+ gzdopen returns NULL if there was insufficient memory to allocate the
+ gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+ provided, or '+' was provided), or if fd is -1. The file descriptor is not
+ used until the next gz* read, write, seek, or close operation, so gzdopen
+ will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+ Set the internal buffer size used by this library's functions. The
+ default buffer size is 8192 bytes. This function must be called after
+ gzopen() or gzdopen(), and before any other calls that read or write the
+ file. The buffer memory allocation is always deferred to the first read or
+ write. Two buffers are allocated, either both of the specified size when
+ writing, or one of the specified size and the other twice that size when
+ reading. A larger buffer size of, for example, 64K or 128K bytes will
+ noticeably increase the speed of decompression (reading).
+
+ The new buffer size also affects the maximum length for gzprintf().
+
+ gzbuffer() returns 0 on success, or -1 on failure, such as being called
+ too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file. If
+ the input file is not in gzip format, gzread copies the given number of
+ bytes into the buffer directly from the file.
+
+ After reaching the end of a gzip stream in the input, gzread will continue
+ to read, looking for another gzip stream. Any number of gzip streams may be
+ concatenated in the input file, and will all be decompressed by gzread().
+ If something other than a gzip stream is encountered after a gzip stream,
+ that remaining trailing garbage is ignored (and no error is returned).
+
+ gzread can be used to read a gzip file that is being concurrently written.
+ Upon reaching the end of the input, gzread will return with the available
+ data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+ gzclearerr can be used to clear the end of file indicator in order to permit
+ gzread to be tried again. Z_OK indicates that a gzip stream was completed
+ on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
+ middle of a gzip stream. Note that gzread does not return -1 in the event
+ of an incomplete gzip stream. This error is deferred until gzclose(), which
+ will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+ stream. Alternatively, gzerror can be used before gzclose to detect this
+ case.
+
+ gzread returns the number of uncompressed bytes actually read, less than
+ len for end of file, or -1 for error.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes written or 0 in case of
+ error.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the arguments to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written, or 0 in case of error. The number of
+ uncompressed bytes written is limited to 8191, or one less than the buffer
+ size given to gzbuffer(). The caller should assure that this limit is not
+ exceeded. If it is exceeded, then gzprintf() will return an error (0) with
+ nothing written. In this case, there may also be a buffer overflow with
+ unpredictable consequences, which is possible only if zlib was compiled with
+ the insecure functions sprintf() or vsprintf() because the secure snprintf()
+ or vsnprintf() functions were not available. This can be determined using
+ zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or a
+ newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. If any characters are read or if len == 1, the
+ string is terminated with a null character. If no characters are read due
+ to an end-of-file or len < 1, then the buffer is left untouched.
+
+ gzgets returns buf which is a null-terminated string, or it returns NULL
+ for end-of-file or in case of error. If there was an error, the contents at
+ buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file. gzputc
+ returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte or -1
+ in case of end of file or error. This is implemented as a macro for speed.
+ As such, it does not do all of the checking the other functions do. I.e.
+ it does not check to see if file is NULL, nor whether the structure file
+ points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read as the first character
+ on the next read. At least one character of push-back is allowed.
+ gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
+ fail if c is -1, and may fail if a character has been pushed but not read
+ yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
+ output buffer size of pushed characters is allowed. (See gzbuffer above.)
+ The pushed character will be discarded if the stream is repositioned with
+ gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter flush
+ is as in the deflate() function. The return value is the zlib error number
+ (see function gzerror below). gzflush is only permitted when writing.
+
+ If the flush parameter is Z_FINISH, the remaining data is written and the
+ gzip stream is completed in the output. If gzwrite() is called again, a new
+ gzip stream will be started in the output. gzread() is able to read such
+ concatented gzip streams.
+
+ gzflush should be called only when strictly necessary because it will
+ degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+
+ Returns the starting position for the next gzread or gzwrite on the given
+ compressed file. This position represents a number of bytes in the
+ uncompressed data stream, and is zero when starting, even if appending or
+ reading a gzip stream from the middle of a file using gzdopen().
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+ Returns the current offset in the file being read or written. This offset
+ includes the count of bytes that precede the gzip stream, for example when
+ appending or when using gzdopen() for reading. When reading, the offset
+ does not include as yet unused buffered input. This information can be used
+ for a progress indicator. On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns true (1) if the end-of-file indicator has been set while reading,
+ false (0) otherwise. Note that the end-of-file indicator is set only if the
+ read tried to go past the end of the input, but came up short. Therefore,
+ just like feof(), gzeof() may return false even if there is no more data to
+ read, in the event that the last read request was for the exact number of
+ bytes remaining in the input file. This will happen if the input file size
+ is an exact multiple of the buffer size.
+
+ If gzeof() returns true, then the read functions will return no more data,
+ unless the end-of-file indicator is reset by gzclearerr() and the input file
+ has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns true (1) if file is being copied directly while reading, or false
+ (0) if file is a gzip stream being decompressed.
+
+ If the input file is empty, gzdirect() will return true, since the input
+ does not contain a gzip stream.
+
+ If gzdirect() is used immediately after gzopen() or gzdopen() it will
+ cause buffers to be allocated to allow reading the file to determine if it
+ is a gzip file. Therefore if gzbuffer() is used, it should be called before
+ gzdirect().
+
+ When writing, gzdirect() returns true (1) if transparent writing was
+ requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
+ gzdirect() is not needed when writing. Transparent writing must be
+ explicitly requested, so the application already knows the answer. When
+ linking statically, using gzdirect() will include all of the zlib code for
+ gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file and
+ deallocates the (de)compression state. Note that once file is closed, you
+ cannot call gzerror with file, since its structures have been deallocated.
+ gzclose must not be called more than once on the same file, just as free
+ must not be called more than once on the same allocation.
+
+ gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+ file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+ last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+ Same as gzclose(), but gzclose_r() is only for use when reading, and
+ gzclose_w() is only for use when writing or appending. The advantage to
+ using these instead of gzclose() is that they avoid linking in zlib
+ compression or decompression code that is not used when only reading or only
+ writing respectively. If gzclose() is used, then both compression and
+ decompression code will be included the application when linking to a static
+ zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the given
+ compressed file. errnum is set to zlib error number. If an error occurred
+ in the file system and not in the compression library, errnum is set to
+ Z_ERRNO and the application may consult errno to get the exact error code.
+
+ The application must not modify the returned string. Future calls to
+ this function may invalidate the previously returned string. If file is
+ closed, then the string previously returned by gzerror will no longer be
+ available.
+
+ gzerror() should be used to distinguish errors from end-of-file for those
+ functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the compression
+ library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is Z_NULL, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster.
+
+ Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
+ that the z_off_t type (like off_t) is a signed integer. If len2 is
+ negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is Z_NULL, this function returns the required
+ initial value for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
+
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure. Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro. The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously. They can
+ * only be used by the gzgetc() macro. You have been warned.
+ */
+struct gzFile_s {
+ unsigned have;
+ unsigned char *next;
+ z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+# define z_gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#else
+# define gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+# ifdef Z_PREFIX_SET
+# define z_gzopen z_gzopen64
+# define z_gzseek z_gzseek64
+# define z_gztell z_gztell64
+# define z_gzoffset z_gzoffset64
+# define z_adler32_combine z_adler32_combine64
+# define z_crc32_combine z_crc32_combine64
+# else
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# endif
+# ifndef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+# endif
+#else
+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* hack for buggy compilers */
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;};
+#endif
+
+/* undocumented functions */
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
+#if defined(_WIN32) && !defined(Z_SOLO)
+ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
+ const char *mode));
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/kernel/drivers/net/ethernet/ip1811/ip1811.c b/kernel/drivers/net/ethernet/ip1811/ip1811.c
new file mode 100644
index 0000000..df75aa6
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/ip1811.c
@@ -0,0 +1,482 @@
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <asm/uaccess.h>
+#include <linux/uaccess.h>
+
+#include "ip1811.h"
+#include "ip1811fdat.h"
+
+static struct cdev ip1811_cdev;
+struct class *ip1811_class;
+static DEFINE_MUTEX(ip1811_mutex);
+u8 CPU_IF_SPEED_NORMAL;
+
+#define IP1811_MAJOR 248
+#define IP1811_NAME "ip1811_cdev"
+
+//#define IP1811DEBUG
+
+MODULE_LICENSE ("GPL");
+
+static int ip1811_open(struct inode *inode, struct file *fs)
+{
+#ifdef IP1811DEBUG
+ printk("ip1811: open...\n");
+#endif
+ try_module_get(THIS_MODULE);
+
+ return 0;
+}
+
+static int ip1811_release(struct inode *inode, struct file *file)
+{
+ module_put(THIS_MODULE);
+#ifdef IP1811DEBUG
+ printk("ip1811: release!\n");
+#endif
+ return 0;
+}
+
+static ssize_t ip1811_read(struct file *filp, char __user *buffer, size_t length, loff_t *offset)
+{
+ // return simple_read_from_buffer(buffer, length, offset, msg, 200);
+ return 0;
+}
+
+static ssize_t ip1811_write(struct file *filp, const char __user *buff, size_t len, loff_t *off)
+{
+ /* if (len > 199)
+ return -EINVAL;
+ copy_from_user(msg, buff, len);
+ msg[len] = '\0';
+ return len;*/
+ return 0;
+}
+
+static int ip1811_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+{
+ int ret;
+ unsigned long len, cmdid, fno, fsubg, fgrp, fusg;
+ void *cptr;
+ char *cdata, *cmptr;
+ int offset_t;
+
+#ifdef IP1811DEBUG
+ printk(KERN_ALERT "ip1811: +ioctl...\n");
+#endif
+ len = (int)(_IOC_SIZE(cmd));
+ cptr = (void *)arg;
+ offset_t = sizeof(void*) + sizeof(unsigned long);
+
+ do {
+ cdata = kmalloc(len, GFP_KERNEL);
+ cmptr=cdata;
+
+ if (!cdata)
+ {
+ printk(KERN_ERR "cdata==NULL");
+ ret = -ENOMEM;
+ goto out_ip1811_ioctl;
+ }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
+ if(access_ok(VERIFY_READ, cptr, len)){
+#else
+ if(access_ok(cptr, len)){
+#endif
+ if(copy_from_user(cdata, cptr, len)){
+ printk(KERN_ERR "copy_from_user fail. len:%ld",(unsigned long)len);
+ ret=-EFAULT;
+ goto out_ip1811_ioctl;
+ }
+ }
+ else{
+ printk(KERN_ERR "[switchDriver] copy_from_user access fail by %s:%d CMD:%x\n",__FUNCTION__,__LINE__,cmd);
+ ret = -EFAULT;
+ goto out_ip1811_ioctl;
+ }
+ if(cmptr!=cdata){
+ printk(KERN_ERR "cdata error org: %p, after: %p", cmptr, cdata);
+ }
+ cmdid = *((unsigned long *)(cdata+offset_t));
+ fno = (cmdid >> _CMDID_NRSHIFT) & _CMDID_NRMASK;
+ fsubg=(cmdid >> _CMDID_SUBGSHIFT) & _CMDID_SUBGMASK;
+ fgrp= (cmdid >> _CMDID_GRPSHIFT) & _CMDID_GRPMASK;
+ fusg= (cmdid >> _CMDID_USGSHIFT) & _CMDID_USGMASK;
+#ifdef IP1811DEBUG
+ printk(KERN_ALERT "cmdid=0x%08x\n", (unsigned int)cmdid);
+#endif
+
+ if (fusg == _CMDID_USG_COMMON)
+ {
+ switch (fgrp)
+ {
+ case _CMDID_GRP_BASIC:
+ switch (fsubg)
+ {
+ case _CMDID_SUBG_SMI:
+ ret = func_of_common_smi[fno](cdata, len); break;
+
+ case _CMDID_SUBG_CAP:
+ ret = func_of_common_cap[fno](cdata, len); break;
+
+ case _CMDID_SUBG_LUT:
+ ret = func_of_common_lut[fno](cdata, len); break;
+
+ case _CMDID_SUBG_SNIFFER:
+ ret = func_of_common_sniffer[fno](cdata, len); break;
+
+ case _CMDID_SUBG_STORM:
+ ret = func_of_common_storm[fno](cdata, len); break;
+
+ case _CMDID_SUBG_EOC:
+ ret = func_of_common_eoc[fno](cdata, len); break;
+
+ case _CMDID_SUBG_LD:
+ ret = func_of_common_ld[fno](cdata, len); break;
+
+ case _CMDID_SUBG_WOL:
+ ret = func_of_common_wol[fno](cdata, len); break;
+
+ case _CMDID_SUBG_STAG:
+ ret = func_of_common_stag[fno](cdata, len); break;
+
+ case _CMDID_SUB_BANDWIDTH:
+ ret = func_of_common_bandwidth[fno](cdata, len); break;
+
+ case _CMDID_SUBG_MISC:
+ ret = func_of_common_misc[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+
+ case _CMDID_GRP_VLAN:
+ switch (fsubg)
+ {
+ case _CMDID_SUBG_VLAN:
+ ret = func_of_common_vlan[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+
+ case _CMDID_GRP_QOS:
+ switch (fsubg)
+ {
+ case _CMDID_SUB_BANDWIDTH:
+ ret = func_of_common_bandwidth[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+
+ case _CMDID_GRP_SEC:
+ switch (fsubg)
+ {
+ case _CMDID_SUBG_IMP:
+ ret = func_of_common_imp[fno](cdata, len); break;
+
+ case _CMDID_SUBG_COS:
+ ret = func_of_common_cos[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+
+ case _CMDID_GRP_ADV:
+ switch (fsubg)
+ {
+ case _CMDID_SUBG_STP:
+ ret = func_of_common_stp[fno](cdata, len); break;
+
+ case _CMDID_SUBG_LACP:
+ ret = func_of_common_lacp[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+
+ default:
+ ret = -EINVAL;
+ }
+ }
+ else if (fusg == _CMDID_USG_IP1811)
+ {
+ switch (fgrp)
+ {
+ case _CMDID_GRP_BASIC:
+ switch (fsubg)
+ {
+ case _CMDID_SUBG_CAP:
+ ret = func_of_common_cap[fno](cdata, len); break;
+
+ case _CMDID_SUBG_LUT:
+ ret = func_of_ip1811_lut[fno](cdata, len); break;
+
+ case _CMDID_SUBG_SNIFFER:
+ ret = func_of_ip1811_sniffer[fno](cdata, len); break;
+
+ case _CMDID_SUBG_STORM:
+ ret = func_of_ip1811_storm[fno](cdata, len); break;
+
+ case _CMDID_SUBG_EOC:
+ ret = func_of_ip1811_eoc[fno](cdata, len); break;
+
+ case _CMDID_SUBG_LD:
+ ret = func_of_ip1811_ld[fno](cdata, len); break;
+
+ case _CMDID_SUBG_WOL:
+ ret = func_of_ip1811_wol[fno](cdata, len); break;
+
+ case _CMDID_SUBG_IGMP:
+ ret = func_of_ip1811_igmp[fno](cdata, len); break;
+
+ case _CMDID_SUBG_PTP:
+ ret = func_of_ip1811_ptp[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+
+ case _CMDID_GRP_VLAN:
+ switch (fsubg)
+ {
+ case _CMDID_SUBG_VLAN:
+ ret = func_of_ip1811_vlan[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+ case _CMDID_GRP_QOS:
+ switch (fsubg)
+ {
+ case _CMDID_SUB_QOS:
+ ret = func_of_ip1811_qos[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+ case _CMDID_GRP_ACL:
+ switch (fsubg)
+ {
+ case _CMDID_SUBG_ACL:
+ ret = func_of_ip1811_acl[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+
+ case _CMDID_GRP_SEC:
+ switch (fsubg)
+ {
+ case _CMDID_SUBG_IMP:
+ ret = func_of_ip1811_imp[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+
+ case _CMDID_GRP_ADV:
+ switch (fsubg)
+ {
+ case _CMDID_SUBG_STP:
+ ret = func_of_ip1811_stp[fno](cdata, len); break;
+
+ case _CMDID_SUBG_LACP:
+ ret = func_of_ip1811_lacp[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+ case _CMDID_GRP_MON:
+ switch (fsubg)
+ {
+ case _CMDID_SUBG_MIB_COUNTER:
+ ret = func_of_ip1811_mib_counter[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+
+ case _CMDID_GRP_HSR:
+ switch (fsubg)
+ {
+ case _CMDID_SUBG_HSR:
+ ret = func_of_ip1811_hsr[fno](cdata, len); break;
+
+ default:
+ ret = -EINVAL;
+ }
+ break;
+
+ default:
+ ret = -EINVAL;
+ }
+ }
+ else
+ ret = -EINVAL;
+
+ if (ret < 0) goto out_ip1811_ioctl;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
+ if(access_ok(WERIFY_WRITE, cptr, len)){
+#else
+ if(access_ok(cptr, len)){
+#endif
+ if (copy_to_user(cptr, cdata, len)) {
+ printk(KERN_ERR "copy_touser fail.");
+ ret = -EFAULT;
+ goto out_ip1811_ioctl;
+ }
+ }
+ else{
+ printk(KERN_ERR "[switchDriver] copy_from_user access fail by %s:%d CMD:%x\n",__FUNCTION__,__LINE__,cmd);
+ ret=-EFAULT;
+ goto out_ip1811_ioctl;
+ }
+ cptr= (void *)*((unsigned long *)cdata);
+ len = *((unsigned long *)(cdata+4));
+
+ kfree(cdata);
+ cdata = NULL;
+ } while (cptr);
+out_ip1811_ioctl:
+ if(cdata)
+ {
+ //memset(cdata, 0x0, len);
+ kfree(cdata);
+ }
+#ifdef IP1811DEBUG
+ printk(KERN_ALERT "ip1811: -ioctl...\n");
+#endif
+ return (ret < 0) ? ret : 0;
+}
+
+static void lock_key_ioctl(void)
+{
+ mutex_lock(&ip1811_mutex);
+}
+
+static void unlock_key_ioctl(void)
+{
+ mutex_unlock(&ip1811_mutex);
+}
+
+static long ip1811_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+{
+ int ret;
+
+ lock_key_ioctl();
+ ret = ip1811_ioctl(filep, cmd, arg);
+ unlock_key_ioctl();
+
+ return ret;
+}
+
+static struct file_operations ip1811_fops = {
+ .owner = THIS_MODULE,
+ .read = ip1811_read,
+ .write = ip1811_write,
+ .unlocked_ioctl = ip1811_unlocked_ioctl,
+ .open = ip1811_open,
+ .release = ip1811_release
+};
+
+extern u16 Read_Reg(u8 regaddr);
+extern void Write_Reg(u8 regaddr, u16 value);
+extern void IP2Page(u8 page);
+extern u16 Read_Reg_0_With_1s(void);
+
+/* ==================================================================================== */
+
+static int __init ip1811_init(void)
+{
+ int result;
+
+ result = register_chrdev_region(MKDEV(IP1811_MAJOR, 0), 1, IP1811_NAME);
+ if (result < 0)
+ {
+ printk(KERN_WARNING "ip1811: can't get major %d\n", IP1811_MAJOR);
+ return result;
+ }
+
+ cdev_init(&ip1811_cdev, &ip1811_fops);
+ ip1811_cdev.owner = THIS_MODULE;
+ result = cdev_add(&ip1811_cdev, MKDEV(IP1811_MAJOR, 0), 1);
+ if (result)
+ {
+ printk(KERN_WARNING "ip1811: error %d adding driver\n", result);
+ return result;
+ }
+
+ CPU_IF_SPEED_NORMAL = 0; //set to normal speed initially
+
+ IP2Page(0);
+ if( (Read_Reg_0_With_1s() & 0xFFF0) == 0x8120 )
+ {
+ printk("ip1811: CPU I/F High speed.");
+ }
+ else
+ {
+ CPU_IF_SPEED_NORMAL = 1;
+ printk("ip1811: CPU I/F Normal speed.");
+ }
+
+ // for acl_man init.
+ acl_init();
+
+ printk(" Driver loaded!\n");
+ return 0;
+ /*
+fail_return:
+ if(ip1811_cdev){
+ cdev_del(ip1811_cdev);
+ kfree(ip1811_cdev);
+ ip1811_cdev=NULL;
+ }
+ if(devno)
+ unregister_chrdev_region(devno, 1);
+ if(ip1811_class)
+ class_destroy(ip1811_class);
+ return -1;
+ */
+}
+
+static void __exit ip1811_exit(void)
+{
+ /*
+ if(ip1811_cdev){
+ cdev_del(ip1811_cdev);
+ kfree(ip1811_cdev);
+ ip1811_cdev=NULL;
+ }
+ if(devno)
+ unregister_chrdev_region(devno, 1);
+ if(ip1811_class)
+ class_destroy(ip1811_class);
+ */
+ cdev_del(&ip1811_cdev);
+ unregister_chrdev_region(MKDEV(IP1811_MAJOR, 0), 1);
+ printk("ip1811: Driver unloaded!\n");
+}
+
+module_init(ip1811_init);
+module_exit(ip1811_exit);
diff --git a/kernel/drivers/net/ethernet/ip1811/ip1811.h b/kernel/drivers/net/ethernet/ip1811/ip1811.h
new file mode 100644
index 0000000..0774d60
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/ip1811.h
@@ -0,0 +1,1323 @@
+#ifndef IP1811_H
+#define IP1811_H
+
+/*===================================================================*/
+/* max port number of this switch */
+#define MAX_PHY_NUM (12)
+/* port-list mask */
+#define ALL_PHY_PORTS_LIST (~(-1 << (MAX_PHY_NUM - 1)))
+/* max port number of TP port */
+#define MAX_PHY_TP_NUM (8)
+
+/* max number of fid */
+#define MAX_FID_NUM (16)
+/* max LUT table block number */
+#define MAX_BLOCK_NUM (1)
+/* max LUT table entry number */
+#define MAX_LUT_ENTRY_NUM (4096)
+/* LUT table aging time unit(millisecond) */
+#define AGING_TIME_UNIT (550)
+
+/* max IP-Mac-Port table entry number */
+#define MAX_IMP_ENTRY_NUM (128)
+
+/* max PVID number */
+#define MAX_PVID_NUM (4096)
+/* mac Protocol Based VLAN entry number */
+#define MAX_PRO_VLAN_ENTRY_NUM (4)
+
+/* max link speed of TP port */
+#define MAX_TP_SPEED (100000000)
+/* max link speed of Giga port */
+#define MAX_GIGA_SPEED (1000000000)
+
+/*===================================================================*/
+#define TYPECHECK(t) (sizeof(t))
+
+#define _CMDID_NRBITS 8
+#define _CMDID_SUBGBITS 4
+#define _CMDID_RSVD1BITS 4
+#define _CMDID_GRPBITS 8
+#define _CMDID_USGBITS 4
+
+#define _CMDID_NRMASK ((1 << _CMDID_NRBITS)-1)
+#define _CMDID_SUBGMASK ((1 << _CMDID_SUBGBITS)-1)
+#define _CMDID_GRPMASK ((1 << _CMDID_GRPBITS)-1)
+#define _CMDID_USGMASK ((1 << _CMDID_USGBITS)-1)
+
+#define _CMDID_NRSHIFT 0
+#define _CMDID_SUBGSHIFT (_CMDID_NRSHIFT+_CMDID_NRBITS)
+#define _CMDID_GRPSHIFT (_CMDID_SUBGSHIFT+_CMDID_SUBGBITS+_CMDID_RSVD1BITS)
+#define _CMDID_USGSHIFT (_CMDID_GRPSHIFT+_CMDID_GRPBITS)
+
+#define MAKECMDID(usg, grp, subg, nr) ( (usg << _CMDID_USGSHIFT) | (grp << _CMDID_GRPSHIFT) | \
+ (subg << _CMDID_SUBGSHIFT) | (nr << _CMDID_NRSHIFT) )
+
+#define _CMDID_USG_COMMON 0x0
+#define _CMDID_USG_IP1811 0x1
+#define _CMDID_USG_DBS 0x2
+#define NUM_CMDID_USG 0x3
+
+/*===================================================================*/
+#define _CMDID_GRP_BASIC 0x01
+
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_SMI 0x1
+enum{
+ IDX_COMMON_SET_PORT_AN, //0
+ IDX_COMMON_GET_PORT_AN,
+ IDX_COMMON_SET_PORT_SPEED,
+ IDX_COMMON_GET_PORT_SPEED,
+ IDX_COMMON_SET_PORT_DUPLEX,
+ IDX_COMMON_GET_PORT_DUPLEX,
+ IDX_COMMON_SET_PORT_PAUSE,
+ IDX_COMMON_GET_PORT_PAUSE,
+ IDX_COMMON_SET_PORT_ASYM_PAUSE,
+ IDX_COMMON_GET_PORT_ASYM_PAUSE,
+ IDX_COMMON_SET_PORT_LINK_STATUS, //10
+ IDX_COMMON_GET_PORT_LINK_STATUS,
+ IDX_COMMON_SET_PORT_BACKPRESSURE,
+ IDX_COMMON_GET_PORT_BACKPRESSURE,
+ IDX_COMMON_SET_PORT_POWER_DOWN,
+ IDX_COMMON_GET_PORT_POWER_DOWN,
+ IDX_COMMON_SET_PORT_FORCE_LINK,
+ IDX_COMMON_GET_PORT_FORCE_LINK,
+ IDX_COMMON_SET_PORT_UNI_DIRECTION,
+ IDX_COMMON_GET_PORT_UNI_DIRECTION,
+ IDX_COMMON_SET_MDIO_DIV, //20
+ IDX_COMMON_SET_FALSE_LINK_SOLUTION,
+ NUM_COMMON_SMI //22
+};
+
+#define ID_COMMON_SMI(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_BASIC, _CMDID_SUBG_SMI, idx)
+
+#define ID_COMMON_SET_PORT_AN \
+ ID_COMMON_SMI(IDX_COMMON_SET_PORT_AN)
+#define ID_COMMON_GET_PORT_AN \
+ ID_COMMON_SMI(IDX_COMMON_GET_PORT_AN)
+#define ID_COMMON_SET_PORT_SPEED \
+ ID_COMMON_SMI(IDX_COMMON_SET_PORT_SPEED)
+#define ID_COMMON_GET_PORT_SPEED \
+ ID_COMMON_SMI(IDX_COMMON_GET_PORT_SPEED)
+#define ID_COMMON_SET_PORT_DUPLEX \
+ ID_COMMON_SMI(IDX_COMMON_SET_PORT_DUPLEX)
+#define ID_COMMON_GET_PORT_DUPLEX \
+ ID_COMMON_SMI(IDX_COMMON_GET_PORT_DUPLEX)
+#define ID_COMMON_SET_PORT_PAUSE \
+ ID_COMMON_SMI(IDX_COMMON_SET_PORT_PAUSE)
+#define ID_COMMON_GET_PORT_PAUSE \
+ ID_COMMON_SMI(IDX_COMMON_GET_PORT_PAUSE)
+#define ID_COMMON_SET_PORT_ASYM_PAUSE \
+ ID_COMMON_SMI(IDX_COMMON_SET_PORT_ASYM_PAUSE)
+#define ID_COMMON_GET_PORT_ASYM_PAUSE \
+ ID_COMMON_SMI(IDX_COMMON_GET_PORT_ASYM_PAUSE)
+#define ID_COMMON_SET_PORT_LINK_STATUS \
+ ID_COMMON_SMI(IDX_COMMON_SET_PORT_LINK_STATUS)
+#define ID_COMMON_GET_PORT_LINK_STATUS \
+ ID_COMMON_SMI(IDX_COMMON_GET_PORT_LINK_STATUS)
+#define ID_COMMON_SET_PORT_BACKPRESSURE \
+ ID_COMMON_SMI(IDX_COMMON_SET_PORT_BACKPRESSURE)
+#define ID_COMMON_GET_PORT_BACKPRESSURE \
+ ID_COMMON_SMI(IDX_COMMON_GET_PORT_BACKPRESSURE)
+#define ID_COMMON_SET_PORT_POWER_DOWN \
+ ID_COMMON_SMI(IDX_COMMON_SET_PORT_POWER_DOWN)
+#define ID_COMMON_GET_PORT_POWER_DOWN \
+ ID_COMMON_SMI(IDX_COMMON_GET_PORT_POWER_DOWN)
+#define ID_COMMON_SET_PORT_FORCE_LINK \
+ ID_COMMON_SMI(IDX_COMMON_SET_PORT_FORCE_LINK)
+#define ID_COMMON_GET_PORT_FORCE_LINK \
+ ID_COMMON_SMI(IDX_COMMON_GET_PORT_FORCE_LINK)
+#define ID_COMMON_SET_PORT_UNI_DIRECTION \
+ ID_COMMON_SMI(IDX_COMMON_SET_PORT_UNI_DIRECTION)
+#define ID_COMMON_GET_PORT_UNI_DIRECTION \
+ ID_COMMON_SMI(IDX_COMMON_GET_PORT_UNI_DIRECTION)
+#define ID_COMMON_SET_MDIO_DIV \
+ ID_COMMON_SMI(IDX_COMMON_SET_MDIO_DIV)
+#define ID_COMMON_SET_FALSE_LINK_SOLUTION\
+ ID_COMMON_SMI(IDX_COMMON_SET_FALSE_LINK_SOLUTION)
+
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_CAP 0x2
+enum{
+ IDX_COMMON_L2_SET_CAP_ACT,
+ IDX_COMMON_CAP_SET_IN_BAND,
+ IDX_COMMON_CAP_SET_SWITCH_MAC,
+ IDX_COMMON_CAP_SET_IPV6_TCPUDP_ENABLE,
+ NUM_COMMON_CAP
+};
+
+#define ID_COMMON_CAP(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_BASIC, _CMDID_SUBG_CAP, idx)
+
+#define ID_COMMON_L2_SET_CAP_ACT \
+ ID_COMMON_CAP(IDX_COMMON_L2_SET_CAP_ACT)
+
+#define ID_COMMON_CAP_SET_IN_BAND \
+ ID_COMMON_CAP(IDX_COMMON_CAP_SET_IN_BAND)
+
+#define ID_COMMON_CAP_SET_SWITCH_MAC \
+ ID_COMMON_CAP(IDX_COMMON_CAP_SET_SWITCH_MAC)
+
+#define ID_COMMON_CAP_SET_IPV6_TCPUDP_ENABLE \
+ ID_COMMON_CAP(IDX_COMMON_CAP_SET_IPV6_TCPUDP_ENABLE)
+
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_LUT 0x3
+
+enum{
+ IDX_COMMON_SET_SMAC_LEARNING, //0
+ IDX_COMMON_GET_SMAC_LEARNING,
+ IDX_COMMON_LUT_SET_PORT_FLUSH,
+ IDX_COMMON_SET_LUT_AGING_TIME,
+ IDX_COMMON_GET_LUT_AGING_TIME,
+ IDX_COMMON_SET_LUT_AGING_TIME_ENABLE,
+ IDX_COMMON_SET_LUT_LEARN_NSA,
+ IDX_COMMON_SET_LUT_HASHING_ALGORITHM,
+ IDX_COMMON_SET_LUT_BINDING_ENABLE,
+ IDX_COMMON_GET_LUT_BINDING_ENABLE,
+ NUM_COMMON_LUT
+};
+
+#define ID_COMMON_LUT(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_BASIC, _CMDID_SUBG_LUT, idx)
+
+#define ID_COMMON_SET_SMAC_LEARNING \
+ ID_COMMON_LUT(IDX_COMMON_SET_SMAC_LEARNING)
+#define ID_COMMON_GET_SMAC_LEARNING\
+ ID_COMMON_LUT(IDX_COMMON_GET_SMAC_LEARNING)
+#define ID_COMMON_LUT_SET_PORT_FLUSH\
+ ID_COMMON_LUT(IDX_COMMON_LUT_SET_PORT_FLUSH)
+#define ID_COMMON_SET_LUT_AGING_TIME\
+ ID_COMMON_LUT(IDX_COMMON_SET_LUT_AGING_TIME)
+#define ID_COMMON_GET_LUT_AGING_TIME\
+ ID_COMMON_LUT(IDX_COMMON_GET_LUT_AGING_TIME)
+#define ID_COMMON_SET_LUT_AGING_TIME_ENABLE\
+ ID_COMMON_LUT(IDX_COMMON_SET_LUT_AGING_TIME_ENABLE)
+#define ID_COMMON_SET_LUT_LEARN_NSA \
+ ID_COMMON_LUT(IDX_COMMON_SET_LUT_LEARN_NSA)
+#define ID_COMMON_SET_LUT_HASHING_ALGORITHM \
+ ID_COMMON_LUT(IDX_COMMON_SET_LUT_HASHING_ALGORITHM)
+#define ID_COMMON_SET_LUT_BINDING_ENABLE \
+ ID_COMMON_LUT(IDX_COMMON_SET_LUT_BINDING_ENABLE)
+#define ID_COMMON_GET_LUT_BINDING_ENABLE\
+ ID_COMMON_LUT(IDX_COMMON_GET_LUT_BINDING_ENABLE)
+
+enum{
+ IDX_1811_LUT_SET_UNKNOWN_SA_RULE,
+ IDX_1811_LUT_SET_ENTRY,
+ IDX_1811_LUT_GET_ENTRY,
+ IDX_1811_LUT_GET_VALID_ENTRY,
+ NUM_1811_LUT
+};
+
+#define ID_1811_LUT(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_BASIC, _CMDID_SUBG_LUT, idx)
+
+#define ID_1811_LUT_SET_UNKNOWN_SA_RULE \
+ ID_1811_LUT(IDX_1811_LUT_SET_UNKNOWN_SA_RULE)
+#define ID_1811_LUT_SET_ENTRY\
+ ID_1811_LUT(IDX_1811_LUT_SET_ENTRY)
+#define ID_1811_LUT_GET_ENTRY\
+ ID_1811_LUT(IDX_1811_LUT_GET_ENTRY)
+#define ID_1811_LUT_GET_VALID_ENTRY\
+ ID_1811_LUT(IDX_1811_LUT_GET_VALID_ENTRY)
+
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_SNIFFER 0x4
+
+enum{
+ IDX_COMMON_SET_SNIFFER_SOURCE,
+ IDX_COMMON_GET_SNIFFER_SOURCE,
+ IDX_COMMON_SET_SNIFFER_DEST_GRP1,
+ IDX_COMMON_GET_SNIFFER_DEST_GRP1,
+ IDX_COMMON_SNIFFER1_SET_METHOD,
+ IDX_COMMON_SNIFFER1_GET_METHOD,
+ NUM_COMMON_SNIFFER
+};
+#define ID_COMMON_SNIFFER(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_BASIC, _CMDID_SUBG_SNIFFER, idx)
+
+#define ID_COMMON_SET_SNIFFER_SOURCE \
+ ID_COMMON_SNIFFER(IDX_COMMON_SET_SNIFFER_SOURCE)
+#define ID_COMMON_GET_SNIFFER_SOURCE \
+ ID_COMMON_SNIFFER(IDX_COMMON_GET_SNIFFER_SOURCE)
+#define ID_COMMON_SET_SNIFFER_DEST_GRP1 \
+ ID_COMMON_SNIFFER(IDX_COMMON_SET_SNIFFER_DEST_GRP1)
+#define ID_COMMON_GET_SNIFFER_DEST_GRP1 \
+ ID_COMMON_SNIFFER(IDX_COMMON_GET_SNIFFER_DEST_GRP1)
+#define ID_COMMON_SNIFFER1_SET_METHOD \
+ ID_COMMON_SNIFFER(IDX_COMMON_SNIFFER1_SET_METHOD)
+#define ID_COMMON_SNIFFER1_GET_METHOD \
+ ID_COMMON_SNIFFER(IDX_COMMON_SNIFFER1_GET_METHOD)
+
+enum{
+ IDX_1811_SNIFFER1_SET_PKT_MODIFY,
+ IDX_1811_SNIFFER1_GET_PKT_MODIFY,
+ IDX_1811_SNIFFER1_SET_TAG_MODIFY_FOR_CPU_STAG,
+ IDX_1811_SNIFFER1_GET_TAG_MODIFY_FOR_CPU_STAG,
+ IDX_1811_SNIFFER1_SET_TAG_MODIFY_FOR_ACL_REDIR_2CPU,
+ IDX_1811_SNIFFER1_GET_TAG_MODIFY_FOR_ACL_REDIR_2CPU,
+ IDX_1811_SNIFFER1_SET_TAG_MODIFY_FOR_PKT_2MIRROR_PORT,
+ IDX_1811_SNIFFER1_GET_TAG_MODIFY_FOR_PKT_2MIRROR_PORT,
+ IDX_1811_SNIFFER2_SET_LUT_TRIGGER_TARGET_FOR_GRP1,
+ IDX_1811_SNIFFER2_GET_LUT_TRIGGER_TARGET_FOR_GRP1,
+ NUM_1811_SNIFFER
+};
+#define ID_1811_SNIFFER(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_BASIC, _CMDID_SUBG_SNIFFER, idx)
+
+#define ID_1811_SNIFFER1_SET_PKT_MODIFY \
+ ID_1811_SNIFFER(IDX_1811_SNIFFER1_SET_PKT_MODIFY)
+#define ID_1811_SNIFFER1_GET_PKT_MODIFY \
+ ID_1811_SNIFFER(IDX_1811_SNIFFER1_GET_PKT_MODIFY)
+#define ID_1811_SNIFFER1_SET_TAG_MODIFY_FOR_CPU_STAG \
+ ID_1811_SNIFFER(IDX_1811_SNIFFER1_SET_TAG_MODIFY_FOR_CPU_STAG)
+#define ID_1811_SNIFFER1_GET_TAG_MODIFY_FOR_CPU_STAG \
+ ID_1811_SNIFFER(IDX_1811_SNIFFER1_GET_TAG_MODIFY_FOR_CPU_STAG)
+#define ID_1811_SNIFFER1_SET_TAG_MODIFY_FOR_ACL_REDIR_2CPU \
+ ID_1811_SNIFFER(IDX_1811_SNIFFER1_SET_TAG_MODIFY_FOR_ACL_REDIR_2CPU)
+#define ID_1811_SNIFFER1_GET_TAG_MODIFY_FOR_ACL_REDIR_2CPU \
+ ID_1811_SNIFFER(IDX_1811_SNIFFER1_GET_TAG_MODIFY_FOR_ACL_REDIR_2CPU)
+#define ID_1811_SNIFFER1_SET_TAG_MODIFY_FOR_PKT_2MIRROR_PORT \
+ ID_1811_SNIFFER(IDX_1811_SNIFFER1_SET_TAG_MODIFY_FOR_PKT_2MIRROR_PORT)
+#define ID_1811_SNIFFER1_GET_TAG_MODIFY_FOR_PKT_2MIRROR_PORT \
+ ID_1811_SNIFFER(IDX_1811_SNIFFER1_GET_TAG_MODIFY_FOR_PKT_2MIRROR_PORT)
+#define ID_1811_SNIFFER2_SET_LUT_TRIGGER_TARGET_FOR_GRP1 \
+ ID_1811_SNIFFER(IDX_1811_SNIFFER2_SET_LUT_TRIGGER_TARGET_FOR_GRP1)
+#define ID_1811_SNIFFER2_GET_LUT_TRIGGER_TARGET_FOR_GRP1 \
+ ID_1811_SNIFFER(IDX_1811_SNIFFER2_GET_LUT_TRIGGER_TARGET_FOR_GRP1)
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_STORM 0x5
+
+enum{
+ IDX_COMMON_STORM_CTRL_SET_FUNC,
+ IDX_COMMON_STORM_CTRL_GET_FUNC,
+ IDX_COMMON_STORM_CTRL_SET_THRESHOLD,
+ IDX_COMMON_STORM_CTRL_GET_THRESHOLD,
+ IDX_COMMON_STORM_SET_COUNTER_CLR_PERIOD,
+ IDX_COMMON_STORM_GET_COUNTER_CLR_PERIOD,
+ IDX_COMMON_STORM_SET_BLOCK_FRAME_2CPU,
+ IDX_COMMON_STORM_GET_BLOCK_FRAME_2CPU,
+ IDX_COMMON_STORM_SET_DROP_INTERRUPT,
+ IDX_COMMON_STORM_GET_DROP_INTERRUPT,
+ NUM_COMMON_STORM
+};
+#define ID_COMMON_STORM(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_BASIC, _CMDID_SUBG_STORM, idx)
+
+#define ID_COMMON_STORM_CTRL_SET_FUNC \
+ ID_COMMON_STORM(IDX_COMMON_STORM_CTRL_SET_FUNC)
+#define ID_COMMON_STORM_CTRL_GET_FUNC \
+ ID_COMMON_STORM(IDX_COMMON_STORM_CTRL_GET_FUNC)
+#define ID_COMMON_STORM_CTRL_SET_THRESHOLD \
+ ID_COMMON_STORM(IDX_COMMON_STORM_CTRL_SET_THRESHOLD)
+#define ID_COMMON_STORM_CTRL_GET_THRESHOLD \
+ ID_COMMON_STORM(IDX_COMMON_STORM_CTRL_GET_THRESHOLD)
+#define ID_COMMON_STORM_SET_COUNTER_CLR_PERIOD \
+ ID_COMMON_STORM(IDX_COMMON_STORM_SET_COUNTER_CLR_PERIOD)
+#define ID_COMMON_STORM_GET_COUNTER_CLR_PERIOD \
+ ID_COMMON_STORM(IDX_COMMON_STORM_GET_COUNTER_CLR_PERIOD)
+#define ID_COMMON_STORM_SET_BLOCK_FRAME_2CPU \
+ ID_COMMON_STORM(IDX_COMMON_STORM_SET_BLOCK_FRAME_2CPU)
+#define ID_COMMON_STORM_GET_BLOCK_FRAME_2CPU \
+ ID_COMMON_STORM(IDX_COMMON_STORM_GET_BLOCK_FRAME_2CPU)
+#define ID_COMMON_STORM_SET_DROP_INTERRUPT \
+ ID_COMMON_STORM(IDX_COMMON_STORM_SET_DROP_INTERRUPT)
+#define ID_COMMON_STORM_GET_DROP_INTERRUPT \
+ ID_COMMON_STORM(IDX_COMMON_STORM_GET_DROP_INTERRUPT)
+
+enum{
+ IDX_1811_MCST_STORM_SET_NBLOCK_IP_PKT,
+ IDX_1811_MCST_STORM_GET_NBLOCK_IP_PKT,
+ IDX_1811_MCST_STORM_SET_IGNORE_01005EXXXXXX,
+ IDX_1811_MCST_STORM_GET_IGNORE_01005EXXXXXX,
+ NUM_1811_STORM
+};
+#define ID_1811_STORM(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_BASIC, _CMDID_SUBG_STORM, idx)
+#define ID_1811_MCST_STORM_SET_NBLOCK_IP_PKT \
+ ID_1811_STORM(IDX_1811_MCST_STORM_SET_NBLOCK_IP_PKT)
+#define ID_1811_MCST_STORM_GET_NBLOCK_IP_PKT \
+ ID_1811_STORM(IDX_1811_MCST_STORM_GET_NBLOCK_IP_PKT)
+#define ID_1811_MCST_STORM_SET_IGNORE_01005EXXXXXX \
+ ID_1811_STORM(IDX_1811_MCST_STORM_SET_IGNORE_01005EXXXXXX)
+#define ID_1811_MCST_STORM_GET_IGNORE_01005EXXXXXX \
+ ID_1811_STORM(IDX_1811_MCST_STORM_GET_IGNORE_01005EXXXXXX)
+
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_EOC 0x6
+#define ID_COMMON_EOC_SET_FUNC \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_BASIC, _CMDID_SUBG_EOC, 0)
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_LD 0x7
+enum{
+ IDX_COMMON_LOOP_DETECT_SET_FUNC,
+ IDX_COMMON_LOOP_DETECT_GET_FUNC,
+ IDX_COMMON_LOOP_DETECT_SET_TIME_UNIT,
+ IDX_COMMON_LOOP_DETECT_GET_TIME_UNIT,
+ IDX_COMMON_LOOP_DETECT_SET_PKT_SEND_TIMER,
+ IDX_COMMON_LOOP_DETECT_GET_PKT_SEND_TIMER,
+ IDX_COMMON_LOOP_DETECT_SET_BLOCK_RELEASE_TIMER,
+ IDX_COMMON_LOOP_DETECT_GET_BLOCK_RELEASE_TIMER,
+ IDX_COMMON_LOOP_DETECT_GET_STATUS,
+ NUM_COMMON_LOOP_DETECT
+};
+#define ID_COMMON_LOOP_DETECT(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_BASIC, _CMDID_SUBG_LD, idx)
+#define ID_COMMON_LOOP_DETECT_SET_FUNC \
+ ID_COMMON_LOOP_DETECT(IDX_COMMON_LOOP_DETECT_SET_FUNC)
+#define ID_COMMON_LOOP_DETECT_GET_FUNC \
+ ID_COMMON_LOOP_DETECT(IDX_COMMON_LOOP_DETECT_GET_FUNC)
+#define ID_COMMON_LOOP_DETECT_SET_TIME_UNIT \
+ ID_COMMON_LOOP_DETECT(IDX_COMMON_LOOP_DETECT_SET_TIME_UNIT)
+#define ID_COMMON_LOOP_DETECT_GET_TIME_UNIT \
+ ID_COMMON_LOOP_DETECT(IDX_COMMON_LOOP_DETECT_GET_TIME_UNIT)
+#define ID_COMMON_LOOP_DETECT_SET_PKT_SEND_TIMER \
+ ID_COMMON_LOOP_DETECT(IDX_COMMON_LOOP_DETECT_SET_PKT_SEND_TIMER)
+#define ID_COMMON_LOOP_DETECT_GET_PKT_SEND_TIMER \
+ ID_COMMON_LOOP_DETECT(IDX_COMMON_LOOP_DETECT_GET_PKT_SEND_TIMER)
+#define ID_COMMON_LOOP_DETECT_SET_BLOCK_RELEASE_TIMER \
+ ID_COMMON_LOOP_DETECT(IDX_COMMON_LOOP_DETECT_SET_BLOCK_RELEASE_TIMER)
+#define ID_COMMON_LOOP_DETECT_GET_BLOCK_RELEASE_TIMER \
+ ID_COMMON_LOOP_DETECT(IDX_COMMON_LOOP_DETECT_GET_BLOCK_RELEASE_TIMER)
+#define ID_COMMON_LOOP_DETECT_GET_STATUS \
+ ID_COMMON_LOOP_DETECT(IDX_COMMON_LOOP_DETECT_GET_STATUS)
+
+enum{
+ IDX_1811_LOOP_DETECT_SET_DMAC,
+ IDX_1811_LOOP_DETECT_SET_SUB_TYPE,
+ NUM_1811_LOOP_DETECT
+};
+#define ID_1811_LOOP_DETECT(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_BASIC, _CMDID_SUBG_LD, idx)
+#define ID_1811_LOOP_DETECT_SET_DMAC \
+ ID_1811_LOOP_DETECT(IDX_1811_LOOP_DETECT_SET_DMAC)
+#define ID_1811_LOOP_DETECT_SET_SUB_TYPE \
+ ID_1811_LOOP_DETECT(IDX_1811_LOOP_DETECT_SET_SUB_TYPE)
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_WOL 0x8
+#define ID_COMMON_WOL_SET_FUNC \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_BASIC, _CMDID_SUBG_WOL, 0)
+#define ID_COMMON_WOL_GET_FUNC \
+#define ID_1811_WOL_SET_WAKE_IF_TX_GET_ANY_PKT \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_BASIC, _CMDID_SUBG_WOL, 0)
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_STAG 0x9
+enum{
+ IDX_COMMON_SET_CPU_PORT_LINK,
+ IDX_COMMON_STAG_SET_FUNC,
+ IDX_COMMON_STAG_GET_TYPE_LENGTH,
+ IDX_COMMON_CONFIG_CPU_PORT,
+ NUM_COMMON_STAG
+};
+#define ID_COMMON_STAG(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_BASIC, _CMDID_SUBG_STAG, idx)
+#define ID_COMMON_SET_CPU_PORT_LINK \
+ ID_COMMON_STAG(IDX_COMMON_SET_CPU_PORT_LINK)
+#define ID_COMMON_STAG_SET_FUNC \
+ ID_COMMON_STAG(IDX_COMMON_STAG_SET_FUNC)
+#define ID_COMMON_STAG_GET_TYPE_LENGTH \
+ ID_COMMON_STAG(IDX_COMMON_STAG_GET_TYPE_LENGTH )
+#define ID_COMMON_CONFIG_CPU_PORT\
+ ID_COMMON_STAG(IDX_COMMON_CONFIG_CPU_PORT)
+
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_IGMP 0xA
+enum{
+ IDX_1811_IGMP_SET_SNOOPING_FUNCTION,
+ IDX_1811_IGMP_GET_SNOOPING_FUNCTION,
+ IDX_1811_IGMP_SET_MCT_BY_CPU,
+ IDX_1811_IGMP_GET_MCT_BY_CPU,
+ IDX_1811_IGMP_SET_ROUTER_LIST_MAKE_BY_CPU,
+ IDX_1811_IGMP_GET_ROUTER_LIST_MAKE_BY_CPU,
+ IDX_1811_IGMP_SET_PACKET_FORWARD_RULE,
+ IDX_1811_IGMP_GET_PACKET_FORWARD_RULE,
+ IDX_1811_IGMP_SET_ROUTER_LIST,
+ IDX_1811_IGMP_GET_ROUTER_LIST,
+ IDX_1811_IGMP_SET_HASHING_METHOD,
+ IDX_1811_IGMP_GET_HASHING_METHOD,
+ IDX_1811_MLD_SET_FORWARD_RULE,
+ IDX_1811_MLD_GET_FORWARD_RULE,
+ IDX_1811_MT_SET_RULE,
+ IDX_1811_MT_GET_RULE,
+ IDX_1811_SLT_SET_RULE,
+ IDX_1811_SLT_GET_RULE,
+ NUM_1811_IGMP
+};
+
+#define ID_1811_IGMP(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_BASIC, _CMDID_SUBG_IGMP, idx)
+
+#define ID_1811_IGMP_SET_SNOOPING_FUNCTION \
+ ID_1811_IGMP(IDX_1811_IGMP_SET_SNOOPING_FUNCTION)
+#define ID_1811_IGMP_GET_SNOOPING_FUNCTION \
+ ID_1811_IGMP(IDX_1811_IGMP_GET_SNOOPING_FUNCTION)
+#define ID_1811_IGMP_SET_MCT_BY_CPU \
+ ID_1811_IGMP(IDX_1811_IGMP_SET_MCT_BY_CPU)
+#define ID_1811_IGMP_GET_MCT_BY_CPU \
+ ID_1811_IGMP(IDX_1811_IGMP_GET_MCT_BY_CPU)
+#define ID_1811_IGMP_SET_ROUTER_LIST_MAKE_BY_CPU \
+ ID_1811_IGMP(IDX_1811_IGMP_SET_ROUTER_LIST_MAKE_BY_CPU)
+#define ID_1811_IGMP_GET_ROUTER_LIST_MAKE_BY_CPU \
+ ID_1811_IGMP(IDX_1811_IGMP_GET_ROUTER_LIST_MAKE_BY_CPU)
+#define ID_1811_IGMP_SET_PACKET_FORWARD_RULE \
+ ID_1811_IGMP(IDX_1811_IGMP_SET_PACKET_FORWARD_RULE)
+#define ID_1811_IGMP_GET_PACKET_FORWARD_RULE \
+ ID_1811_IGMP(IDX_1811_IGMP_GET_PACKET_FORWARD_RULE)
+#define ID_1811_IGMP_SET_ROUTER_LIST \
+ ID_1811_IGMP(IDX_1811_IGMP_SET_ROUTER_LIST)
+#define ID_1811_IGMP_GET_ROUTER_LIST \
+ ID_1811_IGMP(IDX_1811_IGMP_GET_ROUTER_LIST)
+#define ID_1811_IGMP_SET_HASHING_METHOD \
+ ID_1811_IGMP(IDX_1811_IGMP_SET_HASHING_METHOD)
+#define ID_1811_IGMP_GET_HASHING_METHOD \
+ ID_1811_IGMP(IDX_1811_IGMP_GET_HASHING_METHOD)
+#define ID_1811_MLD_SET_FORWARD_RULE \
+ ID_1811_IGMP(IDX_1811_MLD_SET_FORWARD_RULE)
+#define ID_1811_MLD_GET_FORWARD_RULE \
+ ID_1811_IGMP(IDX_1811_MLD_GET_FORWARD_RULE)
+#define ID_1811_MT_SET_RULE \
+ ID_1811_IGMP(IDX_1811_MT_SET_RULE)
+#define ID_1811_MT_GET_RULE \
+ ID_1811_IGMP(IDX_1811_MT_GET_RULE)
+#define ID_1811_SLT_SET_RULE \
+ ID_1811_IGMP(IDX_1811_SLT_SET_RULE)
+#define ID_1811_SLT_GET_RULE \
+ ID_1811_IGMP(IDX_1811_SLT_GET_RULE)
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_PTP 0xB
+
+enum{
+ IDX_1811_PTP_SET_ENABLE,
+ IDX_1811_PTP_GET_ENABLE,
+ IDX_1811_PTP_SET_DA_011B19000000,
+ IDX_1811_PTP_GET_DA_011B19000000,
+ IDX_1811_PTP_SET_DA_0180C200000E,
+ IDX_1811_PTP_GET_DA_0180C200000E,
+ IDX_1811_PTP_SET_UDP_DP,
+ IDX_1811_PTP_GET_UDP_DP,
+ IDX_1811_PTP_SET_UDP_SP,
+ IDX_1811_PTP_GET_UDP_SP,
+ IDX_1811_PTP_SET_TO_CPU,
+ IDX_1811_PTP_GET_TO_CPU,
+ IDX_1811_PTP_SET_SPECIAL_TAG,
+ IDX_1811_PTP_GET_SPECIAL_TAG,
+ IDX_1811_PTP_SET_CLOCK_RESET,
+ IDX_1811_PTP_GET_TIMESTAMP,
+ IDX_1811_PTP_SET_CLOCK_ENABLE,
+ IDX_1811_PTP_GET_CLOCK_ENABLE,
+ IDX_1811_PTP_SET_OVERWRITE_ENABLE,
+ IDX_1811_PTP_GET_OVERWRITE_ENABLE,
+ IDX_1811_PTP_SET_PROGRAMMABLE,
+ IDX_1811_PTP_GET_PROGRAMMABLE,
+ IDX_1811_PTP_SET_PROGRAMMABLE_OUTPUT,
+ IDX_1811_PTP_SET_TIMESTAMP_ENABLE,
+ IDX_1811_PTP_GET_TIMESTAMP_ENABLE,
+ IDX_1811_PTP_SET_TIMESTAMP_CLEAR,
+ IDX_1811_PTP_SET_TIMEDATA,
+ IDX_1811_PTP_GET_TIMEDATA,
+ IDX_1811_PTP_ADD_TIMEDATA,
+ IDX_1811_PTP_SUB_TIMEDATA,
+ IDX_1811_PTP_SET_FREQUENCY_ADD,
+ IDX_1811_PTP_GET_FREQUENCY_ADD,
+ IDX_1811_PTP_SET_CLOCK_PERIOD,
+ IDX_1811_PTP_GET_CLOCK_PERIOD,
+ IDX_1811_PTP_SET_PROGRAMMABLE_CONFIG,
+ IDX_1811_PTP_SET_DURATION_FREQUENCY_COMPENSATION,
+ IDX_1811_PTP_SET_ALWAYS_FREQUENCY_COMPENSATION,
+ IDX_1811_PTP_GET_INGRESS_LATENCY_10,
+ IDX_1811_PTP_GET_INGRESS_LATENCY_100,
+ IDX_1811_PTP_GET_INGRESS_LATENCY_FIBER,
+ IDX_1811_PTP_GET_EGRESS_LATENCY_10,
+ IDX_1811_PTP_GET_EGRESS_LATENCY_100,
+ IDX_1811_PTP_GET_EGRESS_LATENCY_FIBER,
+ NUM_1811_PTP
+};
+
+#define ID_1811_PTP(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_BASIC, _CMDID_SUBG_PTP, idx)
+
+#define ID_1811_PTP_SET_ENABLE \
+ ID_1811_PTP(IDX_1811_PTP_SET_ENABLE)
+#define ID_1811_PTP_GET_ENABLE \
+ ID_1811_PTP(IDX_1811_PTP_GET_ENABLE)
+#define ID_1811_PTP_SET_DA_011B19000000 \
+ ID_1811_PTP(IDX_1811_PTP_SET_DA_011B19000000)
+#define ID_1811_PTP_GET_DA_011B19000000 \
+ ID_1811_PTP(IDX_1811_PTP_GET_DA_011B19000000)
+#define ID_1811_PTP_SET_DA_0180C200000E \
+ ID_1811_PTP(IDX_1811_PTP_SET_DA_0180C200000E)
+#define ID_1811_PTP_GET_DA_0180C200000E \
+ ID_1811_PTP(IDX_1811_PTP_GET_DA_0180C200000E)
+#define ID_1811_PTP_SET_UDP_DP \
+ ID_1811_PTP(IDX_1811_PTP_SET_UDP_DP)
+#define ID_1811_PTP_GET_UDP_DP \
+ ID_1811_PTP(IDX_1811_PTP_GET_UDP_DP)
+#define ID_1811_PTP_SET_UDP_SP \
+ ID_1811_PTP(IDX_1811_PTP_SET_UDP_SP)
+#define ID_1811_PTP_GET_UDP_SP \
+ ID_1811_PTP(IDX_1811_PTP_GET_UDP_SP)
+#define ID_1811_PTP_SET_TO_CPU \
+ ID_1811_PTP(IDX_1811_PTP_SET_TO_CPU)
+#define ID_1811_PTP_GET_TO_CPU \
+ ID_1811_PTP(IDX_1811_PTP_GET_TO_CPU)
+#define ID_1811_PTP_SET_SPECIAL_TAG \
+ ID_1811_PTP(IDX_1811_PTP_SET_SPECIAL_TAG)
+#define ID_1811_PTP_GET_SPECIAL_TAG \
+ ID_1811_PTP(IDX_1811_PTP_GET_SPECIAL_TAG)
+#define ID_1811_PTP_SET_CLOCK_RESET \
+ ID_1811_PTP(IDX_1811_PTP_SET_CLOCK_RESET)
+#define ID_1811_PTP_GET_TIMESTAMP \
+ ID_1811_PTP(IDX_1811_PTP_GET_TIMESTAMP)
+#define ID_1811_PTP_SET_CLOCK_ENABLE \
+ ID_1811_PTP(IDX_1811_PTP_SET_CLOCK_ENABLE)
+#define ID_1811_PTP_GET_CLOCK_ENABLE \
+ ID_1811_PTP(IDX_1811_PTP_GET_CLOCK_ENABLE)
+#define ID_1811_PTP_SET_OVERWRITE_ENABLE \
+ ID_1811_PTP(IDX_1811_PTP_SET_OVERWRITE_ENABLE)
+#define ID_1811_PTP_GET_OVERWRITE_ENABLE \
+ ID_1811_PTP(IDX_1811_PTP_GET_OVERWRITE_ENABLE)
+#define ID_1811_PTP_SET_PROGRAMMABLE \
+ ID_1811_PTP(IDX_1811_PTP_SET_PROGRAMMABLE)
+#define ID_1811_PTP_GET_PROGRAMMABLE \
+ ID_1811_PTP(IDX_1811_PTP_GET_PROGRAMMABLE)
+#define ID_1811_PTP_SET_PROGRAMMABLE_OUTPUT \
+ ID_1811_PTP(IDX_1811_PTP_SET_PROGRAMMABLE_OUTPUT)
+#define ID_1811_PTP_SET_TIMESTAMP_ENABLE \
+ ID_1811_PTP(IDX_1811_PTP_SET_TIMESTAMP_ENABLE)
+#define ID_1811_PTP_GET_TIMESTAMP_ENABLE \
+ ID_1811_PTP(IDX_1811_PTP_GET_TIMESTAMP_ENABLE)
+#define ID_1811_PTP_SET_TIMESTAMP_CLEAR \
+ ID_1811_PTP(IDX_1811_PTP_SET_TIMESTAMP_CLEAR)
+#define ID_1811_PTP_SET_TIMEDATA \
+ ID_1811_PTP(IDX_1811_PTP_SET_TIMEDATA)
+#define ID_1811_PTP_GET_TIMEDATA \
+ ID_1811_PTP(IDX_1811_PTP_GET_TIMEDATA)
+#define ID_1811_PTP_ADD_TIMEDATA \
+ ID_1811_PTP(IDX_1811_PTP_ADD_TIMEDATA)
+#define ID_1811_PTP_SUB_TIMEDATA \
+ ID_1811_PTP(IDX_1811_PTP_SUB_TIMEDATA)
+#define ID_1811_PTP_SET_FREQUENCY_ADD \
+ ID_1811_PTP(IDX_1811_PTP_SET_FREQUENCY_ADD)
+#define ID_1811_PTP_GET_FREQUENCY_ADD \
+ ID_1811_PTP(IDX_1811_PTP_GET_FREQUENCY_ADD)
+#define ID_1811_PTP_SET_CLOCK_PERIOD \
+ ID_1811_PTP(IDX_1811_PTP_SET_CLOCK_PERIOD)
+#define ID_1811_PTP_GET_CLOCK_PERIOD \
+ ID_1811_PTP(IDX_1811_PTP_GET_CLOCK_PERIOD)
+#define ID_1811_PTP_SET_PROGRAMMABLE_CONFIG \
+ ID_1811_PTP(IDX_1811_PTP_SET_PROGRAMMABLE_CONFIG)
+#define ID_1811_PTP_SET_DURATION_FREQUENCY_COMPENSATION \
+ ID_1811_PTP(IDX_1811_PTP_SET_DURATION_FREQUENCY_COMPENSATION)
+#define ID_1811_PTP_SET_ALWAYS_FREQUENCY_COMPENSATION \
+ ID_1811_PTP(IDX_1811_PTP_SET_ALWAYS_FREQUENCY_COMPENSATION)
+#define ID_1811_PTP_GET_INGRESS_LATENCY_10 \
+ ID_1811_PTP(IDX_1811_PTP_GET_INGRESS_LATENCY_10)
+#define ID_1811_PTP_GET_INGRESS_LATENCY_100 \
+ ID_1811_PTP(IDX_1811_PTP_GET_INGRESS_LATENCY_100)
+#define ID_1811_PTP_GET_INGRESS_LATENCY_FIBER \
+ ID_1811_PTP(IDX_1811_PTP_GET_INGRESS_LATENCY_FIBER)
+#define ID_1811_PTP_GET_EGRESS_LATENCY_10 \
+ ID_1811_PTP(IDX_1811_PTP_GET_EGRESS_LATENCY_10)
+#define ID_1811_PTP_GET_EGRESS_LATENCY_100 \
+ ID_1811_PTP(IDX_1811_PTP_GET_EGRESS_LATENCY_100)
+#define ID_1811_PTP_GET_EGRESS_LATENCY_FIBER \
+ ID_1811_PTP(IDX_1811_PTP_GET_EGRESS_LATENCY_FIBER)
+
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUB_BANDWIDTH 0xC
+#define RATE_SCALE_UNIT 64000
+enum{
+ IDX_COMMON_BANDWIDTH_SET_INGRESS_RATE,
+ IDX_COMMON_BANDWIDTH_GET_INGRESS_RATE,
+ IDX_COMMON_BANDWIDTH_SET_EGRESS_RATE,
+ IDX_COMMON_BANDWIDTH_GET_EGRESS_RATE,
+ IDX_COMMON_BANDWIDTH_SET_EGRESS_PERIOD,
+ IDX_COMMON_BANDWIDTH_GET_EGRESS_PERIOD,
+ NUM_COMMON_BANDWIDTH
+};
+#define ID_COMMON_BANDWIDTH(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_BASIC, _CMDID_SUB_BANDWIDTH, idx)
+
+#define ID_COMMON_BANDWIDTH_SET_INGRESS_RATE \
+ ID_COMMON_BANDWIDTH(IDX_COMMON_BANDWIDTH_SET_INGRESS_RATE)
+#define ID_COMMON_BANDWIDTH_GET_INGRESS_RATE \
+ ID_COMMON_BANDWIDTH(IDX_COMMON_BANDWIDTH_GET_INGRESS_RATE)
+#define ID_COMMON_BANDWIDTH_SET_EGRESS_RATE \
+ ID_COMMON_BANDWIDTH(IDX_COMMON_BANDWIDTH_SET_EGRESS_RATE)
+#define ID_COMMON_BANDWIDTH_GET_EGRESS_RATE \
+ ID_COMMON_BANDWIDTH(IDX_COMMON_BANDWIDTH_GET_EGRESS_RATE)
+#define ID_COMMON_BANDWIDTH_SET_EGRESS_PERIOD \
+ ID_COMMON_BANDWIDTH(IDX_COMMON_BANDWIDTH_SET_EGRESS_PERIOD)
+#define ID_COMMON_BANDWIDTH_GET_EGRESS_PERIOD \
+ ID_COMMON_BANDWIDTH(IDX_COMMON_BANDWIDTH_GET_EGRESS_PERIOD)
+
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_MISC 0xF
+enum{
+ IDX_COMMON_8021X_PORT_LOCK_SET_FUNC,
+ IDX_COMMON_8021X_PORT_LOCK_GET_FUNC,
+ IDX_COMMON_MISC_SET_REG,
+ IDX_COMMON_MISC_GET_REG,
+ IDX_COMMON_MISC_SET_CPU_REG,
+ IDX_COMMON_MISC_GET_CPU_REG,
+ IDX_COMMON_MISC_SET_SWITCH_RESTART,
+ IDX_COMMON_MISC_SET_SWITCH_RESET,
+ IDX_COMMON_MISC_SET_CPU_IF_SPEED,
+ IDX_COMMON_MISC_SET_EEPROM_BYTE,
+ IDX_COMMON_MISC_GET_EEPROM_BYTE,
+ NUM_COMMON_MISC
+};
+#define ID_COMMON_MISC(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_BASIC, _CMDID_SUBG_MISC, idx)
+
+#define ID_COMMON_8021X_PORT_LOCK_SET_FUNC \
+ ID_COMMON_MISC(IDX_COMMON_8021X_PORT_LOCK_SET_FUNC)
+#define ID_COMMON_8021X_PORT_LOCK_GET_FUNC \
+ ID_COMMON_MISC(IDX_COMMON_8021X_PORT_LOCK_GET_FUNC)
+#define ID_COMMON_MISC_SET_REG \
+ ID_COMMON_MISC(IDX_COMMON_MISC_SET_REG)
+#define ID_COMMON_MISC_GET_REG \
+ ID_COMMON_MISC(IDX_COMMON_MISC_GET_REG)
+#define ID_COMMON_MISC_SET_CPU_REG \
+ ID_COMMON_MISC(IDX_COMMON_MISC_SET_CPU_REG)
+#define ID_COMMON_MISC_GET_CPU_REG \
+ ID_COMMON_MISC(IDX_COMMON_MISC_GET_CPU_REG)
+#define ID_COMMON_MISC_SET_SWITCH_RESTART \
+ ID_COMMON_MISC(IDX_COMMON_MISC_SET_SWITCH_RESTART)
+#define ID_COMMON_MISC_SET_SWITCH_RESET\
+ ID_COMMON_MISC(IDX_COMMON_MISC_SET_SWITCH_RESET)
+#define ID_COMMON_MISC_SET_CPU_IF_SPEED\
+ ID_COMMON_MISC(IDX_COMMON_MISC_SET_CPU_IF_SPEED)
+#define ID_COMMON_MISC_SET_EEPROM_BYTE\
+ ID_COMMON_MISC(IDX_COMMON_MISC_SET_EEPROM_BYTE)
+#define ID_COMMON_MISC_GET_EEPROM_BYTE\
+ ID_COMMON_MISC(IDX_COMMON_MISC_GET_EEPROM_BYTE)
+
+#if 0
+#define ID_1811_MAC_LOOP_BACK_SET_FUNC \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_BASIC, _CMDID_SUBG_MISC, 0)
+#endif
+/*===================================================================*/
+#define _CMDID_GRP_VLAN 0x02
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_VLAN 0x1
+
+enum{
+ IDX_COMMON_VLAN_SET_EGRESS_FRAME, //0
+ IDX_COMMON_VLAN_GET_EGRESS_FRAME,
+ IDX_COMMON_VLAN_SET_TAGGING,
+ IDX_COMMON_VLAN_SET_TYPE,
+ IDX_COMMON_VLAN_SET_GROUP,
+ IDX_COMMON_VLAN_SET_QINQ_TYPE, //5
+ IDX_COMMON_VLAN_SET_QINQ_P_ADDTAG,
+ IDX_COMMON_VLAN_GET_QINQ_P_ADDTAG,
+ IDX_COMMON_VLAN_SET_QINQ_P_RMVTAG,
+ IDX_COMMON_VLAN_GET_QINQ_P_RMVTAG,
+ IDX_COMMON_VLAN_SET_QINQ_P_RXDET, //10
+ IDX_COMMON_VLAN_GET_QINQ_P_RXDET,
+ IDX_COMMON_VLAN_SET_QINQ_P_KEEP,
+ IDX_COMMON_VLAN_GET_QINQ_P_KEEP,
+ IDX_COMMON_VLAN_SET_QINQ_P_INDEX,
+ IDX_COMMON_VLAN_GET_QINQ_P_INDEX, //15
+ IDX_COMMON_VLAN_SET_QINQ_INDEX,
+ IDX_COMMON_VLAN_SET_QINQ_STAG_SELECT_METHOD,
+ IDX_COMMON_VLAN_SET_PORT_ADDTAG,
+ IDX_COMMON_VLAN_GET_PORT_ADDTAG,
+ IDX_COMMON_VLAN_SET_PORT_RMVTAG, //20
+ IDX_COMMON_VLAN_GET_PORT_RMVTAG,
+ IDX_COMMON_VLAN_SET_PORT_FORCE,
+ IDX_COMMON_VLAN_GET_PORT_FORCE,
+ IDX_COMMON_VLAN_SET_PORT_UPLINK,
+ IDX_COMMON_VLAN_GET_PORT_UPLINK, //25
+ IDX_COMMON_VLAN_SET_PORT_EXCLUSIVE,
+ IDX_COMMON_VLAN_GET_PORT_EXCLUSIVE,
+ IDX_COMMON_VLAN_SET_PORT_EGRESS,
+ IDX_COMMON_VLAN_GET_PORT_EGRESS,
+ IDX_COMMON_VLAN_SET_PORT_INGRESS_FRAME, //30
+ IDX_COMMON_VLAN_SET_PORT_INGRESS_CHECK,
+ IDX_COMMON_VLAN_GET_PORT_INGRESS_CHECK,
+ IDX_COMMON_VLAN_SET_PORT_VID,
+ IDX_COMMON_VLAN_SET_PROTOCOL_MODE,
+ IDX_COMMON_VLAN_SET_PROTOCOL_VID, //35
+ IDX_COMMON_VLAN_SET_PROTOCOL_TYPE,
+ IDX_COMMON_VLAN_CLEAR_PROTOCOL,
+ IDX_COMMON_VLAN_SET_MAC_VLAN,
+ IDX_COMMON_VLAN_SET_MAC_VLAN_VLANTABLE_CONFIG,
+ IDX_COMMON_VLAN_GET_MAC_VLAN_VLANTABLE_CONFIG, //40
+ IDX_COMMON_VLAN_SET_MAC_VLAN_UNKNOWN,
+ NUM_COMMON_VLAN
+};
+
+#define ID_COMMON_VLAN(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_VLAN, _CMDID_SUBG_VLAN, idx)
+
+#define ID_COMMON_VLAN_SET_EGRESS_FRAME \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_EGRESS_FRAME)
+#define ID_COMMON_VLAN_GET_EGRESS_FRAME \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_EGRESS_FRAME)
+#define ID_COMMON_VLAN_SET_TAGGING \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_TAGGING)
+#define ID_COMMON_VLAN_SET_TYPE \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_TYPE)
+#define ID_COMMON_VLAN_SET_GROUP \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_GROUP)
+
+#define ID_COMMON_VLAN_SET_QINQ_TYPE \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_QINQ_TYPE)
+#define ID_COMMON_VLAN_SET_QINQ_P_ADDTAG \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_QINQ_P_ADDTAG)
+#define ID_COMMON_VLAN_GET_QINQ_P_ADDTAG \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_QINQ_P_ADDTAG)
+#define ID_COMMON_VLAN_SET_QINQ_P_RMVTAG \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_QINQ_P_RMVTAG)
+#define ID_COMMON_VLAN_GET_QINQ_P_RMVTAG \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_QINQ_P_RMVTAG)
+#define ID_COMMON_VLAN_SET_QINQ_P_RXDET \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_QINQ_P_RXDET)
+#define ID_COMMON_VLAN_GET_QINQ_P_RXDET \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_QINQ_P_RXDET)
+#define ID_COMMON_VLAN_SET_QINQ_P_KEEP \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_QINQ_P_KEEP)
+#define ID_COMMON_VLAN_GET_QINQ_P_KEEP \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_QINQ_P_KEEP)
+#define ID_COMMON_VLAN_SET_QINQ_P_INDEX \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_QINQ_P_INDEX)
+#define ID_COMMON_VLAN_GET_QINQ_P_INDEX \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_QINQ_P_INDEX)
+#define ID_COMMON_VLAN_SET_QINQ_INDEX \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_QINQ_INDEX)
+#define ID_COMMON_VLAN_SET_QINQ_STAG_SELECT_METHOD \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_QINQ_STAG_SELECT_METHOD)
+
+#define ID_COMMON_VLAN_SET_PORT_ADDTAG \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PORT_ADDTAG)
+#define ID_COMMON_VLAN_GET_PORT_ADDTAG \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_PORT_ADDTAG)
+#define ID_COMMON_VLAN_SET_PORT_RMVTAG \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PORT_RMVTAG)
+#define ID_COMMON_VLAN_GET_PORT_RMVTAG \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_PORT_RMVTAG)
+#define ID_COMMON_VLAN_SET_PORT_FORCE \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PORT_FORCE)
+#define ID_COMMON_VLAN_GET_PORT_FORCE \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_PORT_FORCE)
+#define ID_COMMON_VLAN_SET_PORT_UPLINK \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PORT_UPLINK)
+#define ID_COMMON_VLAN_GET_PORT_UPLINK \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_PORT_UPLINK)
+#define ID_COMMON_VLAN_SET_PORT_EXCLUSIVE \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PORT_EXCLUSIVE)
+#define ID_COMMON_VLAN_GET_PORT_EXCLUSIVE \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_PORT_EXCLUSIVE)
+#define ID_COMMON_VLAN_SET_PORT_EGRESS \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PORT_EGRESS)
+#define ID_COMMON_VLAN_GET_PORT_EGRESS \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_PORT_EGRESS)
+#define ID_COMMON_VLAN_SET_PORT_INGRESS_FRAME \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PORT_INGRESS_FRAME)
+#define ID_COMMON_VLAN_SET_PORT_INGRESS_CHECK \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PORT_INGRESS_CHECK)
+#define ID_COMMON_VLAN_GET_PORT_INGRESS_CHECK \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_PORT_INGRESS_CHECK)
+#define ID_COMMON_VLAN_SET_PORT_VID \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PORT_VID)
+
+#define ID_COMMON_VLAN_SET_PROTOCOL_MODE \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PROTOCOL_MODE)
+#define ID_COMMON_VLAN_SET_PROTOCOL_VID \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PROTOCOL_VID)
+#define ID_COMMON_VLAN_SET_PROTOCOL_TYPE \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_PROTOCOL_TYPE)
+#define ID_COMMON_VLAN_CLEAR_PROTOCOL \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_CLEAR_PROTOCOL)
+#define ID_COMMON_VLAN_SET_MAC_VLAN \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_MAC_VLAN)
+#define ID_COMMON_VLAN_SET_MAC_VLAN_VLANTABLE_CONFIG \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_MAC_VLAN_VLANTABLE_CONFIG)
+#define ID_COMMON_VLAN_GET_MAC_VLAN_VLANTABLE_CONFIG \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_GET_MAC_VLAN_VLANTABLE_CONFIG)
+#define ID_COMMON_VLAN_SET_MAC_VLAN_UNKNOWN \
+ ID_COMMON_VLAN(IDX_COMMON_VLAN_SET_MAC_VLAN_UNKNOWN)
+
+enum{
+ IDX_IP1811_VLAN_SET_ENTRY_MEMBER, //0
+ IDX_IP1811_VLAN_SET_ENTRY_ADDTAG,
+ IDX_IP1811_VLAN_SET_ENTRY_RMVTAG,
+ IDX_IP1811_VLAN_SET_ENTRY_PRIORITY,
+ IDX_IP1811_VLAN_SET_ENTRY_FID,
+ IDX_IP1811_VLAN_GET_ENTRY_FID, //5
+ IDX_IP1811_VLAN_DELETE_ENTRY,
+ NUM_IP1811_VLAN
+};
+
+#define ID_IP1811_VLAN(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_VLAN, _CMDID_SUBG_VLAN, idx)
+
+#define ID_IP1811_VLAN_SET_ENTRY_MEMBER \
+ ID_IP1811_VLAN(IDX_IP1811_VLAN_SET_ENTRY_MEMBER)
+#define ID_IP1811_VLAN_SET_ENTRY_ADDTAG \
+ ID_IP1811_VLAN(IDX_IP1811_VLAN_SET_ENTRY_ADDTAG)
+#define ID_IP1811_VLAN_SET_ENTRY_RMVTAG \
+ ID_IP1811_VLAN(IDX_IP1811_VLAN_SET_ENTRY_RMVTAG)
+#define ID_IP1811_VLAN_SET_ENTRY_PRIORITY \
+ ID_IP1811_VLAN(IDX_IP1811_VLAN_SET_ENTRY_PRIORITY)
+#define ID_IP1811_VLAN_SET_ENTRY_FID \
+ ID_IP1811_VLAN(IDX_IP1811_VLAN_SET_ENTRY_FID)
+#define ID_IP1811_VLAN_GET_ENTRY_FID \
+ ID_IP1811_VLAN(IDX_IP1811_VLAN_GET_ENTRY_FID)
+#define ID_IP1811_VLAN_DELETE_ENTRY \
+ ID_IP1811_VLAN(IDX_IP1811_VLAN_DELETE_ENTRY)
+
+/*===================================================================*/
+#define _CMDID_GRP_QOS 0x03
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUB_QOS 0x1
+enum{
+ IDX_IP1811_SET_QOS_AGING_FUNCTION,
+ IDX_IP1811_GET_QOS_AGING_FUNCTION,
+ IDX_IP1811_SET_QOS_AGING_TIME,
+ IDX_IP1811_GET_QOS_AGING_TIME,
+ IDX_IP1811_SET_QOS_FASTAGING,
+ IDX_IP1811_GET_QOS_FASTAGING,
+
+ IDX_IP1811_SET_COS_IGMP,
+ IDX_IP1811_GET_COS_IGMP,
+ IDX_IP1811_SET_COS_MACADDRESS,
+ IDX_IP1811_GET_COS_MACADDRESS,
+ IDX_IP1811_SET_COS_VID,
+ IDX_IP1811_GET_COS_VID,
+ IDX_IP1811_SET_COS_TCPUDPPORT,
+ IDX_IP1811_GET_COS_TCPUDPPORT,
+ IDX_IP1811_SET_COS_DSCP,
+ IDX_IP1811_GET_COS_DSCP,
+ IDX_IP1811_SET_COS_8021P,
+ IDX_IP1811_GET_COS_8021P,
+ IDX_IP1811_SET_COS_PHYSICALPORT,
+ IDX_IP1811_GET_COS_PHYSICALPORT,
+ IDX_IP1811_SET_COS_PORT_QUEUE,
+ IDX_IP1811_GET_COS_PORT_QUEUE,
+ IDX_IP1811_SET_COS_8021PEDTION,
+ IDX_IP1811_GET_COS_8021PEDTION,
+ IDX_IP1811_SET_COS_DSCPBASE_DSCP,
+ IDX_IP1811_GET_COS_DSCPBASE_DSCP,
+ IDX_IP1811_SET_COS_DSCPBASE_NOMATCHACTION,
+ IDX_IP1811_GET_COS_DSCPBASE_NOMATCHACTION,
+
+ IDX_IP1811_SET_QOSMODE_GROUP_MEMEBER,
+ IDX_IP1811_GET_QOSMODE_GROUP_MEMEBER,
+ IDX_IP1811_SET_QOSGROUPB_EN,
+ IDX_IP1811_GET_QOSGROUPB_EN,
+ IDX_IP1811_SET_QOS_MODE,
+ IDX_IP1811_GET_QOS_MODE,
+ IDX_IP1811_SET_QOS_METHOD,
+ IDX_IP1811_GET_QOS_METHOD,
+ IDX_IP1811_SET_QOS_WEIGHT,
+ IDX_IP1811_GET_QOS_WEIGHT,
+ IDX_IP1811_SET_QOS_MAXBANDWIDTH,
+ IDX_IP1811_GET_QOS_MAXBANDWIDTH,
+ IDX_IP1811_SET_QOS_UNIT,
+ IDX_IP1811_GET_QOS_UNIT,
+ IDX_IP1811_SET_QOS_RATIOVALUE0_DEF,
+ IDX_IP1811_GET_QOS_RATIOVALUE0_DEF,
+ IDX_IP1811_SET_QOS_SBM_DBM,
+ IDX_IP1811_GET_QOS_SBM_DBM,
+ IDX_IP1811_SET_QOS_DBM_EN,
+ IDX_IP1811_GET_QOS_DBM_EN,
+
+ IDX_IP1811_SET_QOS_REMAP,
+ IDX_IP1811_GET_QOS_REMAP,
+ NUM_IP1811_QOS
+};
+#define ID_IP1811_QOS(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_QOS, _CMDID_SUB_QOS, idx)
+
+#define ID_IP1811_SET_QOS_AGING_FUNCTION \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_AGING_FUNCTION)
+#define ID_IP1811_GET_QOS_AGING_FUNCTION \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_AGING_FUNCTION)
+#define ID_IP1811_SET_QOS_AGING_TIME \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_AGING_TIME)
+#define ID_IP1811_GET_QOS_AGING_TIME \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_AGING_TIME)
+#define ID_IP1811_SET_QOS_FASTAGING \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_FASTAGING)
+#define ID_IP1811_GET_QOS_FASTAGING \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_FASTAGING)
+
+#define ID_IP1811_SET_COS_IGMP \
+ ID_IP1811_QOS(IDX_IP1811_SET_COS_IGMP)
+#define ID_IP1811_GET_COS_IGMP \
+ ID_IP1811_QOS(IDX_IP1811_GET_COS_IGMP)
+#define ID_IP1811_SET_COS_MACADDRESS \
+ ID_IP1811_QOS(IDX_IP1811_SET_COS_MACADDRESS)
+#define ID_IP1811_GET_COS_MACADDRESS \
+ ID_IP1811_QOS(IDX_IP1811_GET_COS_MACADDRESS)
+#define ID_IP1811_SET_COS_VID \
+ ID_IP1811_QOS(IDX_IP1811_SET_COS_VID)
+#define ID_IP1811_GET_COS_VID \
+ ID_IP1811_QOS(IDX_IP1811_GET_COS_VID)
+#define ID_IP1811_SET_COS_TCPUDPPORT \
+ ID_IP1811_QOS(IDX_IP1811_SET_COS_TCPUDPPORT)
+#define ID_IP1811_GET_COS_TCPUDPPORT \
+ ID_IP1811_QOS(IDX_IP1811_GET_COS_TCPUDPPORT)
+#define ID_IP1811_SET_COS_DSCP \
+ ID_IP1811_QOS(IDX_IP1811_SET_COS_DSCP)
+#define ID_IP1811_GET_COS_DSCP \
+ ID_IP1811_QOS(IDX_IP1811_GET_COS_DSCP)
+#define ID_IP1811_SET_COS_8021P \
+ ID_IP1811_QOS(IDX_IP1811_SET_COS_8021P)
+#define ID_IP1811_GET_COS_8021P \
+ ID_IP1811_QOS(IDX_IP1811_GET_COS_8021P)
+#define ID_IP1811_SET_COS_PHYSICALPORT \
+ ID_IP1811_QOS(IDX_IP1811_SET_COS_PHYSICALPORT)
+#define ID_IP1811_GET_COS_PHYSICALPORT \
+ ID_IP1811_QOS(IDX_IP1811_GET_COS_PHYSICALPORT)
+#define ID_IP1811_SET_COS_PORT_QUEUE \
+ ID_IP1811_QOS(IDX_IP1811_SET_COS_PORT_QUEUE)
+#define ID_IP1811_GET_COS_PORT_QUEUE \
+ ID_IP1811_QOS(IDX_IP1811_GET_COS_PORT_QUEUE)
+#define ID_IP1811_SET_COS_8021PEDTION \
+ ID_IP1811_QOS(IDX_IP1811_SET_COS_8021PEDTION)
+#define ID_IP1811_GET_COS_8021PEDTION \
+ ID_IP1811_QOS(IDX_IP1811_GET_COS_8021PEDTION)
+#define ID_IP1811_SET_COS_DSCPBASE_DSCP \
+ ID_IP1811_QOS(IDX_IP1811_SET_COS_DSCPBASE_DSCP)
+#define ID_IP1811_GET_COS_DSCPBASE_DSCP \
+ ID_IP1811_QOS(IDX_IP1811_GET_COS_DSCPBASE_DSCP)
+#define ID_IP1811_SET_COS_DSCPBASE_NOMATCHACTION \
+ ID_IP1811_QOS(IDX_IP1811_SET_COS_DSCPBASE_NOMATCHACTION)
+#define ID_IP1811_GET_COS_DSCPBASE_NOMATCHACTION \
+ ID_IP1811_QOS(IDX_IP1811_GET_COS_DSCPBASE_NOMATCHACTION)
+
+#define ID_IP1811_SET_QOSMODE_GROUP_MEMEBER \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOSMODE_GROUP_MEMEBER)
+#define ID_IP1811_GET_QOSMODE_GROUP_MEMEBER \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOSMODE_GROUP_MEMEBER)
+#define ID_IP1811_SET_QOSGROUPB_EN \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOSGROUPB_EN)
+#define ID_IP1811_GET_QOSGROUPB_EN \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOSGROUPB_EN)
+#define ID_IP1811_SET_QOS_MODE \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_MODE)
+#define ID_IP1811_GET_QOS_MODE \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_MODE)
+#define ID_IP1811_SET_QOS_METHOD \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_METHOD)
+#define ID_IP1811_GET_QOS_METHOD \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_METHOD)
+#define ID_IP1811_SET_QOS_WEIGHT \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_WEIGHT)
+#define ID_IP1811_GET_QOS_WEIGHT \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_WEIGHT)
+#define ID_IP1811_SET_QOS_MAXBANDWIDTH \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_MAXBANDWIDTH)
+#define ID_IP1811_GET_QOS_MAXBANDWIDTH \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_MAXBANDWIDTH)
+#define ID_IP1811_SET_QOS_UNIT \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_UNIT)
+#define ID_IP1811_GET_QOS_UNIT \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_UNIT)
+#define ID_IP1811_SET_QOS_RATIOVALUE0_DEF \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_RATIOVALUE0_DEF)
+#define ID_IP1811_GET_QOS_RATIOVALUE0_DEF \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_RATIOVALUE0_DEF)
+#define ID_IP1811_SET_QOS_SBM_DBM \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_SBM_DBM)
+#define ID_IP1811_GET_QOS_SBM_DBM \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_SBM_DBM)
+#define ID_IP1811_SET_QOS_DBM_EN \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_DBM_EN)
+#define ID_IP1811_GET_QOS_DBM_EN \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_DBM_EN)
+
+#define ID_IP1811_SET_QOS_REMAP \
+ ID_IP1811_QOS(IDX_IP1811_SET_QOS_REMAP)
+#define ID_IP1811_GET_QOS_REMAP \
+ ID_IP1811_QOS(IDX_IP1811_GET_QOS_REMAP)
+/*===================================================================*/
+#define _CMDID_GRP_ACL 0x04
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_ACL 0x01
+enum{
+ IDX_IP1811_ACL_SET_RULE,
+ IDX_IP1811_ACL_GET_RULE,
+ IDX_IP1811_ACL_CLEAN_TABLE,
+ IDX_IP1811_ACL_SET_FUNCTION_EN,
+ IDX_IP1811_ACL_GET_FUNCTION_EN,
+ IDX_IP1811_ACL_SET_ETHER_AFTER_TAG,
+ IDX_IP1811_ACL_GET_ETHER_AFTER_TAG,
+ IDX_IP1811_ACL_GET_USED_RULES,
+ IDX_IP1811_ACL_GET_USED_ENTRIES,
+ IDX_IP1811_ACL_GET_USED_ENTRY_MASK,
+ IDX_IP1811_ACL_SET_BW,
+ IDX_IP1811_ACL_GET_BW,
+ IDX_IP1811_ACL_SET_DSCP,
+ IDX_IP1811_ACL_GET_DSCP,
+ IDX_IP1811_ACL_SET_VID_REMARK,
+ IDX_IP1811_ACL_GET_VID_REMARK,
+ IDX_IP1811_ACL_SET_STORM_PERIOD,
+ IDX_IP1811_ACL_GET_STORM_PERIOD,
+ IDX_IP1811_ACL_SET_STORM,
+ IDX_IP1811_ACL_GET_STORM,
+ NUM_IP1811_ACL
+};
+#define ID_IP1811_ACL(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_ACL, _CMDID_SUBG_ACL, idx)
+#define ID_1811_ACL_SET_RULE \
+ ID_IP1811_ACL(IDX_IP1811_ACL_SET_RULE)
+#define ID_1811_ACL_GET_RULE \
+ ID_IP1811_ACL(IDX_IP1811_ACL_GET_RULE)
+#define ID_1811_ACL_CLEAN_TABLE \
+ ID_IP1811_ACL(IDX_IP1811_ACL_CLEAN_TABLE)
+#define ID_1811_ACL_SET_FUNCTION_EN \
+ ID_IP1811_ACL(IDX_IP1811_ACL_SET_FUNCTION_EN)
+#define ID_1811_ACL_GET_FUNCTION_EN \
+ ID_IP1811_ACL(IDX_IP1811_ACL_GET_FUNCTION_EN)
+#define ID_1811_ACL_SET_ETHER_AFTER_TAG \
+ ID_IP1811_ACL(IDX_IP1811_ACL_SET_ETHER_AFTER_TAG)
+#define ID_1811_ACL_GET_ETHER_AFTER_TAG \
+ ID_IP1811_ACL(IDX_IP1811_ACL_GET_ETHER_AFTER_TAG)
+#define ID_1811_ACL_GET_USED_RULES \
+ ID_IP1811_ACL(IDX_IP1811_ACL_GET_USED_RULES)
+#define ID_1811_ACL_GET_USED_ENTRIES \
+ ID_IP1811_ACL(IDX_IP1811_ACL_GET_USED_ENTRIES)
+#define ID_1811_ACL_GET_USED_ENTRY_MASK \
+ ID_IP1811_ACL(IDX_IP1811_ACL_GET_USED_ENTRY_MASK)
+#define ID_1811_ACL_SET_BW \
+ ID_IP1811_ACL(IDX_IP1811_ACL_SET_BW)
+#define ID_1811_ACL_GET_BW \
+ ID_IP1811_ACL(IDX_IP1811_ACL_GET_BW)
+#define ID_1811_ACL_SET_DSCP \
+ ID_IP1811_ACL(IDX_IP1811_ACL_SET_DSCP)
+#define ID_1811_ACL_GET_DSCP \
+ ID_IP1811_ACL(IDX_IP1811_ACL_GET_DSCP)
+#define ID_1811_ACL_SET_VID_REMARK \
+ ID_IP1811_ACL(IDX_IP1811_ACL_SET_VID_REMARK)
+#define ID_1811_ACL_GET_VID_REMARK \
+ ID_IP1811_ACL(IDX_IP1811_ACL_GET_VID_REMARK)
+#define ID_1811_ACL_SET_STORM_PERIOD \
+ ID_IP1811_ACL(IDX_IP1811_ACL_SET_STORM_PERIOD)
+#define ID_1811_ACL_GET_STORM_PERIOD \
+ ID_IP1811_ACL(IDX_IP1811_ACL_GET_STORM_PERIOD)
+#define ID_1811_ACL_SET_STORM \
+ ID_IP1811_ACL(IDX_IP1811_ACL_SET_STORM)
+#define ID_1811_ACL_GET_STORM \
+ ID_IP1811_ACL(IDX_IP1811_ACL_GET_STORM)
+
+/*===================================================================*/
+#define _CMDID_GRP_SEC 0x05
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_IMP 0x01
+#define ID_COMMON_SET_IMP_MODE \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_SEC, _CMDID_SUBG_IMP, 0)
+
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_COS 0x2
+enum{
+ IDX_COMMON_TCPUDP_SET_USER_DEFINE,
+ IDX_COMMON_TCPUDP_GET_USER_DEFINE,
+ IDX_COMMON_TCPUDP_SET_QUEUE,
+ IDX_COMMON_TCPUDP_GET_QUEUE,
+ IDX_COMMON_TCPUDP_SET_ENABLE,
+ IDX_COMMON_TCPUDP_GET_ENABLE,
+ IDX_COMMON_TCPUDP_SET_TCP_ENABLE,
+ IDX_COMMON_TCPUDP_GET_TCP_ENABLE,
+ IDX_COMMON_TCPUDP_SET_UDP_ENABLE,
+ IDX_COMMON_TCPUDP_GET_UDP_ENABLE,
+ IDX_COMMON_TCPFLAG_SET_DROP_NULL,
+ IDX_COMMON_TCPFLAG_GET_DROP_NULL,
+ IDX_COMMON_TCPFLAG_SET_DROP_ALLSET,
+ IDX_COMMON_TCPFLAG_GET_DROP_ALLSET,
+ IDX_COMMON_TCPFLAG_SET_FLAG,
+ IDX_COMMON_TCPFLAG_GET_FLAG,
+ IDX_COMMON_TCPFLAG_SET_ACTION,
+ IDX_COMMON_TCPFLAG_GET_ACTION,
+ IDX_COMMON_TCPFLAG_SET_PORT,
+ IDX_COMMON_TCPFLAG_GET_PORT,
+ NUM_COMMON_TCPUDP
+};
+#define ID_COMMON_COS(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_SEC, _CMDID_SUBG_COS, idx)
+
+#define ID_COMMON_TCPUDP_SET_USER_DEFINE \
+ ID_COMMON_COS(IDX_COMMON_TCPUDP_SET_USER_DEFINE)
+#define ID_COMMON_TCPUDP_GET_USER_DEFINE \
+ ID_COMMON_COS(IDX_COMMON_TCPUDP_GET_USER_DEFINE)
+#define ID_COMMON_TCPUDP_SET_QUEUE \
+ ID_COMMON_COS(IDX_COMMON_TCPUDP_SET_QUEUE)
+#define ID_COMMON_TCPUDP_GET_QUEUE \
+ ID_COMMON_COS(IDX_COMMON_TCPUDP_GET_QUEUE)
+#define ID_COMMON_TCPUDP_SET_ENABLE \
+ ID_COMMON_COS(IDX_COMMON_TCPUDP_SET_ENABLE)
+#define ID_COMMON_TCPUDP_GET_ENABLE \
+ ID_COMMON_COS(IDX_COMMON_TCPUDP_GET_ENABLE)
+#define ID_COMMON_TCPUDP_SET_TCP_ENABLE \
+ ID_COMMON_COS(IDX_COMMON_TCPUDP_SET_TCP_ENABLE)
+#define ID_COMMON_TCPUDP_GET_TCP_ENABLE \
+ ID_COMMON_COS(IDX_COMMON_TCPUDP_GET_TCP_ENABLE)
+#define ID_COMMON_TCPUDP_SET_UDP_ENABLE \
+ ID_COMMON_COS(IDX_COMMON_TCPUDP_SET_UDP_ENABLE)
+#define ID_COMMON_TCPUDP_GET_UDP_ENABLE \
+ ID_COMMON_COS(IDX_COMMON_TCPUDP_GET_UDP_ENABLE)
+#define ID_COMMON_TCPFLAG_SET_DROP_NULL \
+ ID_COMMON_COS(IDX_COMMON_TCPFLAG_SET_DROP_NULL)
+#define ID_COMMON_TCPFLAG_GET_DROP_NULL \
+ ID_COMMON_COS(IDX_COMMON_TCPFLAG_GET_DROP_NULL)
+#define ID_COMMON_TCPFLAG_SET_DROP_ALLSET \
+ ID_COMMON_COS(IDX_COMMON_TCPFLAG_SET_DROP_ALLSET)
+#define ID_COMMON_TCPFLAG_GET_DROP_ALLSET \
+ ID_COMMON_COS(IDX_COMMON_TCPFLAG_GET_DROP_ALLSET)
+#define ID_COMMON_TCPFLAG_SET_FLAG \
+ ID_COMMON_COS(IDX_COMMON_TCPFLAG_SET_FLAG)
+#define ID_COMMON_TCPFLAG_GET_FLAG \
+ ID_COMMON_COS(IDX_COMMON_TCPFLAG_GET_FLAG)
+#define ID_COMMON_TCPFLAG_SET_ACTION \
+ ID_COMMON_COS(IDX_COMMON_TCPFLAG_SET_ACTION)
+#define ID_COMMON_TCPFLAG_GET_ACTION \
+ ID_COMMON_COS(IDX_COMMON_TCPFLAG_GET_ACTION)
+#define ID_COMMON_TCPFLAG_SET_PORT \
+ ID_COMMON_COS(IDX_COMMON_TCPFLAG_SET_PORT)
+#define ID_COMMON_TCPFLAG_GET_PORT \
+ ID_COMMON_COS(IDX_COMMON_TCPFLAG_GET_PORT)
+
+/*===================================================================*/
+#define _CMDID_GRP_ADV 0x06
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_STP 0x1
+enum{
+ IDX_COMMON_MSTP_SET_FUNC,
+ IDX_COMMON_MSTP_GET_FUNC,
+ NUM_COMMON_STP
+};
+#define ID_COMMON_STP(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_ADV, _CMDID_SUBG_STP, idx)
+
+#define ID_COMMON_MSTP_SET_FUNC \
+ ID_COMMON_STP(IDX_COMMON_MSTP_SET_FUNC)
+#define ID_COMMON_MSTP_GET_FUNC \
+ ID_COMMON_STP(IDX_COMMON_MSTP_GET_FUNC)
+
+enum{
+ IDX_1811_BPDU_SET_CAP_MODE,
+ IDX_1811_BPDU_GET_CAP_MODE,
+ IDX_1811_BPDU_SET_PORT_ACT,
+ IDX_1811_BPDU_GET_PORT_ACT,
+ IDX_1811_STP_SET_PORT_STATE,
+ IDX_1811_STP_GET_PORT_STATE,
+ NUM_1811_STP
+};
+#define ID_1811_STP(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_ADV, _CMDID_SUBG_STP, idx)
+
+#define ID_1811_BPDU_SET_CAP_MODE \
+ ID_1811_STP(IDX_1811_BPDU_SET_CAP_MODE)
+#define ID_1811_BPDU_GET_CAP_MODE \
+ ID_1811_STP(IDX_1811_BPDU_GET_CAP_MODE)
+#define ID_1811_BPDU_SET_PORT_ACT \
+ ID_1811_STP(IDX_1811_BPDU_SET_PORT_ACT)
+#define ID_1811_BPDU_GET_PORT_ACT \
+ ID_1811_STP(IDX_1811_BPDU_GET_PORT_ACT)
+#define ID_1811_STP_SET_PORT_STATE \
+ ID_1811_STP(IDX_1811_STP_SET_PORT_STATE)
+#define ID_1811_STP_GET_PORT_STATE \
+ ID_1811_STP(IDX_1811_STP_GET_PORT_STATE)
+
+
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_LACP 0x2
+enum{
+ IDX_COMMON_TRUNK_SET_HASH_METHOD,
+ IDX_COMMON_TRUNK_GET_HASH_METHOD,
+ IDX_COMMON_TRUNK_SET_MEMBER,
+ IDX_COMMON_TRUNK_GET_MEMBER,
+ IDX_COMMON_CPU_SET_NOT_CARE_TRUNK_AND_VLAN,
+ IDX_COMMON_CPU_GET_NOT_CARE_TRUNK_AND_VLAN,
+ NUM_COMMON_LACP
+};
+#define ID_COMMON_LACP(idx) \
+ MAKECMDID(_CMDID_USG_COMMON, _CMDID_GRP_ADV, _CMDID_SUBG_LACP, idx)
+
+#define ID_COMMON_TRUNK_SET_HASH_METHOD \
+ ID_COMMON_LACP(IDX_COMMON_TRUNK_SET_HASH_METHOD)
+#define ID_COMMON_TRUNK_GET_HASH_METHOD \
+ ID_COMMON_LACP(IDX_COMMON_TRUNK_GET_HASH_METHOD)
+#define ID_COMMON_TRUNK_SET_MEMBER \
+ ID_COMMON_LACP(IDX_COMMON_TRUNK_SET_MEMBER)
+#define ID_COMMON_TRUNK_GET_MEMBER \
+ ID_COMMON_LACP(IDX_COMMON_TRUNK_GET_MEMBER)
+#define ID_COMMON_CPU_SET_NOT_CARE_TRUNK_AND_VLAN \
+ ID_COMMON_LACP(IDX_COMMON_CPU_SET_NOT_CARE_TRUNK_AND_VLAN)
+#define ID_COMMON_CPU_GET_NOT_CARE_TRUNK_AND_VLAN \
+ ID_COMMON_LACP(IDX_COMMON_CPU_GET_NOT_CARE_TRUNK_AND_VLAN)
+
+enum{
+ IPX_1811_TRUNK_SET_HASH_METHOD_SEQ,
+ IPX_1811_TRUNK_GET_HASH_METHOD_SEQ,
+ IPX_1811_TRUNK_SET_GROUP_COMBINE,
+ IPX_1811_TRUNK_GET_GROUP_COMBINE,
+ NUM_1811_LACP
+};
+#define ID_1811_LACP(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_ADV, _CMDID_SUBG_LACP, idx)
+
+#define IP_1811_TRUNK_SET_HASH_METHOD_SEQ \
+ ID_1811_LACP(IPX_1811_TRUNK_SET_HASH_METHOD_SEQ)
+#define IP_1811_TRUNK_GET_HASH_METHOD_SEQ \
+ ID_1811_LACP(IPX_1811_TRUNK_GET_HASH_METHOD_SEQ)
+#define IP_1811_TRUNK_SET_GROUP_COMBINE \
+ ID_1811_LACP(IPX_1811_TRUNK_SET_GROUP_COMBINE)
+#define IP_1811_TRUNK_GET_GROUP_COMBINE \
+ ID_1811_LACP(IPX_1811_TRUNK_GET_GROUP_COMBINE)
+
+/*===================================================================*/
+#define _CMDID_GRP_MON 0x07
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_MIB_COUNTER 0x1
+enum{
+ IDX_1811_SET_MIB_COUNTER_ENABLE,
+ IDX_1811_GET_MIB_COUNTER_ENABLE,
+ IDX_1811_GET_MIB_COUNTER_ALL,
+ IDX_1811_GET_MIB_COUNTER_BY_PORT,
+ IDX_1811_GET_MIB_COUNTER_BY_ITEM,
+ NUM_1811_MIB_COUNTER
+};
+#define ID_COMMON_MIB_COUNTER(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_MON, _CMDID_SUBG_MIB_COUNTER, idx)
+
+#define ID_1811_SET_MIB_COUNTER_ENABLE \
+ ID_COMMON_MIB_COUNTER(IDX_1811_SET_MIB_COUNTER_ENABLE)
+#define ID_1811_GET_MIB_COUNTER_ENABLE \
+ ID_COMMON_MIB_COUNTER(IDX_1811_GET_MIB_COUNTER_ENABLE)
+#define ID_1811_GET_MIB_COUNTER_ALL \
+ ID_COMMON_MIB_COUNTER(IDX_1811_GET_MIB_COUNTER_ALL)
+#define ID_1811_GET_MIB_COUNTER_BY_PORT \
+ ID_COMMON_MIB_COUNTER(IDX_1811_GET_MIB_COUNTER_BY_PORT)
+#define ID_1811_GET_MIB_COUNTER_BY_ITEM \
+ ID_COMMON_MIB_COUNTER(IDX_1811_GET_MIB_COUNTER_BY_ITEM)
+
+/*===================================================================*/
+#define _CMDID_GRP_HSR 0x08
+/*-------------------------------------------------------------------*/
+#define _CMDID_SUBG_HSR 0x1
+enum{
+ IDX_1811_SET_HSR_ENABLE,
+ IDX_1811_GET_HSR_ENABLE,
+ IDX_1811_SET_HSR_MODE,
+ IDX_1811_GET_HSR_MODE,
+ NUM_IP1811_HSR
+};
+#define ID_COMMON_HSR(idx) \
+ MAKECMDID(_CMDID_USG_IP1811, _CMDID_GRP_HSR, _CMDID_SUBG_HSR, idx)
+
+#define ID_1811_SET_HSR_ENABLE \
+ ID_COMMON_HSR(IDX_1811_SET_HSR_ENABLE)
+#define ID_1811_GET_HSR_ENABLE \
+ ID_COMMON_HSR(IDX_1811_GET_HSR_ENABLE)
+#define ID_1811_SET_HSR_MODE \
+ ID_COMMON_HSR(IDX_1811_SET_HSR_MODE)
+#define ID_1811_GET_HSR_MODE \
+ ID_COMMON_HSR(IDX_1811_GET_HSR_MODE)
+
+#endif /* IP1811_H */
diff --git a/kernel/drivers/net/ethernet/ip1811/ip1811ds.h b/kernel/drivers/net/ethernet/ip1811/ip1811ds.h
new file mode 100644
index 0000000..50e52b8
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/ip1811ds.h
@@ -0,0 +1,746 @@
+#ifndef IP1811DS_H
+#define IP1811DS_H
+
+#include "ip1811.h"
+#include "include/list.h"
+
+/*typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned long u32;*/
+
+struct GeneralSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int gdata;
+};
+
+struct PortMemberSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned long member;
+};
+
+struct ByPortSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int port;
+ int pdata;
+};
+
+struct ByPortSetting32
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int port;
+ unsigned long pdata;
+};
+
+struct AllPortsSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int apdata[MAX_PHY_NUM];
+};
+
+struct PortmapSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned long portmap;
+ int pmdata;
+};
+
+struct PortMaskSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned long portmap;
+ int mask;
+};
+
+/*--------------- Special Data Structures for PTP ---------------*/
+struct PTPReadSetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned char addr; //0-15
+ char in_out; //1:egress, 0:ingress
+ int port; //1-12
+ unsigned long long second;
+ unsigned long nanosecond;
+};
+
+struct PTPPortTSSetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned long portmap;
+ char in_out; //1:egress, 0:ingress
+ char pmdata; //set:OP_FUNC_ENABLE/DISABLE
+ //get:always enable
+};
+
+struct PTPTimeSetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned long long second;
+ unsigned long nanosecond;
+};
+
+struct PTPFrequencySetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ char type; //1:add 0:sub
+ unsigned long frequency;
+ unsigned long clockcycle;
+ unsigned long period_time; //nanosecond
+};
+
+struct PTPFrequencyPPMSetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ char type; //1:add 0:sub
+ unsigned long ppm_h;
+ unsigned long ppm_l;
+};
+/*--------------- Special Data Structures for SMI ---------------*/
+struct LinkStatusSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int port;
+ unsigned int link;
+ unsigned int speed;
+ unsigned int duplex;
+ unsigned int pause;
+ unsigned int asym;
+ unsigned int an;
+ unsigned int fiber;
+};
+
+/*--------------- Special Data Structures for L2 Protocol ---------------*/
+struct CapActSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned int protocol;
+ int act;
+};
+
+/*--------------- Special Data Structures for Storm ---------------*/
+struct StormGeneralSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned char storm;
+ long sdata;
+};
+
+/*--------------- Special Data Structures for Loop Detect ---------------*/
+struct LDDASetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned char da[6];
+};
+
+/*--------------- Special Data Structures for Special Tag ---------------*/
+struct STagTypeLenSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned int length;
+ unsigned int type;
+};
+
+/*--------------- Special Data Structures for MISC ---------------*/
+struct RegSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned char page;
+ unsigned char reg;
+ unsigned short val;
+};
+/*--------------- Special Data Structures for MISC PHY ---------------*/
+struct PhySetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned char phy;
+ unsigned char page;
+ unsigned char reg;
+ unsigned short val;
+ unsigned char all;
+};
+
+/*--------------- Special Data Structures for STP ---------------*/
+struct StpByFPSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int fid;
+ int port;
+ int pstate;
+};
+
+struct StpAllPortsSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int fid;
+ int pstate[MAX_PHY_NUM-1];
+};
+
+/*--------------- Special Data Structures for LACP ---------------*/
+struct TrunkMemberSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned long portmask;
+ unsigned long tstate;
+};
+
+struct TrunkCombineSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned long tgrps;
+ int cen;
+};
+
+/*--------------- Special Data Structures for LUT ---------------*/
+struct IP1811LUTEntry
+{
+ unsigned char cfg;
+ unsigned char mac[6];
+ unsigned char fid;
+ unsigned char srcport;
+ unsigned char aging;
+ unsigned char priority;
+ struct{
+ unsigned short drop: 1;
+ unsigned short snif: 1;
+ unsigned short sflow: 1;
+ unsigned short reserve: 13;
+ }flag;
+};
+
+struct IP1811LUTSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned long retval;
+ unsigned char action;
+ unsigned long tarports;
+ unsigned short index;
+ unsigned char block;
+ struct IP1811LUTEntry entry;
+ unsigned short data[6];
+};
+
+struct IP1811LUTReg
+{
+ unsigned short data[6];
+ unsigned char block;
+ struct list_head list;
+};
+
+/*--------------- Special Data Structures for IGMP ---------------*/
+
+struct mt_rule{
+ unsigned char group[4];
+ unsigned char fid;
+ unsigned long port_mem;
+ unsigned char pri;
+ unsigned char slt_index;
+ unsigned char flag;
+};
+
+struct MtRuleSetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int index;
+ struct mt_rule mt_data;
+};
+
+struct slt_rule{
+ unsigned char type; //4:ipv4, 6:ipv6, define in ip1811op.h
+ union slt_para{
+ struct slt_ipv4{
+ unsigned char ip[6][4];
+ unsigned int used_port[6];
+ }ipv4;
+
+ struct slt_ipv6{
+ unsigned short ip[2][8];
+ unsigned int used_port[2];
+ }ipv6;
+ }data;
+ unsigned int port_filter_mode;
+};
+
+struct SltRuleSetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int index;
+ struct slt_rule slt_data;
+};
+
+struct IgmpPacketRule{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned int packet_type;
+ unsigned int rule;
+};
+
+struct IgmpRouterListSetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned int portmask;
+ unsigned int tstate;
+};
+
+/*--------------- Special Data Structures for IMP ---------------*/
+struct IP1811IMPEntry
+{
+ unsigned char ip[16];
+ unsigned char mac[6];
+ unsigned char srcport;
+ unsigned char priority;
+ struct{
+ unsigned int valid: 1;
+ unsigned int ip_type: 1;
+ unsigned int check_ip: 1;
+ unsigned int check_mac: 1;
+ unsigned int check_port: 1;
+ unsigned int filter: 1;
+ unsigned int sniff2: 1;
+ unsigned int reserved: 9;
+ }flag;
+};
+
+struct IP1811IMPSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned long retval;
+ unsigned char action;
+ unsigned char index;
+ struct IP1811IMPEntry entry;
+};
+
+/*--------------- Special Data Structures for VLAN ---------------*/
+struct VlanSetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned int vtype;
+ unsigned int vdata;
+};
+
+struct MACVlanSetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned int index;
+ unsigned int mvdata;
+};
+
+/*--------------- Special Data Structures for MAC ---------------*/
+struct MACSetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ char mac[6];
+};
+
+/*--------------- Special Data Structures for TCP Flag ---------------*/
+struct TcpFlagSetting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned int index;
+ int fdata;
+};
+
+/*--------------- Special Data Structures for IPv6 ---------------*/
+struct IPv6Setting{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned int header;
+ int act;
+};
+
+/*--------------- Special Data Structures for MIB Counter ---------------*/
+#define NUM_MIB_COUNTER_RX 24
+#define NUM_MIB_COUNTER_TX 20
+
+struct MIBCounterData{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int port;
+ int dir;
+ int idx;
+ unsigned long counter;
+};
+
+struct MIBCounterEntry{
+ unsigned long RX_counter[NUM_MIB_COUNTER_RX];
+ unsigned long TX_counter[NUM_MIB_COUNTER_TX];
+};
+
+struct MIBCounterEntry_all{
+ struct MIBCounterEntry entry[MAX_PHY_NUM];
+};
+
+/*--------------- Special Data Structures for QOS ---------------*/
+struct qos_dscp_setting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned char dscpentry;
+ unsigned char dscpvalue;
+ unsigned char dscpqueue;
+};
+
+struct qos_modesettings
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int groupnum;
+ int queuenum;
+ int modesettings;
+};
+
+struct qos_remap
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int port;
+ unsigned char queue;
+ unsigned char remap;
+};
+/*--------------- Special Data Structures for ACL ---------------*/
+struct acl_man {
+ struct list_head rule_list;
+
+ int num_used_rules;
+ int num_used_entries;
+
+ // IP1811 has 64 entries
+ unsigned short used_entry_mask[4];
+};
+
+#define ACL_RULE_FUNC_USED_ACL BIT(0)
+#define ACL_RULE_FUNC_USED_MCP BIT(1)
+#define ACL_RULE_FUNC_USED_SNOOP BIT(2)
+#define ACL_RULE_FUNC_USED_DOS BIT(3)
+
+struct acl_man_rule {
+ struct list_head rule_entry;
+ int start_block;
+ int start_index;
+ int num_entries;
+ int rule_index;
+ unsigned int func_used; // bit 0 : acl
+ // bit 1 : mcp
+ // bit 2 : dhcp snooping
+};
+
+enum {
+ ACL_SELECT_MODE_0001 = 1,
+ ACL_SELECT_MODE_0010,
+ ACL_SELECT_MODE_0100 = 4,
+ ACL_SELECT_MODE_0101,
+ ACL_SELECT_MODE_0110,
+ ACL_SELECT_MODE_0111,
+ ACL_SELECT_MODE_1x00,
+ ACL_SELECT_MODE_1x01,
+ ACL_SELECT_MODE_1x10,
+ ACL_SELECT_MODE_1x11,
+};
+#define ACL_SELECT_MODE_BIT_0010 BIT(ACL_SELECT_MODE_0010)
+#define ACL_SELECT_MODE_BIT_0100 BIT(ACL_SELECT_MODE_0100)
+#define ACL_SELECT_MODE_BIT_0101 BIT(ACL_SELECT_MODE_0101)
+#define ACL_SELECT_MODE_BIT_0110 BIT(ACL_SELECT_MODE_0110)
+#define ACL_SELECT_MODE_BIT_0111 BIT(ACL_SELECT_MODE_0111)
+#define ACL_SELECT_MODE_BIT_1x00 BIT(ACL_SELECT_MODE_1x00)
+#define ACL_SELECT_MODE_BIT_1x01 BIT(ACL_SELECT_MODE_1x01)
+#define ACL_SELECT_MODE_BIT_1x10 BIT(ACL_SELECT_MODE_1x10)
+#define ACL_SELECT_MODE_BIT_1x11 BIT(ACL_SELECT_MODE_1x11)
+enum {
+ ACL_LINK_TYPE_00 = 0,
+ ACL_LINK_TYPE_01,
+ ACL_LINK_TYPE_10,
+ ACL_LINK_TYPE_11,
+};
+
+#define ACL_RULE_VALID_SMAC BIT(0)
+#define ACL_RULE_VALID_DMAC BIT(1)
+#define ACL_RULE_VALID_SIP BIT(2)
+#define ACL_RULE_VALID_SIP_MASK BIT(3)
+#define ACL_RULE_VALID_DIP BIT(4)
+#define ACL_RULE_VALID_DIP_MASK BIT(5)
+#define ACL_RULE_VALID_SIP6 BIT(6)
+#define ACL_RULE_VALID_SIP6_MASK BIT(7)
+#define ACL_RULE_VALID_DIP6 BIT(8)
+#define ACL_RULE_VALID_DIP6_MASK BIT(9)
+#define ACL_RULE_VALID_ETH_TYPE BIT(10)
+#define ACL_RULE_VALID_VLAN BIT(11)
+#define ACL_RULE_VALID_COS BIT(12)
+#define ACL_RULE_VALID_SP_R BIT(13)
+#define ACL_RULE_VALID_DP_R BIT(14)
+#define ACL_RULE_VALID_DSCP BIT(15)
+#define ACL_RULE_VALID_IP_PROT BIT(16)
+#define ACL_RULE_VALID_INGRESS_PORT BIT(17)
+#define ACL_RULE_VALID_USERDEF_OFFSET BIT(18)
+
+#define ACL_RULE_RVS_SMAC BIT(0)
+#define ACL_RULE_RVS_DMAC BIT(1)
+#define ACL_RULE_RVS_SIP BIT(2)
+#define ACL_RULE_RVS_SIP_MASK BIT(3)
+#define ACL_RULE_RVS_DIP BIT(4)
+#define ACL_RULE_RVS_DIP_MASK BIT(5)
+#define ACL_RULE_RVS_SIP6 BIT(6)
+#define ACL_RULE_RVS_SIP6_MASK BIT(7)
+#define ACL_RULE_RVS_DIP6 BIT(8)
+#define ACL_RULE_RVS_DIP6_MASK BIT(9)
+#define ACL_RULE_RVS_ETH_TYPE BIT(10)
+#define ACL_RULE_RVS_VLAN BIT(11)
+#define ACL_RULE_RVS_COS BIT(12)
+#define ACL_RULE_RVS_SP_R BIT(13)
+#define ACL_RULE_RVS_DP_R BIT(14)
+#define ACL_RULE_RVS_DSCP BIT(15)
+#define ACL_RULE_RVS_IP_PROT BIT(16)
+#define ACL_RULE_RVS_INGRESS_PORT BIT(17)
+#define ACL_RULE_RVS_USERDEF_OFFSET BIT(18)
+
+#define ACL_ACT_VALID_REDIR BIT(0)
+#define ACL_ACT_VALID_PRI BIT(1)
+#define ACL_ACT_VALID_DSCP BIT(2)
+#define ACL_ACT_VALID_CPU BIT(3)
+#define ACL_ACT_VALID_SNIFFER BIT(4)
+#define ACL_ACT_VALID_PTP BIT(5)
+#define ACL_ACT_VALID_SFLOW BIT(6)
+#define ACL_ACT_VALID_CTAG BIT(7)
+#define ACL_ACT_VALID_STAG BIT(8)
+#define ACL_ACT_VALID_BW BIT(9)
+#define ACL_ACT_VALID_STORM BIT(10)
+#define ACL_ACT_VALID_MIB_COUNTER BIT(11)
+
+#define ACL_ACT_TYPE_3 3
+
+struct acl_rule
+{
+ // rule
+ unsigned long rule_valid; // bit 0 : smac
+ // bit 1 : dmac
+ // bit 2 : sip
+ // bit 3 : sip_mask
+ // bit 4 : dip
+ // bit 5 : dip_mask
+ // bit 6 : sip6
+ // bit 7 : sip6_mask
+ // bit 8 : dip6
+ // bit 9 : dip6_mask
+ // bit 10: eth_type
+ // bit 11: vlan
+ // bit 12: cos
+ // bit 13: sp_range
+ // bit 14: dp_range
+ // bit 15: dscp
+ // bit 16: ip_prot
+ // bit 17: ingress_port
+ // reverse
+ unsigned long rule_rvs; // bit 0 : smac
+ // bit 1 : dmac
+ // bit 2 : sip
+ // bit 3 : sip_mask
+ // bit 4 : dip
+ // bit 5 : dip_mask
+ // bit 6 : sip6
+ // bit 7 : sip6_mask
+ // bit 8 : dip6
+ // bit 9 : dip6_mask
+ // bit 10: eth_type
+ // bit 11: vlan
+ // bit 12: cos
+ // bit 13: sp_range
+ // bit 14: dp_range
+ // bit 15: dscp
+ // bit 16: ip_prot
+ // bit 17: ingress_port
+
+ unsigned char smac[6];
+ unsigned char dmac[6];
+
+ union{
+ unsigned long sip4;
+ unsigned short sip6[8];
+ }sip;
+#define sip4_addr sip.sip4
+#define sip6_addr16 sip.sip6
+ unsigned char sip_mask;
+ // IPv4 0 - FF:FF:FF:FF IPv6 0 - FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF(0x00)
+ // 1 - FF:FF:FF:00 1 - FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:0000:0000(0x3C)
+ // 2 - FF:FF:00:00 2 - FFFF:FFFF:FFFF:FFFF:0000:0000:0000:0000(0x3D)
+ // 4 - FF:00:00:00 3 - FFFF:FFFF:0000:0000:0000:0000:0000:0000(0x3F)
+ // 8 - F0:00:00:00 4 - FFFF:0000:0000:0000:0000:0000:0000:0000(0xFF)
+ union{
+ unsigned long dip4;
+ unsigned short dip6[8];
+ }dip;
+#define dip4_addr dip.dip4
+#define dip6_addr16 dip.dip6
+ unsigned char dip_mask;
+
+ unsigned short eth_type;
+ unsigned short vlan;
+ unsigned short cos;
+ unsigned short sp_hi;
+ unsigned short sp_lo;
+ unsigned short dp_hi;
+ unsigned short dp_lo;
+ unsigned char r_dscp;
+ unsigned char ip_prot;
+ unsigned char ingress_port;
+
+ // action
+ int act_type; // value = 0 ~ 2, type 3 need a acl entry
+ // 0 for drop
+ // 1 for Act_0 = b'0
+ // 2 for Act_1 = b'1
+ // 3 for Act_0001
+
+ unsigned long act_valid; // bit 0 : redir
+ // bit 1 : pri
+ // bit 2 : dscp
+ // bit 3 : cpu
+ // bit 4 : mirror
+ // bit 5 : ptp
+ // bit 6 : sflow
+ // bit 7 : ctag
+ // bit 8 : stag
+ // bit 9 : bw
+ // bit 10: storm
+ // bit 11: mib_counter
+ unsigned int redir:5;
+ unsigned int pri:3;
+ unsigned int a_dscp:3;
+ unsigned int cpu:1;
+ unsigned int mirror:1;
+ unsigned int ptp:1;
+ unsigned int sflow:1;
+ unsigned short ctag;
+ unsigned short stag;
+ unsigned short bw;
+ unsigned short storm;
+ unsigned short mib_counter;
+
+ /* User define 64 bytes offset */
+ //one bit for 2 bytes offset
+ unsigned short location1; //[4:0] user0
+ //[9:5] user1
+ unsigned short location2; //[4:0] user2
+ //[9:5] user3
+
+ unsigned short usr0;
+ unsigned short usr0_start;
+ unsigned short usr1;
+ unsigned short usr1_start;
+ unsigned short usr2;
+ unsigned short usr3;
+
+ unsigned short mask0;
+ unsigned short mask1;
+ unsigned short mask2;
+ unsigned short mask3;
+};
+
+struct AclRuleSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned int find_index_blockn; // find index start from block n and return used block actually.
+ unsigned int find_index_rvs; // in block, find index in reverse or not
+ unsigned int rule_index;
+ unsigned int func_used;
+ int rule_index_res;
+ struct acl_rule rule;
+ unsigned long reserved; // show the used entry numbers for ip1811
+};
+
+struct AclGeneralSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int index;
+ int data;
+};
+
+struct AclEntryMaskGetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned short mask[4];
+};
+
+struct AclTableCleanSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ int rule_idx;
+ int func_used;
+};
+
+/*--------------- Special Data Structures for EEPROM ---------------*/
+struct EepromSetting
+{
+ void *nextcmd;
+ unsigned long size_nextcmd;
+ unsigned long cmdid;
+ unsigned short addr;
+ unsigned char value;
+};
+
+#endif /* IP1811DS_H */
diff --git a/kernel/drivers/net/ethernet/ip1811/ip1811fdat.c b/kernel/drivers/net/ethernet/ip1811/ip1811fdat.c
new file mode 100644
index 0000000..e467128
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/ip1811fdat.c
@@ -0,0 +1,466 @@
+#include "ip1811fdat.h"
+
+int (*func_of_common_smi[NUM_COMMON_SMI])(void *cdata, int len) =
+{
+ &setPortAN,
+ &getPortAN,
+ &setPortSpeed,
+ &getPortSpeed,
+ &setPortDuplex,
+ &getPortDuplex,
+ &setPortPause,
+ &getPortPause,
+ &setPortAsymPause,
+ &getPortAsymPause,
+ &setPortLinkStatus,
+ &getPortLinkStatus,
+ &setPortBackpressure,
+ &getPortBackpressure,
+ &setPortPowerDown,
+ &getPortPowerDown,
+ &setPortForceLink,
+ &getPortForceLink,
+ &setPortUniDirection,
+ &getPortUniDirection,
+};
+
+int (*func_of_common_cap[NUM_COMMON_CAP])(void *cdata, int len) =
+{
+ &setL2CapAct,
+ &setCapInBand,
+ &setCapSwitchMac,
+ &setCapIpv6TcpUdpEnable,
+};
+
+int (*func_of_common_lut[NUM_COMMON_LUT])(void *cdata, int len) =
+{
+ &setSMACLearning,
+ &getSMACLearning,
+ &setLutPortFlush,
+ &setLutAgingTime,
+ &getLutAgingTime,
+ &setLutAgingTimeEnable,
+ &setLutLearningNullSA,
+ &setLutHashingAlgorithm,
+ &setLutBindingEnable,
+ &getLutBindingEnable,
+};
+
+int (*func_of_common_sniffer[NUM_COMMON_SNIFFER])(void *cdata, int len) =
+{
+ &setSnifferSrc,
+ &getSnifferSrc,
+ &setSnifferDestGrp1,
+ &getSnifferDestGrp1,
+ &setS1Method,
+ &getS1Method,
+};
+
+int (*func_of_common_storm[NUM_COMMON_STORM])(void *cdata, int len) =
+{
+ &setStormFunc,
+ &getStormFunc,
+ &setStormThreshold,
+ &getStormThreshold,
+ &setStormCntrClrPeriod,
+ &getStormCntrClrPeriod,
+ &setStormBlockFrm2Cpu,
+ &getStormBlockFrm2Cpu,
+ &setStormDropInterrupt,
+ &getStormDropInterrupt,
+};
+
+int (*func_of_common_eoc[5])(void *cdata, int len) =
+{
+};
+
+int (*func_of_common_ld[NUM_COMMON_LOOP_DETECT])(void *cdata, int len) =
+{
+ &setLdFunc,
+ &getLdFunc,
+ &setLdTimeUnit,
+ &getLdTimeUnit,
+ &setLdPktSendTimer,
+ &getLdPktSendTimer,
+ &setLdBlockReleaseTimer,
+ &getLdBlockReleaseTimer,
+ &getLdStatus,
+};
+
+int (*func_of_common_wol[12])(void *cdata, int len) =
+{
+};
+
+int (*func_of_common_stag[NUM_COMMON_STAG])(void *cdata, int len) =
+{
+ &setCpuPortLink,
+ &setSTagFunc,
+ &getSTagTypeLen,
+ &configCpuPort,
+ &getCpuPort,
+};
+
+int (*func_of_common_misc[NUM_COMMON_MISC])(void *cdata, int len) =
+{
+ &set8021xFunc,
+ &get8021xFunc,
+ &setReg,
+ &getReg,
+ &setCPUReg,
+ &getCPUReg,
+ &setSwitchRestart,
+ &setSwitchReset,
+ &setCpuIfSpeed,
+ &setEepromByte,
+ &getEepromByte,
+};
+
+int (*func_of_common_vlan[NUM_COMMON_VLAN])(void *cdata, int len) =
+{
+ &setVlanEgressFrame, //0
+ &getVlanEgressFrame,
+ &setVlanTagging,
+ &setVlanType,
+
+ &setVlanGroup,
+
+ &setVlanQinQPType, //5
+ &setVlanQinQPAddtag,
+ &getVlanQinQPAddtag,
+ &setVlanQinQPRmvtag,
+ &getVlanQinQPRmvtag,
+ &setVlanQinQPRxdet, //10
+ &getVlanQinQPRxdet,
+ &setVlanQinQPKeep,
+ &getVlanQinQPKeep,
+ &setVlanQinQPIndex,
+ &getVlanQinQPIndex, //15
+ &setVlanQinQIndex,
+ &setVlanQinQStagSelectMethod,
+
+ &setVlanPortAddtag,
+ &getVlanPortAddtag,
+ &setVlanPortRmvtag, //20
+ &getVlanPortRmvtag,
+ &setVlanPortForce,
+ &getVlanPortForce,
+ &setVlanPortUplink,
+ &getVlanPortUplink, //25
+ &setVlanPortExclusive,
+ &getVlanPortExclusive,
+ &setVlanPortEgress,
+ &getVlanPortEgress,
+ &setVlanPortIngressFrame, //30
+ &setVlanPortIngressCheck,
+ &getVlanPortIngressCheck,
+ &setVlanPortVid,
+
+ &setVlanProtocolMode,
+ &setVlanProtocolVid, //35
+ &setVlanProtocolType,
+
+ &setVlanProtocolClear,
+ &setVlanMACBased,
+ &setVlanMACBasedtableconfig,
+ &getVlanMACBasedtableconfig, //40
+ &setVlanMACBasedunknown,
+};
+
+int (*func_of_common_stp[NUM_COMMON_STP])(void *cdata, int len) =
+{
+ &setMstpFunc,
+ &getMstpFunc,
+};
+
+int (*func_of_common_lacp[NUM_COMMON_LACP])(void *cdata, int len) =
+{
+ &setTrunkHashMthd,
+ &getTrunkHashMthd,
+ &setTrunkMbr,
+ &getTrunkMbr,
+ &setCpuNCareTrunkAndVlan,
+ &getCpuNCareTrunkAndVlan,
+};
+
+int (*func_of_common_imp[8])(void *cdata, int len) =
+{
+};
+
+int (*func_of_common_cos[NUM_COMMON_TCPUDP])(void *cdata, int len) =
+{
+ &setCosTcpUdpUserDefine,
+ &getCosTcpUdpUserDefine,
+ &setCosTcpUdpQueue,
+ &getCosTcpUdpQueue,
+ &setCosTcpUdpEnable,
+ &getCosTcpUdpEnable,
+ &setCosTcpEnable,
+ &getCosTcpEnable,
+ &setCosUdpEnable,
+ &getCosUdpEnable,
+ &setCosTcpFlagDropNull,
+ &getCosTcpFlagDropNull,
+ &setCosTcpFlagDropAllset,
+ &getCosTcpFlagDropAllset,
+ &setCosTcpFlag,
+ &getCosTcpFlag,
+ &setCosTcpFlagAct,
+ &getCosTcpFlagAct,
+ &setCosTcpFlagPort,
+ &getCosTcpFlagPort,
+};
+
+int (*func_of_common_bandwidth[NUM_COMMON_BANDWIDTH])(void *cdata, int len) =
+{
+ &setBandwidthIngressRate,
+ &getBandwidthIngressRate,
+ &setBandwidthEgressRate,
+ &getBandwidthEgressRate,
+ &setBandwidthEgressPeriod,
+ &getBandwidthEgressPeriod,
+};
+/* ---------------- functions of ip1811 ---------------------------*/
+int (*func_of_ip1811_lut[NUM_1811_LUT])(void *cdata, int len) =
+{
+ &setLutUnknownSARule,
+ &setLutEntry,
+ &getLutEntry,
+ &getLutValidEntry,
+};
+
+int (*func_of_ip1811_sniffer[NUM_1811_SNIFFER])(void *cdata, int len) =
+{
+ &setS1PktModify,
+ &getS1PktModify,
+ &setS1TM4CpuSTag,
+ &getS1TM4CpuSTag,
+ &setS1TM4Acl2Cpu,
+ &getS1TM4Acl2Cpu,
+ &setS1TM4Pkt2MPort,
+ &getS1TM4Pkt2MPort,
+ &setS2LTT4Grp1,
+ &getS2LTT4Grp1,
+};
+
+int (*func_of_ip1811_storm[NUM_1811_STORM])(void *cdata, int len) =
+{
+ &setMStormNBlockIpPkt,
+ &getMStormNBlockIpPkt,
+ &setMStormIgnr01005EXXXXXX,
+ &getMStormIgnr01005EXXXXXX,
+};
+
+int (*func_of_ip1811_eoc[3])(void *cdata, int len) =
+{
+};
+
+int (*func_of_ip1811_ld[NUM_1811_LOOP_DETECT])(void *cdata, int len) =
+{
+ &setLdDMAC,
+ &setLdSubType,
+};
+
+int (*func_of_ip1811_wol[6])(void *cdata, int len) =
+{
+};
+
+int (*func_of_ip1811_misc[15])(void *cdata, int len) =
+{
+};
+
+int (*func_of_ip1811_stp[NUM_1811_STP])(void *cdata, int len) =
+{
+ &setBpduCapMode,
+ &getBpduCapMode,
+ &setBpduPortAct,
+ &getBpduPortAct,
+ &setStpPortState,
+ &getStpPortState,
+};
+
+int (*func_of_ip1811_lacp[NUM_1811_LACP])(void *cdata, int len) =
+{
+ &setTrunkHashMthdSeq,
+ &getTrunkHashMthdSeq,
+ &setTrunkGrpCombine,
+ &getTrunkGrpCombine,
+};
+
+int (*func_of_ip1811_igmp[NUM_1811_IGMP])(void *cdata, int len) =
+{
+ &setIGMPSnooping,
+ &getIGMPSnooping,
+ &setIGMPMctByCPU,
+ &getIGMPMctByCPU,
+ &setIGMPRltByCPU,
+ &getIGMPRltByCPU,
+ &setIGMPPktForward,
+ &getIGMPPktForward,
+ &setIGMPRlt,
+ &getIGMPRlt,
+ &setIGMPHashMethod,
+ &getIGMPHashMethod,
+ &setIGMPMldRule,
+ &getIGMPMldRule,
+ &setIGMPMctTable,
+ &getIGMPMctTable,
+ &setIGMPSltTable,
+ &getIGMPSltTable,
+};
+
+int (*func_of_ip1811_ptp[NUM_1811_PTP])(void *cdata, int len)=
+{
+ &setPTPEnable,
+ &getPTPEnable,
+ &setPTPDA011B19000000,
+ &getPTPDA011B19000000,
+ &setPTPDA0180C200000E,
+ &getPTPDA0180C200000E,
+ &setPTPUdpDP,
+ &getPTPUdpDP,
+ &setPTPUdpSP,
+ &getPTPUdpSP,
+ &setPTPToCPU,
+ &getPTPToCPU,
+ &setPTPSpecialTag,
+ &getPTPSpecialTag,
+ &setPTPClockReset,
+ &getPTPTimeStamp,
+ &setPTPClockEnable,
+ &getPTPClockEnable,
+ &setPTPOverwriteEnable,
+ &getPTPOverwriteEnable,
+ &setPTPProgrammable,
+ &getPTPProgrammable,
+ &setPTPProgrammableOut,
+ &setPTPTimestampEnable,
+ &getPTPTimestampEnable,
+ &setPTPTimestampClear,
+ &setPTPTimeData,
+ &getPTPTimeData,
+ &addPTPTimeData,
+ &subPTPTimeData,
+ &setPTPFrequencyAdd,
+ &getPTPFrequencyAdd,
+ &setPTPClockPeriod,
+ &getPTPClockPeriod,
+ &setPTPProgrammableConfig,
+ &setPTPDurationFrequencyCompensation,
+ &setPTPAlwaysFrequencyCompensation,
+ &getPTPIngressLatency10,
+ &getPTPIngressLatency100,
+ &getPTPIngressLatencyFiber,
+ &getPTPEgressLatency10,
+ &getPTPEgressLatency100,
+ &getPTPEgressLatencyFiber,
+};
+
+int (*func_of_ip1811_imp[2])(void *cdata, int len) =
+{
+};
+
+int (*func_of_ip1811_vlan[NUM_IP1811_VLAN])(void *cdata, int len) =
+{
+ &setVlanEntryMember,
+ &setVlanEntryAddtag,
+ &setVlanEntryRmvtag,
+ &setVlanEntryPriority,
+ &setVlanEntryFid,
+ &getVlanEntryFid,
+ &setVlanEntryClear,
+};
+
+int (*func_of_ip1811_mib_counter[NUM_1811_MIB_COUNTER])(void *cdata, int len) =
+{
+ &setMibCounterEnable,
+ &getMibCounterEnable,
+ &getMibCounterAll,
+ &getMibCounterByPort,
+ &getMibCounterByItem,
+};
+
+int (*func_of_ip1811_qos[NUM_IP1811_QOS])(void *cdata, int len) =
+{
+ &setQOSAgingFunction,
+ &getQOSAgingFunction,
+ &setQOSAgingTime,
+ &getQOSAgingTime,
+ &setQOSFastAging,
+ &getQOSFastAging,
+ &setCOSIGMP,
+ &getCOSIGMP,
+ &setCOSMACAddress,
+ &getCOSMACAddress,
+ &setCOSVID,
+ &getCOSVID,
+ &setCOSTCPUDPPort,
+ &getCOSTCPUDPPort,
+ &setCOSDSCP,
+ &getCOSDSCP,
+ &setCOS8021P,
+ &getCOS8021P,
+ &setCOSPhsicalPort,
+ &getCOSPhsicalPort,
+ &setCOSPortQueue,
+ &getCOSPortQueue,
+ &setCOS8021PEdtion,
+ &getCOS8021PEdtion,
+ &setCOSDSCPBaseDSCP,
+ &getCOSDSCPBaseDSCP,
+ &setCOSDSCPBaseNoMatchAction,
+ &getCOSDSCPBaseNoMatchAction,
+ &setQOSmodeGroupMember,
+ &getQOSmodeGroupMember,
+ &setQOSGroupBEn,
+ &getQOSGroupBEn,
+ &setQOSMode,
+ &getQOSMode,
+ &setQOSMethod,
+ &getQOSMethod,
+ &setQOSWeight,
+ &getQOSWeight,
+ &setQOSMaxBandwidth,
+ &getQOSMaxBandwidth,
+ &setQOSUnit,
+ &getQOSUnit,
+ &setQOSRatioValue0Def,
+ &getQOSRatioValue0Def,
+ &setQOSSBMDBM,
+ &getQOSSBMDBM,
+ &setQOSDBMEn,
+ &getQOSDBMEn,
+ &setQOSRemap,
+ &getQOSRemap,
+};
+
+int (*func_of_ip1811_acl[NUM_IP1811_ACL])(void *cdata, int len) =
+{
+ &setAclRule,
+ &getAclRule,
+ &aclCleanTable,
+ &setAclFunctionEn,
+ &getAclFunctionEn,
+ &setAclEtherAfterTag,
+ &getAclEtherAfterTag,
+ &getAclUsedRules,
+ &getAclUsedEntries,
+ &getAclUsedEntryMask,
+ &setAclBW,
+ &getAclBW,
+ &setAclDscp,
+ &getAclDscp,
+ &setAclVidRemark,
+ &getAclVidRemark,
+ &setAclStormPeriod,
+ &getAclStormPeriod,
+ &setAclStorm,
+ &getAclStorm,
+};
+
+int (*func_of_ip1811_hsr[NUM_IP1811_HSR])(void *cdata, int len) =
+{
+ &setHSREnable,
+ &getHSREnable,
+ &setHSRMode,
+ &getHSRMode,
+};
diff --git a/kernel/drivers/net/ethernet/ip1811/ip1811fdat.h b/kernel/drivers/net/ethernet/ip1811/ip1811fdat.h
new file mode 100644
index 0000000..8b5d4cd
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/ip1811fdat.h
@@ -0,0 +1,550 @@
+#ifndef IP1811FDAT_H
+#define IP1811FDAT_H
+#include "ip1811.h"
+
+extern int (*func_of_common_smi[NUM_COMMON_SMI])(void *cdata, int len);
+extern int (*func_of_common_cap[NUM_COMMON_CAP])(void *cdata, int len);
+extern int (*func_of_common_lut[NUM_COMMON_LUT])(void *cdata, int len);
+extern int (*func_of_common_sniffer[NUM_COMMON_SNIFFER])(void *cdata, int len);
+extern int (*func_of_common_storm[NUM_COMMON_STORM])(void *cdata, int len);
+extern int (*func_of_common_eoc[5])(void *cdata, int len);
+extern int (*func_of_common_ld[NUM_COMMON_LOOP_DETECT])(void *cdata, int len);
+extern int (*func_of_common_wol[12])(void *cdata, int len);
+extern int (*func_of_common_stag[NUM_COMMON_STAG])(void *cdata, int len);
+extern int (*func_of_common_misc[NUM_COMMON_MISC])(void *cdata, int len);
+extern int (*func_of_common_vlan[NUM_COMMON_VLAN])(void *cdata, int len);
+extern int (*func_of_common_stp[NUM_COMMON_STP])(void *cdata, int len);
+extern int (*func_of_common_lacp[NUM_COMMON_LACP])(void *cdata, int len);
+extern int (*func_of_common_imp[8])(void *cdata, int len);
+extern int (*func_of_common_cos[NUM_COMMON_TCPUDP])(void *cdata, int len);
+extern int (*func_of_common_bandwidth[NUM_COMMON_BANDWIDTH])(void *cdata, int len);
+extern int (*func_of_ip1811_sniffer[NUM_1811_SNIFFER])(void *cdata, int len);
+extern int (*func_of_ip1811_storm[NUM_1811_STORM])(void *cdata, int len);
+extern int (*func_of_ip1811_eoc[3])(void *cdata, int len);
+extern int (*func_of_ip1811_ld[NUM_1811_LOOP_DETECT])(void *cdata, int len);
+extern int (*func_of_ip1811_wol[6])(void *cdata, int len);
+extern int (*func_of_ip1811_misc[15])(void *cdata, int len);
+extern int (*func_of_ip1811_stp[NUM_1811_STP])(void *cdata, int len);
+extern int (*func_of_ip1811_lacp[NUM_1811_LACP])(void *cdata, int len);
+extern int (*func_of_ip1811_lut[NUM_1811_LUT])(void *cdata, int len);
+extern int (*func_of_ip1811_igmp[NUM_1811_IGMP])(void *cdata, int len);
+extern int (*func_of_ip1811_ptp[NUM_1811_PTP])(void *cdata, int len);
+extern int (*func_of_ip1811_imp[2])(void *cdata, int len);
+extern int (*func_of_ip1811_vlan[NUM_IP1811_VLAN])(void *cdata, int len);
+extern int (*func_of_ip1811_mib_counter[NUM_1811_MIB_COUNTER])(void *cdata, int len);
+extern int (*func_of_ip1811_qos[NUM_IP1811_QOS])(void *cdata, int len);
+extern int (*func_of_ip1811_acl[NUM_IP1811_ACL])(void *cdata, int len);
+extern int (*func_of_ip1811_hsr[NUM_IP1811_HSR])(void *cdata, int len);
+
+int setPortAN(void *cdata, int len);
+int getPortAN(void *cdata, int len);
+int setPortSpeed(void *cdata, int len);
+int getPortSpeed(void *cdata, int len);
+int setPortDuplex(void *cdata, int len);
+int getPortDuplex(void *cdata, int len);
+int setPortPause(void *cdata, int len);
+int getPortPause(void *cdata, int len);
+int setPortAsymPause(void *cdata, int len);
+int getPortAsymPause(void *cdata, int len);
+int setPortLinkStatus(void *cdata, int len);
+int getPortLinkStatus(void *cdata, int len);
+int setPortBackpressure(void *cdata, int len);
+int getPortBackpressure(void *cdata, int len);
+int setPortPowerDown(void *cdata, int len);
+int getPortPowerDown(void *cdata, int len);
+int setPortForceLink(void *cdata, int len);
+int getPortForceLink(void *cdata, int len);
+int setPortUniDirection(void *cdata, int len);
+int getPortUniDirection(void *cdata, int len);
+int setMdioDivisor(void *cdata, int len);
+int setFalseLinkSolution(void *cdata, int len);
+
+int setL2CapAct(void *cdata, int len);
+int getL2CapAct(void *cdata, int len);
+int setCapInBand(void *cdata, int len);
+int getCapInBand(void *cdata, int len);
+int setCapInBandRestrict(void *cdata, int len);
+int getCapInBandRestrict(void *cdata, int len);
+int setCapInBandRestrictCfg(void *cdata, int len);
+int getCapInBandRestrictCfg(void *cdata, int len);
+int setCapSwitchMac(void *cdata, int len);
+int getCapSwitchMac(void *cdata, int len);
+int setCapL3Act(void *cdata, int len);
+int getCapL3Act(void *cdata, int len);
+int setCapL3User(void *cdata, int len);
+int getCapL3User(void *cdata, int len);
+int setCapEtherUser(void *cdata, int len);
+int getCapEtherUser(void *cdata, int len);
+int setCapIpv6TcpUdpEnable(void *cdata, int len);
+int getCapIpv6TcpUdpEnable(void *cdata, int len);
+int setCapIpv6TcpUdpFlagEnable(void *cdata, int len);
+int getCapIpv6TcpUdpFlagEnable(void *cdata, int len);
+int setCapIpv6StopFinding(void *cdata, int len);
+int getCapIpv6StopFinding(void *cdata, int len);
+int setCapIpv6ToAllPortsHigh(void *cdata, int len);
+int getCapIpv6ToAllPortsHigh(void *cdata, int len);
+int setCapIpv6ToCpuHigh(void *cdata, int len);
+int getCapIpv6ToCpuHigh(void *cdata, int len);
+int setCapIpv6Act(void *cdata, int len);
+int getCapIpv6Act(void *cdata, int len);
+int setCapIpv6User(void *cdata, int len);
+int getCapIpv6User(void *cdata, int len);
+int setCapIcmpv6User(void *cdata, int len);
+int getCapIcmpv6User(void *cdata, int len);
+
+int setSMACLearning(void *cdata, int len);
+int getSMACLearning(void *cdata, int len);
+int setSMACLrnCntCtrl(void *cdata, int len);
+int getSMACLrnCntCtrl(void *cdata, int len);
+int setSMACLrnThreshold(void *cdata, int len);
+int getSMACLrnThreshold(void *cdata, int len);
+int setLutPortFlush(void *cdata, int len);
+int setLutAgingTime(void *cdata, int len);
+int getLutAgingTime(void *cdata, int len);
+int setLutAgingTimeEnable(void *cdata, int len);
+int getLutAgingTimeEnable(void *cdata, int len);
+int setLutLearningNullSA(void *cdata, int len);
+int getLutLearningNullSA(void *cdata, int len);
+int setLutHashingAlgorithm(void *cdata, int len);
+int getLutHashingAlgorithm(void *cdata, int len);
+int setLutBindingEnable(void *cdata, int len);
+int getLutBindingEnable(void *cdata, int len);
+int setLutLearnPktDropByVlanIgsChk(void *cdata, int len);
+int getLutLearnPktDropByVlanIgsChk(void *cdata, int len);
+
+int setLutLearningMode(void *cdata, int len);
+int getLutLearningMode(void *cdata, int len);
+int setLutUnknownSARule(void *cdata, int len);
+int getLutUnknownSARule(void *cdata, int len);
+int setLutEntry(void *cdata, int len);
+int getLutEntry(void *cdata, int len);
+int getLutValidEntry(void *cdata, int len);
+
+int setSnifferSrc(void *cdata, int len);
+int getSnifferSrc(void *cdata, int len);
+int setSnifferDestGrp1(void *cdata, int len);
+int getSnifferDestGrp1(void *cdata, int len);
+int setSnifferDestGrp2(void *cdata, int len);
+int getSnifferDestGrp2(void *cdata, int len);
+int setS1Method(void *cdata, int len);
+int getS1Method(void *cdata, int len);
+
+int setStormFunc(void *cdata, int len);
+int getStormFunc(void *cdata, int len);
+int setStormThreshold(void *cdata, int len);
+int getStormThreshold(void *cdata, int len);
+int setStormCntrClrPeriod(void *cdata, int len);
+int getStormCntrClrPeriod(void *cdata, int len);
+int setStormBlockFrm2Cpu(void *cdata, int len);
+int getStormBlockFrm2Cpu(void *cdata, int len);
+int setStormDropInterrupt(void *cdata, int len);
+int getStormDropInterrupt(void *cdata, int len);
+
+int setEocFunc(void *cdata, int len);
+int getEocFunc(void *cdata, int len);
+int getEocStatus(void *cdata, int len);
+int setEocReleaseTime(void *cdata, int len);
+int getEocReleaseTime(void *cdata, int len);
+
+int setLdFunc(void *cdata, int len);
+int getLdFunc(void *cdata, int len);
+int setLdTimeUnit(void *cdata, int len);
+int getLdTimeUnit(void *cdata, int len);
+int setLdPktSendTimer(void *cdata, int len);
+int getLdPktSendTimer(void *cdata, int len);
+int setLdBlockReleaseTimer(void *cdata, int len);
+int getLdBlockReleaseTimer(void *cdata, int len);
+int getLdStatus(void *cdata, int len);
+
+int setWolFunc(void *cdata, int len);
+int getWolFunc(void *cdata, int len);
+int setWolMode(void *cdata, int len);
+int getWolMode(void *cdata, int len);
+int setWolInterrupt(void *cdata, int len);
+int getWolInterrupt(void *cdata, int len);
+int setWolIPUnit(void *cdata, int len);
+int getWolIPUnit(void *cdata, int len);
+int setWolIPThreshold(void *cdata, int len);
+int getWolIPThreshold(void *cdata, int len);
+int setWolStatusInSlaveMode(void *cdata, int len);
+int getWolStatus(void *cdata, int len);
+
+int setCpuPortLink(void *cdata, int len);
+int getCpuPortLink(void *cdata, int len);
+int setSTagFunc(void *cdata, int len);
+int getSTagFunc(void *cdata, int len);
+int setSTagTypeLen(void *cdata, int len);
+int getSTagTypeLen(void *cdata, int len);
+int configCpuPort(void *cdata, int len);
+int getCpuPort(void *cdata, int len);
+
+int setCosTcpUdpUserDefine(void *cdata, int len);
+int getCosTcpUdpUserDefine(void *cdata, int len);
+int setCosTcpUdpQueue(void *cdata, int len);
+int getCosTcpUdpQueue(void *cdata, int len);
+int setCosTcpUdpEnable(void *cdata, int len);
+int getCosTcpUdpEnable(void *cdata, int len);
+int setCosTcpEnable(void *cdata, int len);
+int getCosTcpEnable(void *cdata, int len);
+int setCosUdpEnable(void *cdata, int len);
+int getCosUdpEnable(void *cdata, int len);
+int setCosTcpFlagDropNull(void *cdata, int len);
+int getCosTcpFlagDropNull(void *cdata, int len);
+int setCosTcpFlagDropAllset(void *cdata, int len);
+int getCosTcpFlagDropAllset(void *cdata, int len);
+int setCosTcpFlag(void *cdata, int len);
+int getCosTcpFlag(void *cdata, int len);
+int setCosTcpFlagAct(void *cdata, int len);
+int getCosTcpFlagAct(void *cdata, int len);
+int setCosTcpFlagPort(void *cdata, int len);
+int getCosTcpFlagPort(void *cdata, int len);
+
+int setBandwidthIngressRate(void *cdata, int len);
+int getBandwidthIngressRate(void *cdata, int len);
+int setBandwidthEgressRate(void *cdata, int len);
+int getBandwidthEgressRate(void *cdata, int len);
+int setBandwidthEgressPeriod(void *cdata, int len);
+int getBandwidthEgressPeriod(void *cdata, int len);
+
+int setPTPEnable(void *cdata, int len);
+int getPTPEnable(void *cdata, int len);
+int setPTPDA011B19000000(void *cdata, int len);
+int getPTPDA011B19000000(void *cdata, int len);
+int setPTPDA0180C200000E(void *cdata, int len);
+int getPTPDA0180C200000E(void *cdata, int len);
+int setPTPUdpDP(void *cdata, int len);
+int getPTPUdpDP(void *cdata, int len);
+int setPTPUdpSP(void *cdata, int len);
+int getPTPUdpSP(void *cdata, int len);
+int setPTPToCPU(void *cdata, int len);
+int getPTPToCPU(void *cdata, int len);
+int setPTPSpecialTag(void *cdata, int len);
+int getPTPSpecialTag(void *cdata, int len);
+int setPTPClockReset(void *cdata, int len);
+int getPTPTimeStamp(void *cdata, int len);
+int setPTPClockEnable(void *cdata, int len);
+int getPTPClockEnable(void *cdata, int len);
+int setPTPOverwriteEnable(void *cdata, int len);
+int getPTPOverwriteEnable(void *cdata, int len);
+int setPTPProgrammable(void *cdata, int len);
+int getPTPProgrammable(void *cdata, int len);
+int setPTPProgrammableOut(void *cdata, int len);
+int setPTPTimestampEnable(void *cdata, int len);
+int getPTPTimestampEnable(void *cdata, int len);
+int setPTPTimestampClear(void *cdata, int len);
+int setPTPTimeData(void *cdata, int len);
+int getPTPTimeData(void *cdata, int len);
+int addPTPTimeData(void *cdata, int len);
+int subPTPTimeData(void *cdata, int len);
+int setPTPFrequencyAdd(void *cdata, int len);
+int getPTPFrequencyAdd(void *cdata, int len);
+int setPTPClockPeriod(void *cdata, int len);
+int getPTPClockPeriod(void *cdata, int len);
+int setPTPProgrammableConfig(void *cdata, int len);
+int setPTPDurationFrequencyCompensation(void *cdata, int len);
+int setPTPAlwaysFrequencyCompensation(void *cdata, int len);
+int getPTPIngressLatency10(void *cdata, int len);
+int getPTPIngressLatency100(void *cdata, int len);
+int getPTPIngressLatencyFiber(void *cdata, int len);
+int getPTPEgressLatency10(void *cdata, int len);
+int getPTPEgressLatency100(void *cdata, int len);
+int getPTPEgressLatencyFiber(void *cdata, int len);
+
+int setJumboPktFunc(void *cdata, int len);
+int getJumboPktFunc(void *cdata, int len);
+int set8021xFunc(void *cdata, int len);
+int get8021xFunc(void *cdata, int len);
+int setReg(void *cdata, int len);
+int getReg(void *cdata, int len);
+int setCPUReg(void *cdata, int len);
+int getCPUReg(void *cdata, int len);
+int setSwitchRestart(void *cdata, int len);
+int setSwitchReset(void *cdata, int len);
+int setCpuIfSpeed(void *cdata, int len);
+int setEepromByte(void *cdata, int len);
+int getEepromByte(void *cdata, int len);
+int get_mii_reg(void *cdata, int len);
+int set_mii_reg(void *cdata, int len);
+
+int setVlanEgressFrame(void *cdata, int len);
+int getVlanEgressFrame(void *cdata, int len);
+int setVlanTagging(void *cdata, int len);
+int getVlanTagging(void *cdata, int len);
+int setVlanType(void *cdata, int len);
+int getVlanType(void *cdata, int len);
+int setVlanGroup(void *cdata, int len);
+
+int setVlanQinQPType(void *cdata, int len);
+int getVlanQinQPType(void *cdata, int len);
+int setVlanQinQPAddtag(void *cdata, int len);
+int getVlanQinQPAddtag(void *cdata, int len);
+int setVlanQinQPRmvtag(void *cdata, int len);
+int getVlanQinQPRmvtag(void *cdata, int len);
+int setVlanQinQPRxdet(void *cdata, int len);
+int getVlanQinQPRxdet(void *cdata, int len);
+int setVlanQinQPKeep(void *cdata, int len);
+int getVlanQinQPKeep(void *cdata, int len);
+int setVlanQinQPIndex(void *cdata, int len);
+int getVlanQinQPIndex(void *cdata, int len);
+int setVlanQinQIndex(void *cdata, int len);
+int getVlanQinQIndex(void *cdata, int len);
+int setVlanQinQStagSelectMethod(void *cdata, int len);
+int getVlanQinQStagSelectMethod(void *cdata, int len);
+
+int setVlanPortAddtag(void *cdata, int len);
+int getVlanPortAddtag(void *cdata, int len);
+int setVlanPortRmvtag(void *cdata, int len);
+int getVlanPortRmvtag(void *cdata, int len);
+int setVlanPortForce(void *cdata, int len);
+int getVlanPortForce(void *cdata, int len);
+int setVlanPortUplink(void *cdata, int len);
+int getVlanPortUplink(void *cdata, int len);
+int setVlanPortExclusive(void *cdata, int len);
+int getVlanPortExclusive(void *cdata, int len);
+int setVlanPortEgress(void *cdata, int len);
+int getVlanPortEgress(void *cdata, int len);
+int setVlanPortIngressFrame(void *cdata, int len);
+int getVlanPortIngressFrame(void *cdata, int len);
+int setVlanPortIngressCheck(void *cdata, int len);
+int getVlanPortIngressCheck(void *cdata, int len);
+int setVlanPortMember(void *cdata, int len);
+int getVlanPortMember(void *cdata, int len);
+int setVlanPortVid(void *cdata, int len);
+int getVlanPortVid(void *cdata, int len);
+
+int setVlanProtocolMode(void *cdata, int len);
+int getVlanProtocolMode(void *cdata, int len);
+int setVlanProtocolVid(void *cdata, int len);
+int getVlanProtocolVid(void *cdata, int len);
+int setVlanProtocolType(void *cdata, int len);
+int getVlanProtocolType(void *cdata, int len);
+int setVlanProtocolClear(void *cdata, int len);
+int setVlanMACBased(void *cdata, int len);
+int setVlanMACBasedtableconfig(void *cdata, int len);
+int getVlanMACBasedtableconfig(void *cdata, int len);
+int setVlanMACBasedunknown(void *cdata, int len);
+
+int setVlanEntryMember(void *cdata, int len);
+int getVlanEntryMember(void *cdata, int len);
+int setVlanEntryAddtag(void *cdata, int len);
+int getVlanEntryAddtag(void *cdata, int len);
+int setVlanEntryRmvtag(void *cdata, int len);
+int getVlanEntryRmvtag(void *cdata, int len);
+int setVlanEntryPriority(void *cdata, int len);
+int getVlanEntryPriority(void *cdata, int len);
+int setVlanEntryFid(void *cdata, int len);
+int getVlanEntryFid(void *cdata, int len);
+int setVlanEntryClear(void *cdata, int len);
+
+int setMstpFunc(void *cdata, int len);
+int getMstpFunc(void *cdata, int len);
+
+int setTrunkHashMthd(void *cdata, int len);
+int getTrunkHashMthd(void *cdata, int len);
+int setTrunkMbr(void *cdata, int len);
+int getTrunkMbr(void *cdata, int len);
+int setCpuNCareTrunkAndVlan(void *cdata, int len);
+int getCpuNCareTrunkAndVlan(void *cdata, int len);
+
+int setImpMode(void *cdata, int len);
+int getImpMode(void *cdata, int len);
+int setImpPassNullIP(void *cdata, int len);
+int getImpPassNullIP(void *cdata, int len);
+int setImpHash(void *cdata, int len);
+int getImpHash(void *cdata, int len);
+int setImpPort(void *cdata, int len);
+int getImpPort(void *cdata, int len);
+
+int setImpEntry(void *cdata, int len);
+int getImpEntry(void *cdata, int len);
+
+int setIGMPSnooping(void *cdata, int len);
+int getIGMPSnooping(void *cdata, int len);
+int setIGMPMctByCPU(void *cdata, int len);
+int getIGMPMctByCPU(void *cdata, int len);
+int setIGMPRltByCPU(void *cdata, int len);
+int getIGMPRltByCPU(void *cdata, int len);
+int setIGMPPktForward(void *cdata, int len);
+int getIGMPPktForward(void *cdata, int len);
+int setIGMPRlt(void *cdata, int len);
+int getIGMPRlt(void *cdata, int len);
+int setIGMPHashMethod(void *cdata, int len);
+int getIGMPHashMethod(void *cdata, int len);
+int setIGMPMldRule(void *cdata, int len);
+int getIGMPMldRule(void *cdata, int len);
+int setIGMPMctTable(void *cdata, int len);
+int getIGMPMctTable(void *cdata, int len);
+int setIGMPSltTable(void *cdata, int len);
+int getIGMPSltTable(void *cdata, int len);
+
+
+int setS1PktModify(void *cdata, int len);
+int getS1PktModify(void *cdata, int len);
+int setS1TM4CpuSTag(void *cdata, int len);
+int getS1TM4CpuSTag(void *cdata, int len);
+int setS1TM4Acl2Cpu(void *cdata, int len);
+int getS1TM4Acl2Cpu(void *cdata, int len);
+int setS1TM4Pkt2MPort(void *cdata, int len);
+int getS1TM4Pkt2MPort(void *cdata, int len);
+int setS2LTT4Grp1(void *cdata, int len);
+int getS2LTT4Grp1(void *cdata, int len);
+int setS2LTT4Grp2(void *cdata, int len);
+int getS2LTT4Grp2(void *cdata, int len);
+
+int setMStormNBlockIpPkt(void *cdata, int len);
+int getMStormNBlockIpPkt(void *cdata, int len);
+int setMStormIgnr01005EXXXXXX(void *cdata, int len);
+int getMStormIgnr01005EXXXXXX(void *cdata, int len);
+
+int setEocBlockClr(void *cdata, int len);
+int setEocClrBlockWhenRcvGood(void *cdata, int len);
+int getEocClrBlockWhenRcvGood(void *cdata, int len);
+
+int setLdSMACB40(void *cdata, int len);
+int getLdSMACB40(void *cdata, int len);
+int setLdRerandom(void *cdata, int len);
+int getLdRerandom(void *cdata, int len);
+int setLdDMAC(void *cdata, int len);
+int getLdDMAC(void *cdata, int len);
+int setLdEtherType(void *cdata, int len);
+int getLdEtherType(void *cdata, int len);
+int setLdSubType(void *cdata, int len);
+int getLdSubType(void *cdata, int len);
+int setLdDeviceID(void *cdata, int len);
+int getLdDeviceID(void *cdata, int len);
+
+int setWolWakeIfTxGetAnyPkt(void *cdata, int len);
+int getWolWakeIfTxGetAnyPkt(void *cdata, int len);
+int setWolWakeIfRxGetAnyPkt(void *cdata, int len);
+int getWolWakeIfRxGetAnyPkt(void *cdata, int len);
+int setWolWakeIfMatchAcl2Cpu(void *cdata, int len);
+int getWolWakeIfMatchAcl2Cpu(void *cdata, int len);
+
+int setMACLoopBackFunc(void *cdata, int len);
+int getMACLoopBackFunc(void *cdata, int len);
+int setPausePktFunc(void *cdata, int len);
+int getPausePktFunc(void *cdata, int len);
+int setPausePktDest(void *cdata, int len);
+int getPausePktDest(void *cdata, int len);
+int setLocalTrafficFunc(void *cdata, int len);
+int getLocalTrafficFunc(void *cdata, int len);
+int setMACReset(void *cdata, int len);
+int getMACReset(void *cdata, int len);
+int setMACSelfTestFunc(void *cdata, int len);
+int getMACSelfTestFunc(void *cdata, int len);
+int setMACSelfTestPktNum(void *cdata, int len);
+int getMACSelfTestPktNum(void *cdata, int len);
+int getMACSelfTestResult(void *cdata, int len);
+
+int setBpduCapMode(void *cdata, int len);
+int getBpduCapMode(void *cdata, int len);
+int setBpduPortAct(void *cdata, int len);
+int getBpduPortAct(void *cdata, int len);
+int setStpPortState(void *cdata, int len);
+int getStpPortState(void *cdata, int len);
+int setStpAllPortsState(void *cdata, int len);
+int getStpAllPortsState(void *cdata, int len);
+
+int setTrunkHashMthdSeq(void *cdata, int len);
+int getTrunkHashMthdSeq(void *cdata, int len);
+int setTrunkGrpCombine(void *cdata, int len);
+int getTrunkGrpCombine(void *cdata, int len);
+
+int setMibCounterEnable(void *cdata, int len);
+int getMibCounterEnable(void *cdata, int len);
+int getMibCounterAll(void *cdata, int len);
+int getMibCounterByPort(void *cdata, int len);
+int getMibCounterByItem(void *cdata, int len);
+
+int setQOSAgingFunction(void *cdata, int len);
+int getQOSAgingFunction(void *cdata, int len);
+int setQOSAgingTime(void *cdata, int len);
+int getQOSAgingTime(void *cdata, int len);
+int setQOSFastAging(void *cdata, int len);
+int getQOSFastAging(void *cdata, int len);
+
+int setCOSIGMP(void *cdata, int len);
+int getCOSIGMP(void *cdata, int len);
+int setCOSMACAddress(void *cdata, int len);
+int getCOSMACAddress(void *cdata, int len);
+int setCOSVID(void *cdata, int len);
+int getCOSVID(void *cdata, int len);
+int setCOSTCPUDPPort(void *cdata, int len);
+int getCOSTCPUDPPort(void *cdata, int len);
+int setCOSDSCP(void *cdata, int len);
+int getCOSDSCP(void *cdata, int len);
+int setCOS8021P(void *cdata, int len);
+int getCOS8021P(void *cdata, int len);
+int setCOSPhsicalPort(void *cdata, int len);
+int getCOSPhsicalPort(void *cdata, int len);
+int setCOSPortQueue(void *cdata, int len);
+int getCOSPortQueue(void *cdata, int len);
+int setCOS8021PEdtion(void *cdata, int len);
+int getCOS8021PEdtion(void *cdata, int len);
+int setCOSDSCPBaseDSCP(void *cdata, int len);
+int getCOSDSCPBaseDSCP(void *cdata, int len);
+int setCOSDSCPBaseNoMatchAction(void *cdata, int len);
+int getCOSDSCPBaseNoMatchAction(void *cdata, int len);
+int setQOSmodeGroupMember(void *cdata, int len);
+int getQOSmodeGroupMember(void *cdata, int len);
+int setQOSGroupBEn(void *cdata, int len);
+int getQOSGroupBEn(void *cdata, int len);
+int setQOSMode(void *cdata, int len);
+int getQOSMode(void *cdata, int len);
+int setQOSMethod(void *cdata, int len);
+int getQOSMethod(void *cdata, int len);
+int setQOSWeight(void *cdata, int len);
+int getQOSWeight(void *cdata, int len);
+int setQOSMaxBandwidth(void *cdata, int len);
+int getQOSMaxBandwidth(void *cdata, int len);
+int setQOSUnit(void *cdata, int len);
+int getQOSUnit(void *cdata, int len);
+int setQOSRatioValue0Def(void *cdata, int len);
+int getQOSRatioValue0Def(void *cdata, int len);
+int setQOSSBMDBM(void *cdata, int len);
+int getQOSSBMDBM(void *cdata, int len);
+int setQOSDBMEn(void *cdata, int len);
+int getQOSDBMEn(void *cdata, int len);
+int setQOSEgressControl(void *cdata, int len);
+int getQOSEgressControl(void *cdata, int len);
+
+int setQOSRemap(void *cdata, int len);
+int getQOSRemap(void *cdata, int len);
+
+void acl_init(void);
+int setAclRule(void *cdata, int len);
+int getAclRule(void *cdata, int len);
+int aclCleanTable(void *cdata, int len);
+int setAclFunctionEn(void *cdata, int len);
+int getAclFunctionEn(void *cdata, int len);
+int setAclEtherAfterTag(void *cdata, int len);
+int getAclEtherAfterTag(void *cdata, int len);
+int getAclUsedRules(void *cdata, int len);
+int getAclUsedEntries(void *cdata, int len);
+int getAclUsedEntryMask(void *cdata, int len);
+int setAclBW(void *cdata, int len);
+int getAclBW(void *cdata, int len);
+int setAclDscp(void *cdata, int len);
+int getAclDscp(void *cdata, int len);
+int setAclVidRemark(void *cdata, int len);
+int getAclVidRemark(void *cdata, int len);
+int setAclStormPeriod(void *cdata, int len);
+int getAclStormPeriod(void *cdata, int len);
+int setAclStorm(void *cdata, int len);
+int getAclStorm(void *cdata, int len);
+
+/* ipv: 4: IPv4
+ * 6: IPv6
+ * addr: IP address
+ * method: 1: Direct
+ * 0: CRC
+ * */
+unsigned char tb_calc_index(unsigned char ipv, void *addr, unsigned char method);
+
+int setHSREnable(void *cdata, int len);
+int getHSREnable(void *cdata, int len);
+int setHSRMode(void *cdata, int len);
+int getHSRMode(void *cdata, int len);
+
+void noFunc(void);
+#endif /* IP1811FDAT_H */
diff --git a/kernel/drivers/net/ethernet/ip1811/ip1811func.c b/kernel/drivers/net/ethernet/ip1811/ip1811func.c
new file mode 100644
index 0000000..2edd2fe
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/ip1811func.c
@@ -0,0 +1,13309 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <asm/io.h>
+
+#include "ip1811.h"
+#include "ip1811reg.h"
+#include "ip1811ds.h"
+#include "ip1811op.h"
+#include "ip1811fdat.h"
+#include "ip218.h"
+
+#define MII_OP_READ 0
+#define MII_OP_WRITE 1
+
+//#define TEST_REG
+//#define IP1811DEBUG
+//#define IP1811DRV_REG_DEBUG
+#ifdef IP1811DRV_REG_DEBUG
+#define ip1811drv_dbg(fmt, ...) printk(KERN_DEBUG "<%s:%d>" fmt, __func__, __LINE__, ##__VA_ARGS__)
+#else
+#define ip1811drv_dbg(...)
+#endif//IP1811DRV_REG_DEBUG
+
+#define IP1811DRV_REG_ERROR
+#ifdef IP1811DRV_REG_ERROR
+#define ip1811drv_err(fmt, ...) printk(KERN_ERR "<%s:%d>" fmt, __func__, __LINE__, ##__VA_ARGS__)
+#else
+#define ip1811drv_err(...)
+#endif//IP1811DRV_REG_ERROR
+
+#define FUNC_MSG_IN ip1811drv_dbg("IN \n")
+#define FUNC_MSG_OUT ip1811drv_dbg("OUT\n")
+
+extern u8 CPU_IF_SPEED_NORMAL;
+
+#ifdef TEST_REG
+u16 RegList[16][256];
+u8 pg;
+#endif//TEST_REG
+
+#define ip1811delay() (udelay(100))
+
+/*============= misc. driver functions ===================*/
+
+//#define ACCESS_REG_BY_MDIO
+#ifdef ACCESS_REG_BY_MDIO
+//-------------- p1811 project GPIO MDIO Function ---------------------
+#define MDIO_DELAY 0
+#define MDIO_RD 0
+#define MDIO_WR 1
+#define GPIO_MDIO_OFFSET 10
+#define GPIO_MDC_OFFSET 11
+#include <asm/io.h>
+static DEFINE_MUTEX(ip1811_gpio_lock);
+#define IP1811_GPIO_BASE 0xBD700000
+#define IP1811_GPIO_OUTPUT_VALUE_2_OFFSET 0x003C
+#define IP1811_GPIO_OUTPUT_ENABLE_2_OFFSET 0x0040
+#define IP1811_GPIO_INPUT_VALUE_2_OFFSET 0x0038
+#define IP1811_GPIO_SET_VALUE_1 0x1
+#define IP1811_GPIO_SET_VALUE_0 0x0
+static int ip1811_gpio_get(unsigned offset)
+{
+ void __iomem *base;
+ u32 val;
+
+ mutex_lock(&ip1811_gpio_lock);
+
+
+ base = IP1811_GPIO_BASE + IP1811_GPIO_INPUT_VALUE_2_OFFSET;
+ val = readl(base);
+ val = ((val & BIT(offset))>>offset);
+
+ mutex_unlock(&ip1811_gpio_lock);
+
+ return val;
+}
+static void ip1811_gpio_set(unsigned offset,int value)
+{
+ void __iomem *base;
+ u32 val;
+
+ mutex_lock(&ip1811_gpio_lock);
+
+ base = IP1811_GPIO_BASE + IP1811_GPIO_OUTPUT_VALUE_2_OFFSET;
+ val = readl(base);
+ val = (value == IP1811_GPIO_SET_VALUE_1) ? (val | BIT(offset)) : (val & ~((BIT(offset))));
+ writel(val, base);
+
+ mutex_unlock(&ip1811_gpio_lock);
+
+ return;
+}
+static int ip1811_gpio_direction_out(unsigned offset,int value)
+{
+ void __iomem *base;
+ u32 val;
+
+ mutex_lock(&ip1811_gpio_lock);
+
+ base = IP1811_GPIO_BASE + IP1811_GPIO_OUTPUT_ENABLE_2_OFFSET;
+ val = readl(base);
+ val |= BIT(offset);
+ writel(val, base);
+
+ mutex_unlock(&ip1811_gpio_lock);
+
+ return 0;
+}
+static int ip1811_gpio_direction_in( unsigned offset)
+{
+ void __iomem *base;
+ u32 val;
+
+ mutex_lock(&ip1811_gpio_lock);
+
+ base = IP1811_GPIO_BASE + IP1811_GPIO_OUTPUT_ENABLE_2_OFFSET;
+ val = readl(base);
+ val &= ~(BIT(offset));
+ writel(val, base);
+
+ mutex_unlock(&ip1811_gpio_lock);
+
+ return val;
+}
+void mdio_1(void){
+
+ int i;
+ //set MDIO to 1
+ //set MDC to 0
+ ip1811_gpio_set(GPIO_MDIO_OFFSET,1);
+ ip1811_gpio_set(GPIO_MDC_OFFSET,0);
+
+ for(i=0;i<MDIO_DELAY;i++);
+
+ //set MDIO to 1
+ //set MDC to 1
+ ip1811_gpio_set(GPIO_MDIO_OFFSET,1);
+ ip1811_gpio_set(GPIO_MDC_OFFSET,1);
+
+ for(i=0;i<MDIO_DELAY;i++);
+}
+
+void mdio_0(void){
+
+ int i;
+ //set MDIO to 0
+ //set MDC to 0
+ ip1811_gpio_set(GPIO_MDIO_OFFSET,0);
+ ip1811_gpio_set(GPIO_MDC_OFFSET,0);
+
+ for(i=0;i<MDIO_DELAY;i++);
+
+ //set MDIO to 0
+ //set MDC to 1
+ ip1811_gpio_set(GPIO_MDIO_OFFSET,0);
+ ip1811_gpio_set(GPIO_MDC_OFFSET,1);
+
+ for(i=0;i<MDIO_DELAY;i++);
+}
+
+void mdio_z(void){
+
+ int i;
+ //set MDC to 0
+ ip1811_gpio_set(GPIO_MDC_OFFSET,0);
+
+ for(i=0;i<MDIO_DELAY;i++);
+ //set MDC to 1
+ ip1811_gpio_set(GPIO_MDC_OFFSET,1);
+
+ for(i=0;i<MDIO_DELAY;i++);
+}
+
+void mdio_start(void){
+ mdio_0();
+ mdio_1();
+}
+
+void mdio_rw(int rw){
+ if(rw==MDIO_RD){
+ mdio_1();
+ mdio_0();
+ }else{
+ mdio_0();
+ mdio_1();
+ }
+}
+void mdio_set_MDC_MDIO_direction(unsigned char mdc, unsigned char mdio)//0:input, 1:output for mdc/mdio values
+{
+ if(mdc) ;
+ if(mdio)
+ ip1811_gpio_direction_out(GPIO_MDIO_OFFSET,0);
+ else
+ ip1811_gpio_direction_in(GPIO_MDIO_OFFSET);
+}
+void ic_mdio_wr(unsigned short pa, unsigned short ra, unsigned short va){
+ int i=0;
+ unsigned short data=0;
+
+ //set MDC/MDIO pins to GPIO mode
+ ip1811_gpio_direction_out(GPIO_MDC_OFFSET,0);
+ ip1811_gpio_direction_out(GPIO_MDIO_OFFSET,0);
+
+ //set MDC direction to output
+ //set MDIO direction to output
+ mdio_set_MDC_MDIO_direction(1,1);
+
+ for(i=0;i<32;i++)
+ mdio_1();
+ mdio_start();
+ mdio_rw(MDIO_WR);
+ for(i=0;i<5;i++){
+ if((pa>>(5-1-i))%2)
+ mdio_1();
+ else
+ mdio_0();
+ }
+ for(i=0;i<5;i++){
+ if((ra>>(5-1-i))%2)
+ mdio_1();
+ else
+ mdio_0();
+ }
+ mdio_1();
+ mdio_0();
+ for(i=0;i<16;i++){
+ data=va<<i;
+ data=data>>15;
+ if(data==1)
+ mdio_1();
+ else
+ mdio_0();
+ }
+}
+unsigned short ic_mdio_rd(unsigned short pa, unsigned short ra){
+ int i=0,j=0;
+ unsigned short data=0;
+ int regBit;
+ unsigned char debug[16];
+
+ //set MDC/MDIO pins to GPIO mode
+ ip1811_gpio_direction_out(GPIO_MDC_OFFSET,0);
+ ip1811_gpio_direction_out(GPIO_MDIO_OFFSET,0);
+
+ //set MDC/MDIO PIN direction
+ //mdio_set_MDC_MDIO_dir();
+ //MDC direction set to output
+ //MDIO direction set to output
+ mdio_set_MDC_MDIO_direction(1,1);
+
+ for(i=0;i<32;i++)
+ mdio_1();
+ mdio_start();
+ mdio_rw(MDIO_RD);
+ for(i=0;i<5;i++){
+ if((pa>>(5-1-i))%2)
+ mdio_1();
+ else
+ mdio_0();
+ }
+ for(i=0;i<5;i++){
+ if((ra>>(5-1-i))%2)
+ mdio_1();
+ else
+ mdio_0();
+ }
+ mdio_z();
+ //MDIO DIR set to input
+ mdio_set_MDC_MDIO_direction(1,0);
+ mdio_0();
+
+
+ for(j=0;j<16;j++){
+ //MDC set to 0
+ ip1811_gpio_set(GPIO_MDC_OFFSET,0);
+
+ for(i=0;i<MDIO_DELAY;i++);
+ //get MDIO value
+ regBit=ip1811_gpio_get(GPIO_MDIO_OFFSET);
+ if(regBit==0)
+ {
+ data|=0;
+ debug[15-j]=0;
+ }
+ else
+ {
+ data|=1;
+ debug[15-j]=1;
+ }
+ if(j<15)
+ data=data<<1;
+ //MDC set to 1
+ ip1811_gpio_set(GPIO_MDC_OFFSET,1);
+
+ for(i=0;i<MDIO_DELAY;i++);
+ }
+ //MDC set to 0
+ ip1811_gpio_set(GPIO_MDC_OFFSET,0);
+
+ for(i=0;i<MDIO_DELAY;i++);
+ //MDC set to 1
+ ip1811_gpio_set(GPIO_MDC_OFFSET,1);
+
+ for(i=0;i<MDIO_DELAY;i++);
+
+ return data;
+}
+#else//#ifndef ACCESS_REG_BY_MDIO
+void ic_mdio_wr(unsigned short pa, unsigned short ra, unsigned short va){
+ void __iomem *base;
+ unsigned long val;
+ struct ip218_smictrl0 *smic0;
+
+ FUNC_MSG_IN;
+
+ val = 0;
+ smic0 = (struct ip218_smictrl0 *)&val;
+ smic0 -> phy = pa;
+ smic0 -> reg = ra;
+ smic0 -> wr_data = va;
+ smic0 -> rdwr = 1;//1: write cycle
+ smic0 -> en = 1;
+
+ base = (void __iomem *)(IP218_MAC_BASE + IP218_MAC_SMICTRL0);
+ ip1811drv_dbg("write [%p]=%08lX\n", base, val);
+ writel(val, base);
+
+ // wait for writing process done
+ do{
+ val = readl(base);
+ }while(smic0 -> en);
+
+ FUNC_MSG_OUT;
+}
+unsigned short ic_mdio_rd(unsigned short pa, unsigned short ra){
+ void __iomem *base;
+ unsigned long val;
+ unsigned short ret;
+ struct ip218_smictrl0 *smic0;
+ struct ip218_smictrl1 *smic1;
+
+ FUNC_MSG_IN;
+
+ val = 0;
+ smic0 = (struct ip218_smictrl0 *)&val;
+ smic0 -> phy = pa;
+ smic0 -> reg = ra;
+ smic0 -> rdwr = 0;//0: read cycle
+ smic0 -> en = 1;
+
+ base = (void __iomem *)(IP218_MAC_BASE + IP218_MAC_SMICTRL0);
+ ip1811drv_dbg("write [%p]=%08lX\n", base, val);
+ writel(val, base);
+
+ // wait for writing process done
+ do{
+ val = readl(base);
+ }while(smic0 -> en);
+
+ // read data from register
+ base = (void __iomem *)(IP218_MAC_BASE + IP218_MAC_SMICTRL1);
+ val = readl(base);
+ smic1 = (struct ip218_smictrl1 *)&val;
+ ret = smic1 -> rd_data;
+ ip1811drv_dbg("read [%p]=%08lX\n", base, val);
+
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+#endif//ACCESS_REG_BY_MDIO
+
+void Write_Reg(u8 regaddr, u16 value)
+{
+ u16 tmp = CPU_IF_SPEED_NORMAL ? regaddr : (u16)regaddr << 2;
+#ifdef TEST_REG
+ ip1811drv_dbg("RegList[%x][0x%02X]=0x%04x\n", pg, regaddr, RegList[pg][regaddr]);
+ RegList[pg][regaddr]=value;
+#else
+ ic_mdio_wr(((tmp)>>5)&0x1f,(tmp)&0x1f,value);
+#endif//TEST_REG
+
+#ifdef TEST_REG
+ ip1811drv_dbg("RegList[%x][0x%02X]=0x%04x\n", pg, regaddr, RegList[pg][regaddr]);
+#endif//TEST_REG
+
+ ip1811drv_dbg("write [%02X]=%04x\n", regaddr, value);
+}
+u16 Read_Reg(u8 regaddr)
+{
+ u16 u16d;
+ u16 tmp = CPU_IF_SPEED_NORMAL ? regaddr : (u16)regaddr << 2;
+#ifdef TEST_REG
+ u16d = RegList[pg][regaddr];
+#else
+ u16d=ic_mdio_rd(((tmp)>>5)&0x1f,(tmp)&0x1f);
+#endif//TEST_REG
+#ifdef TEST_REG
+ ip1811drv_dbg("RegList[%x][0x%02X]=0x%04x\n", pg, regaddr, RegList[pg][regaddr]);
+#endif//TEST_REG
+ ip1811drv_dbg("read [%02X]=%04x\n", regaddr, u16d);
+ return u16d;
+}
+
+void _Write_Reg(u8 regaddr, u16 value)
+{
+ u16 tmp = CPU_IF_SPEED_NORMAL ? regaddr : (u16)regaddr << 2;
+ ic_mdio_wr(((tmp)>>5)&0x1f,(tmp)&0x1f,value);
+
+ ip1811drv_dbg("write [%02X]=%04x\n", regaddr, value);
+}
+u16 _Read_Reg(u8 regaddr)
+{
+ u16 u16d;
+ u16 tmp = CPU_IF_SPEED_NORMAL ? regaddr : (u16)regaddr << 2;
+ u16d=ic_mdio_rd(((tmp)>>5)&0x1f,(tmp)&0x1f);
+ ip1811drv_dbg("read [%02X]=%04x\n", regaddr, u16d);
+ return u16d;
+}
+u16 Read_Reg_0_With_1s(void)
+{
+ u16 u16d;
+ u16 tmp = CPU_IF_SPEED_NORMAL ? 0x300 : 0x3;
+ u16d = ic_mdio_rd(((tmp)>>5)&0x1f,(tmp)&0x1f);
+ ip1811drv_dbg("read [%04X]=%04x\n", tmp, u16d);
+ return u16d;
+}
+void IP2Page(u8 page) // Change page to pagenum
+{
+ u16 tmp = CPU_IF_SPEED_NORMAL ? REG_Page : (u16)REG_Page << 2;
+#ifdef TEST_REG
+ pg = page;
+#else
+ ic_mdio_wr(((tmp)>>5)&0x1f,(tmp)&0x1f,page);
+#endif//TEST_REG
+ ip1811drv_dbg("set to page[%02u]\n", page);
+}
+void _IP2Page(u8 page) // Change page to pagenum
+{
+ u16 tmp = CPU_IF_SPEED_NORMAL ? REG_Page : (u16)REG_Page << 2;
+ ic_mdio_wr(((tmp)>>5)&0x1f,(tmp)&0x1f,page);
+ ip1811drv_dbg("set to page[%02u]\n", page);
+}
+/*============= sub. driver functions ==================*/
+static void _WriteRegBits(u8 page, u16 reg, u8 offset, u8 len, u16 val)
+{
+ u16 mask = 0;
+ u16 u16dat;
+
+ FUNC_MSG_IN;
+
+ IP2Page(page);
+ mask = (0x1 << len) - 1;
+ u16dat = Read_Reg(reg);
+ u16dat &= ~(mask<<offset);
+ u16dat |= (val&mask)<<offset;
+ Write_Reg(reg, u16dat);
+
+ FUNC_MSG_OUT;
+}
+
+static u16 _ReadRegBits(u8 page, u16 reg, u8 offset, u8 len)
+{
+ u16 mask = 0;
+ u16 u16dat;
+ u16 val;
+
+ FUNC_MSG_IN;
+
+ IP2Page(page);
+ mask = (0x1 << len) - 1;
+ u16dat = Read_Reg(reg);
+ val = (u16dat>>offset)&mask;
+
+ FUNC_MSG_OUT;
+ return val;
+}
+#if 0
+u16 _read_mii_register(u8 phy, u8 page, u8 reg)
+{
+ u8 option = MII_OP_READ;
+ u16 u16dat = 0;
+ IP2Page(3);
+
+ // change phy page
+ Write_Reg(P3REG_PHYACCESS_DATA, page);
+
+ u16dat = (phy & 0x1f); //PHY
+ u16dat |= (0x14 & 0x1f ) << 5; //MII Reg
+ u16dat |= (MII_OP_WRITE & 0x1 )<< 14;//Read or Write
+ u16dat |= 0x1 << 15;//Trigger & Write
+
+ Write_Reg(P3REG_PHYACCESS_CMD, u16dat);
+ while(_ReadRegBits(3, P3REG_PHYACCESS_CMD, 15, 1));
+ udelay(5000);
+
+ // phy read command
+ u16dat = 0;
+
+ u16dat = (phy & 0x1f); //PHY
+ u16dat |= (reg & 0x1f ) << 5;//MII Reg
+ u16dat |= (option & 0x1 )<< 14;//Read or Write
+ u16dat |= 0x1 << 15;//Trigger & Write
+
+ Write_Reg(P3REG_PHYACCESS_CMD, u16dat);
+ while(_ReadRegBits(3, P3REG_PHYACCESS_CMD, 15, 1));
+ udelay(5000);
+
+ return Read_Reg(P3REG_PHYACCESS_DATA);
+
+}
+
+u16 _write_mii_register(u8 phy, u8 page, u8 reg, u16 val, u8 all)
+{
+ u8 option = MII_OP_WRITE;
+ u16 u16dat = 0;
+ u8 count = 0;
+ IP2Page(3);
+
+ // change phy page
+ do
+ {
+ Write_Reg(P3REG_PHYACCESS_DATA, page);
+
+ u16dat = ((phy+(count*8)) & 0x1f); //PHY
+ u16dat |= (0x14 & 0x1f ) << 5; //MII Reg
+ u16dat |= (MII_OP_WRITE & 0x1 )<< 14;//Read or Write
+ u16dat |= 0x1 << 15;//Trigger & Write
+
+ Write_Reg(P3REG_PHYACCESS_CMD, u16dat);
+ while(_ReadRegBits(3, P3REG_PHYACCESS_CMD, 15, 1));
+ udelay(5000);
+ count = count + 1;
+ }while(all&&(count<3));
+
+ // phy write command
+ Write_Reg(P3REG_PHYACCESS_DATA, val);
+ u16dat = 0;
+
+ u16dat = (phy & 0x1f); //PHY
+ u16dat |= (reg & 0x1f ) << 5; //MII Reg
+ u16dat |= (all & 0x1) << 10; // write to all 24 phy
+ u16dat |= (option & 0x1 )<< 14;//Read or Write
+ u16dat |= 0x1 << 15;//Trigger & Write
+
+ Write_Reg(P3REG_PHYACCESS_CMD, u16dat);
+ while(_ReadRegBits(3, P3REG_PHYACCESS_CMD, 15, 1));
+ if(all)
+ udelay(30000);
+ else
+ udelay(5000);
+
+ return 0;
+}
+
+int get_mii_reg(void *cdata, int len)
+{
+ u8 phy, page, reg;
+ u16 u16dat;
+
+ if (sizeof(struct PhySetting) != len)
+ return -EINVAL;
+
+ phy = ((struct PhySetting *)cdata) ->phy;
+ page = ((struct PhySetting *)cdata) ->page;
+ reg = ((struct PhySetting *)cdata) ->reg;
+
+ if (phy >= 0x20)
+ return -EINVAL;
+
+ if (page >= 0x20)
+ return -EINVAL;
+
+ if (reg >= 0x20)
+ return -EINVAL;
+
+ u16dat = _read_mii_register(phy, page, reg);
+ ((struct PhySetting *)cdata) ->val = (unsigned short)u16dat;
+
+ return 0;
+}
+
+int set_mii_reg(void *cdata, int len)
+{
+ u8 phy, page, reg, all;
+ u16 val;
+ u16 u16dat;
+
+ if (sizeof(struct PhySetting) != len)
+ return -EINVAL;
+
+ phy = ((struct PhySetting *)cdata) ->phy;
+ page = ((struct PhySetting *)cdata) ->page;
+ reg = ((struct PhySetting *)cdata) ->reg;
+ val = ((struct PhySetting *)cdata) ->val;
+ all = ((struct PhySetting *)cdata) ->all; // if the command is set 24 phy,bit=1
+
+ if (phy >= 0x20)
+ return -EINVAL;
+
+ if (page >= 0x20)
+ return -EINVAL;
+
+ if (reg >= 0x20)
+ return -EINVAL;
+
+ if (all >= 2)
+ return -EINVAL;
+
+ u16dat = _write_mii_register(phy, page, reg, val, all);
+
+ return 0;
+}
+
+#endif
+static int _setGeneralEnable(void *cdata, int len, u8 page, u16 reg, u8 offset)
+{
+ int gdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ gdata = ((struct GeneralSetting *)cdata) ->gdata;
+ if( gdata != OP_FUNC_ENABLE && gdata != OP_FUNC_DISABLE ){
+ ip1811drv_err("Error: gdata=%X\n", gdata);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", gdata);
+
+ _WriteRegBits(page, reg, offset, 1, gdata);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+static int _getGeneralEnable(void *cdata, int len, u8 page, u16 reg, u8 offset)
+{
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ ((struct GeneralSetting *)cdata) ->gdata = _ReadRegBits(page, reg, offset, 1);
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+static int _setPortmapMask(void *cdata, int len, u8 page, u8 reg)
+{
+ unsigned long pm;
+ int pd;
+ u32 u32dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortmapSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ pm = ((struct PortmapSetting *)cdata) ->portmap;
+ pd = ((struct PortmapSetting *)cdata) ->pmdata;
+ if (pm & ~0x1FFFFFFF){
+ ip1811drv_err("Error: portmap=%08lX\n", pm);
+ return -EINVAL;
+ }
+ if (pd & ~0x1FFFFFFF){
+ ip1811drv_err("Error: pmdata=%X\n", pd);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("portmap=0x%08lX\n", pm);
+ ip1811drv_dbg("portdata=0x%08X\n", pd);
+
+ IP2Page(page);
+ u32dat = (u32)Read_Reg(reg+1)<<16 | (u32)Read_Reg(reg);
+
+ u32dat &= ~pm;
+ u32dat |= pm & pd;
+
+ Write_Reg(reg, (u16)(u32dat & 0xFFFF));
+ Write_Reg(reg+1, (u16)(u32dat >> 16));
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+static int _getPortmapMask(void *cdata, int len, u8 page, u8 reg)
+{
+ unsigned long pm;
+ u32 u32dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortmapSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ pm = ((struct PortmapSetting *)cdata) ->portmap;
+ if (pm & ~0x1FFFFFFF){
+ ip1811drv_err("Error: portmap=%08lX\n", pm);
+ return -EINVAL;
+ }
+
+ IP2Page(page);
+ u32dat = (u32)Read_Reg(reg+1)<<16 | (u32)Read_Reg(reg);
+ ((struct PortmapSetting *)cdata) ->pmdata = u32dat & pm;
+
+ ip1811drv_dbg("cdata ->portmap=0x%08lX\n", ((struct PortmapSetting *)cdata) ->portmap);
+ ip1811drv_dbg("cdata ->pmdata=0x%08X\n", ((struct PortmapSetting *)cdata) ->pmdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+
+static int _setPortmap(void *cdata, int len, u8 page, u8 reg)
+{
+ unsigned long pm;
+ int pd;
+ u16 u16dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortmapSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ pm = ((struct PortmapSetting *)cdata) ->portmap;
+ pd = ((struct PortmapSetting *)cdata) ->pmdata;
+
+ if (pm & ~0xFFF) {
+ ip1811drv_err("Error: portmap=%08lX\n", pm);
+ return -EINVAL;
+ }
+ if ((pd != OP_FUNC_ENABLE) && (pd != OP_FUNC_DISABLE)) {
+ ip1811drv_err("Error: pd=%X\n", pd);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("portmap=0x%08lX\n", pm);
+ ip1811drv_dbg("portdata=0x%X\n", pd);
+
+ IP2Page(page);
+ u16dat = Read_Reg(reg);
+
+#ifdef COMBINED_PORT
+ if ((pm >> 9) & 0x1)
+ pm |= (u16)(1 << 10);
+#endif
+
+ if (pd == OP_FUNC_ENABLE)
+ u16dat |= (u16)pm;
+ else//OP_FUNC_DISABLE
+ u16dat &= ~(u16)pm;
+
+ Write_Reg(reg, (u16dat & 0xFFF));
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+static int _getPortmap(void *cdata, int len, u8 page, u8 reg)
+{
+ unsigned long pm;
+ u16 u16dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortmapSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ pm = ((struct PortmapSetting *)cdata) ->portmap;
+
+ if (pm & ~0xFFF){
+ ip1811drv_err("Error: portmap=%08lX\n", pm);
+ return -EINVAL;
+ }
+ IP2Page(page);
+ u16dat = Read_Reg(reg);
+ u16dat &= (u16)pm;
+ ((struct PortmapSetting *)cdata) ->pmdata = u16dat;
+
+ ip1811drv_dbg("cdata ->pmdata=0x%08X\n", ((struct PortmapSetting *)cdata) ->pmdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+
+//------------------------------------------------
+//common_smi
+int switchdSetPortAN(int port, int an)
+{
+ u16 u16dat;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if ( !(an==OP_FUNC_DISABLE || an==OP_FUNC_ENABLE) )
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("an=%d\n", an);
+
+ IP2Page(3);
+ u16dat = Read_Reg(P3REG_AN);
+ if (an == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (an == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_AN, u16dat & 0xFFFF);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetPortAN);
+int setPortAN(void *cdata, int len)
+{
+ int port, an;
+
+ ip1811drv_dbg("ip1811: +setPortAN...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port=((struct ByPortSetting *)cdata) ->port;
+ an = ((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetPortAN(port, an) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setPortAN...\n");
+ return 0;
+}
+
+int switchdGetPortAN(int port, int *ptrInt)
+{
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *ptrInt = _ReadRegBits(3, P3REG_PORTSTS0 + port/2,6+(port&0x1)*8 , 1);
+ ip1811drv_dbg("an=0x%x\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetPortAN);
+int getPortAN(void *cdata, int len)
+{
+ int port, an;
+
+ ip1811drv_dbg("ip1811: +getPortAN...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetPortAN(port, &an) != 0)
+ return -EINVAL;
+
+ ((struct ByPortSetting *)cdata) ->pdata = an;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ ip1811drv_dbg("ip1811: -getPortAN...\n");
+ return 0;
+}
+
+int switchdSetPortSpeed(int port, int speed)
+{
+ u16 u16dat;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if ( !(speed==OP_SMI_SPEED_10 || speed==OP_SMI_SPEED_100 ||
+ (speed==OP_SMI_SPEED_1000 && port>=8)) )
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("speed=%d\n", speed);
+
+ IP2Page(3);
+ if (speed == OP_SMI_SPEED_1000)
+ {
+ u16dat = Read_Reg(P3REG_SPG);
+ u16dat |= (u16)(1 << (port-8));
+#ifdef COMBINED_PORT
+ if (port==9)
+ u16dat |= (u16)(1 << (port+1-8));
+#endif
+ Write_Reg(P3REG_SPG, u16dat);
+ }
+ else
+ {
+ if (port >= 8)
+ {
+ u16dat = Read_Reg(P3REG_SPG);
+ u16dat &= (u16)~(1 << (port-8));
+#ifdef COMBINED_PORT
+ if (port==9)
+ u16dat &= (u16)~(1 << (port+1-8));
+#endif
+ Write_Reg(P3REG_SPG, u16dat);
+ }
+
+ u16dat = (u16)( Read_Reg(P3REG_SP) );
+ if (speed == OP_SMI_SPEED_100)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (speed == OP_SMI_SPEED_100)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_SP, u16dat & 0xFFFF);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetPortSpeed);
+int setPortSpeed(void *cdata, int len)
+{
+ int port, speed;
+
+ ip1811drv_dbg("ip1811: +setPortSpeed...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+ speed= ((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetPortSpeed(port, speed) != 0)
+ return -EINVAL;
+ ip1811drv_dbg("ip1811: -setPortSpeed...\n");
+ return 0;
+}
+
+int switchdGetPortSpeed(int port, int *ptrInt)
+{
+ int speed;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ speed = (int) _ReadRegBits(3, P3REG_PORTSTS0 + port/2,1+(port&0x1)*8 , 2);
+ ip1811drv_dbg("speed=0x%x\n", speed);
+ if (speed & 0x2)
+ *ptrInt = OP_SMI_SPEED_1000;
+ else{
+ if (speed & 0x1)
+ *ptrInt = OP_SMI_SPEED_100;
+ else
+ *ptrInt = OP_SMI_SPEED_10;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetPortSpeed);
+int getPortSpeed(void *cdata, int len)
+{
+ int port, speed;
+
+ ip1811drv_dbg("ip1811: +getPortSpeed...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetPortSpeed(port, &speed) != 0)
+ return -EINVAL;
+ ((struct ByPortSetting *)cdata) ->pdata = speed;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ ip1811drv_dbg("ip1811: -getPortSpeed...\n");
+ return 0;
+}
+
+int switchdSetPortDuplex(int port, int dup)
+{
+ u16 u16dat;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if ( !(dup==OP_SMI_DUPLEX_HALF || dup==OP_SMI_DUPLEX_FULL) )
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("dup=%d\n", dup);
+
+ IP2Page(3);
+ u16dat = Read_Reg(P3REG_DUPLEX);
+ if (dup == OP_SMI_DUPLEX_FULL)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (dup == OP_SMI_DUPLEX_FULL)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_DUPLEX, u16dat & 0xFFFF);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetPortDuplex);
+int setPortDuplex(void *cdata, int len)
+{
+ int port, dup;
+
+ ip1811drv_dbg("ip1811: +setPortDuplex...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port=((struct ByPortSetting *)cdata) ->port;
+ dup =((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetPortDuplex(port, dup) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setPortDuplex...\n");
+ return 0;
+}
+
+int switchdGetPortDuplex(int port, int *ptrInt)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *ptrInt = (int) _ReadRegBits(3, P3REG_PORTSTS0 + port/2,(3+(port&0x1)*8), 1);
+ ip1811drv_dbg("dup=0x%x\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetPortDuplex);
+int getPortDuplex(void *cdata, int len)
+{
+ int port, dup;
+
+ ip1811drv_dbg("ip1811: +getPortDuplex...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetPortDuplex(port, &dup) != 0)
+ return -EINVAL;
+ ((struct ByPortSetting *)cdata) ->pdata = dup;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ ip1811drv_dbg("ip1811: -getPortDuplex...\n");
+ return 0;
+}
+
+int switchdSetPortPause(int port, int ps)
+{
+ u16 u16dat;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if ( !(ps==OP_FUNC_ENABLE || ps==OP_FUNC_DISABLE) )
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("ps=%d\n", ps);
+
+ IP2Page(3);
+ u16dat = Read_Reg(P3REG_PAUSE);
+ if (ps == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (ps == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_PAUSE, u16dat & 0xFFFF);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetPortPause);
+int setPortPause(void *cdata, int len)
+{
+ int port, ps;
+
+ ip1811drv_dbg("ip1811: +setPortPause...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port=((struct ByPortSetting *)cdata) ->port;
+ ps = ((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetPortPause(port, ps) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setPortPause...\n");
+ return 0;
+}
+
+int switchdGetPortPause(int port, int *ptrInt)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *ptrInt = (int) _ReadRegBits(3, P3REG_PORTSTS0 + port/2,4+(port&0x1)*8 , 1);
+ ip1811drv_dbg("ps=0x%x\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetPortPause);
+int getPortPause(void *cdata, int len)
+{
+ int port, ps;
+
+ ip1811drv_dbg("ip1811: +getPortPause...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetPortPause(port, &ps) != 0)
+ return -EINVAL;
+ ((struct ByPortSetting *)cdata) ->pdata = ps;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ ip1811drv_dbg("ip1811: -getPortPause...\n");
+ return 0;
+}
+
+int switchdSetPortAsymPause(int port, int aps)
+{
+ u16 u16dat;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if ( !(aps==OP_FUNC_ENABLE || aps==OP_FUNC_DISABLE) )
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("aps=%d\n", aps);
+
+ IP2Page(3);
+ u16dat = Read_Reg(P3REG_ASPAUSE);
+ if (aps == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (aps == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_ASPAUSE, u16dat & 0xFFFF);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetPortAsymPause);
+int setPortAsymPause(void *cdata, int len)
+{
+ int port, aps;
+
+ ip1811drv_dbg("ip1811: +setPortAsymPause...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port=((struct ByPortSetting *)cdata) ->port;
+ aps =((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetPortAsymPause(port, aps) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setPortAsymPause...\n");
+ return 0;
+}
+
+int switchdGetPortAsymPause(int port, int *ptrInt)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *ptrInt = (int) _ReadRegBits(3, P3REG_PORTSTS0 + port/2,5+(port&0x1)*8 , 1);
+ ip1811drv_dbg("aps=0x%x\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetPortAsymPause);
+int getPortAsymPause(void *cdata, int len)
+{
+ int port, aps;
+
+ ip1811drv_dbg("ip1811: +getPortAsymPause...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetPortAsymPause(port, &aps) != 0)
+ return -EINVAL;
+ ((struct ByPortSetting *)cdata) ->pdata = aps;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ ip1811drv_dbg("ip1811: -getPortAsymPause...\n");
+ return 0;
+}
+
+int switchdSetPortLinkStatus(struct LinkStatusSetting *avg)
+{
+ int port, sp, dup, ps, asym, an;
+ u16 u16dat;
+
+ port= avg->port;
+ sp = avg->speed;
+ dup = avg->duplex;
+ ps = avg->pause;
+ asym= avg->asym;
+ an = avg->an;
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if ( !(sp==OP_SMI_SPEED_10 || sp==OP_SMI_SPEED_100 || (sp==OP_SMI_SPEED_1000 && port>8)) )
+ return -EINVAL;
+ if ( !(dup==OP_SMI_DUPLEX_HALF || dup==OP_SMI_DUPLEX_FULL) )
+ return -EINVAL;
+ if ( !(ps==OP_FUNC_DISABLE || ps==OP_FUNC_ENABLE) )
+ return -EINVAL;
+ if ( !(asym==OP_FUNC_DISABLE || asym==OP_FUNC_ENABLE) )
+ return -EINVAL;
+ if ( !(an==OP_FUNC_DISABLE || an==OP_FUNC_ENABLE) )
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("sp=%d dup=%d ps=%d asym=%d an=%d\n",
+ sp, dup, ps, asym, an);
+
+ IP2Page(3);
+ if (sp == OP_SMI_SPEED_1000)
+ {
+ u16dat = Read_Reg(P3REG_SPG);
+ u16dat |= (u16)(1 << (port-8));
+#ifdef COMBINED_PORT
+ if (port==9){
+ u16dat |= (u16)(1 << (port+1-8));
+ }
+#endif
+ Write_Reg(P3REG_SPG, u16dat);
+ }
+ else
+ {
+ if (port >= 8)
+ {
+ u16dat = Read_Reg(P3REG_SPG);
+ u16dat &= (u16)~(1 << (port-8));
+#ifdef COMBINED_PORT
+ if (port==9){
+ u16dat &= (u16)~(1 << (port+1-8));
+ }
+#endif
+ Write_Reg(P3REG_SPG, u16dat);
+ }
+
+ u16dat = Read_Reg(P3REG_SP);
+ if (sp == OP_SMI_SPEED_100)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (sp == OP_SMI_SPEED_100)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_SP, u16dat & 0xFFFF);
+ }
+
+ u16dat = Read_Reg(P3REG_DUPLEX);
+ if (dup == OP_SMI_DUPLEX_FULL)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (dup == OP_SMI_DUPLEX_FULL)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_DUPLEX, u16dat & 0xFFFF);
+
+ u16dat = Read_Reg(P3REG_PAUSE);
+ if (ps == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (ps == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_PAUSE, u16dat & 0xFFFF);
+
+ u16dat = Read_Reg(P3REG_ASPAUSE);
+ if (asym == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (asym == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_ASPAUSE, u16dat & 0xFFFF);
+
+ u16dat = Read_Reg(P3REG_AN);
+ if (an == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (an == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_AN, u16dat & 0xFFFF);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetPortLinkStatus);
+int setPortLinkStatus(void *cdata, int len)
+{
+ int port, sp, dup, ps, asym, an;
+ u16 u16dat;
+ struct LinkStatusSetting *avg = (struct LinkStatusSetting *)cdata;
+
+ ip1811drv_dbg("ip1811: +setPortLinkStatus...\n");
+ if (sizeof(struct LinkStatusSetting) != len)
+ return -EINVAL;
+
+ if(switchdSetPortLinkStatus(avg) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setPortLinkStatus...\n");
+ return 0;
+}
+
+int switchdGetPortLinkStatus(struct LinkStatusSetting *cdata)
+{
+ int port, link, sp, dup, ps, asym, an, fiber;
+ u8 u8dat;
+ u16 u16dat;
+
+ port = ((struct LinkStatusSetting *)cdata) ->port;
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ IP2Page(3);
+ u8dat = P3REG_PORTSTS0 + port/2;
+ u16dat = Read_Reg(u8dat);
+ ip1811drv_dbg("u16dat=0x%04x\n", u16dat);
+ link=(int)( ( u16dat >> (0+(port&0x1)*8) ) & 0x1 );
+ sp = (int)( ( u16dat >> (1+(port&0x1)*8) ) & 0x3 );
+ if (sp & 0x2) sp = OP_SMI_SPEED_1000;
+ else
+ {
+ if (sp & 0x1) sp = OP_SMI_SPEED_100;
+ else sp = OP_SMI_SPEED_10;
+ }
+ dup =(int)( ( u16dat >> (3+(port&0x1)*8) ) & 0x1 );
+ ps = (int)( ( u16dat >> (4+(port&0x1)*8) ) & 0x1 );
+ asym=(int)( ( u16dat >> (5+(port&0x1)*8) ) & 0x1 );
+ an = (int)( ( u16dat >> (6+(port&0x1)*8) ) & 0x1 );
+ fiber = (int)( ( u16dat >> (7+(port&0x1)*8) ) & 0x1 );
+ ip1811drv_dbg("link=0x%x sp=%d dup=0x%x ps=0x%x asym=0x%x an=0x%x fiber=0x%x\n",
+ link, sp, dup, ps, asym, an, fiber);
+ ((struct LinkStatusSetting *)cdata) ->link = link;
+ ((struct LinkStatusSetting *)cdata) ->speed = sp;
+ ((struct LinkStatusSetting *)cdata) ->duplex = dup;
+ ((struct LinkStatusSetting *)cdata) ->pause = ps;
+ ((struct LinkStatusSetting *)cdata) ->asym = asym;
+ ((struct LinkStatusSetting *)cdata) ->an = an;
+ ((struct LinkStatusSetting *)cdata) ->fiber = fiber;
+ ip1811drv_dbg("cdata ->link=%d\n", ((struct LinkStatusSetting *)cdata) ->link);
+ ip1811drv_dbg("cdata ->speed=%d\n", ((struct LinkStatusSetting *)cdata) ->speed);
+ ip1811drv_dbg("cdata ->duplex=%d\n", ((struct LinkStatusSetting *)cdata) ->duplex);
+ ip1811drv_dbg("cdata ->pause=%d\n", ((struct LinkStatusSetting *)cdata) ->pause);
+ ip1811drv_dbg("cdata ->asym=%d\n", ((struct LinkStatusSetting *)cdata) ->asym);
+ ip1811drv_dbg("cdata ->an=%d\n", ((struct LinkStatusSetting *)cdata) ->an);
+ ip1811drv_dbg("cdata ->fiber=%d\n", ((struct LinkStatusSetting *)cdata) ->fiber);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetPortLinkStatus);
+int getPortLinkStatus(void *cdata, int len)
+{
+ struct LinkStatusSetting *avg = (struct LinkStatusSetting *)cdata;
+
+ ip1811drv_dbg("ip1811: +getPortLinkStatus...\n");
+ if (sizeof(struct LinkStatusSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetPortLinkStatus(avg) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -getPortLinkStatus...\n");
+ return 0;
+}
+
+int switchdSetPortBackpressure(int port, int bp)
+{
+ u16 u16dat;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if ( !(bp==OP_FUNC_ENABLE || bp==OP_FUNC_DISABLE) )
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("bp=%d\n", bp);
+
+ IP2Page(3);
+ u16dat = Read_Reg(P3REG_BPRESS);
+ if (bp == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (bp == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_BPRESS, u16dat & 0xFFFF);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetPortBackpressure);
+int setPortBackpressure(void *cdata, int len)
+{
+ int port, bp;
+
+ ip1811drv_dbg("ip1811: +setPortBackpressure...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port=((struct ByPortSetting *)cdata) ->port;
+ bp = ((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetPortBackpressure(port, bp) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setPortBackpressure...\n");
+ return 0;
+}
+
+int switchdGetPortBackpressure(int port, int *ptrInt)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *ptrInt = (int)_ReadRegBits(3, P3REG_BPRESS + port/16, port%16, 1);
+ ip1811drv_dbg("bp=0x%x\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetPortBackpressure);
+int getPortBackpressure(void *cdata, int len)
+{
+ int port, bp;
+
+ ip1811drv_dbg("ip1811: +getPortBackpressure...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetPortBackpressure(port, &bp) != 0)
+ return -EINVAL;
+ ((struct ByPortSetting *)cdata) ->pdata = bp;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ ip1811drv_dbg("ip1811: -getPortBackpressure...\n");
+ return 0;
+}
+
+int switchdSetPortPowerDown(int port, int pd)
+{
+ u16 u16dat;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if ( !(pd==OP_FUNC_ENABLE || pd==OP_FUNC_DISABLE) )
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("pd=%d\n", pd);
+
+ IP2Page(3);
+ u16dat = Read_Reg(P3REG_POWERDOWN);
+ if (pd == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+ Write_Reg(P3REG_POWERDOWN, u16dat & 0xFFFF);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetPortPowerDown);
+int setPortPowerDown(void *cdata, int len)
+{
+ int port, pd;
+
+ ip1811drv_dbg("ip1811: +setPortPowerDown...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port=((struct ByPortSetting *)cdata) ->port;
+ pd = ((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetPortPowerDown(port, pd) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setPortPowerDown...\n");
+ return 0;
+}
+
+int switchdGetPortPowerDown(int port, int *ptrInt)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+ *ptrInt = (int)_ReadRegBits(3, P3REG_POWERDOWN + port/16, port%16, 1);
+ ip1811drv_dbg("pd=0x%x\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetPortPowerDown);
+int getPortPowerDown(void *cdata, int len)
+{
+ int port, pd;
+
+ ip1811drv_dbg("ip1811: +getPortPowerDown...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetPortPowerDown(port, &pd) != 0)
+ return -EINVAL;
+ ((struct ByPortSetting *)cdata) ->pdata = pd;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ ip1811drv_dbg("ip1811: -getPortPowerDown...\n");
+ return 0;
+}
+
+int switchdSetPortForceLink(int port, int fl)
+{
+ u16 u16dat;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if ( !(fl==OP_FUNC_ENABLE || fl==OP_FUNC_DISABLE) )
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("fl=%d\n", fl);
+
+ IP2Page(3);
+ u16dat = Read_Reg(P3REG_FORCELINK);
+ if (fl == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (fl == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_FORCELINK, u16dat & 0xFFFF);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetPortForceLink);
+int setPortForceLink(void *cdata, int len)
+{
+ int port, fl;
+
+ ip1811drv_dbg("ip1811: +setPortForceLink...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port=((struct ByPortSetting *)cdata) ->port;
+ fl = ((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetPortForceLink(port, fl) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setPortForceLink...\n");
+ return 0;
+}
+
+int switchdGetPortForceLink(int port, int *ptrInt)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *ptrInt = (int)_ReadRegBits(3, P3REG_FORCELINK + port/16, port%16, 1);
+ ip1811drv_dbg("fl=0x%x\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetPortForceLink);
+int getPortForceLink(void *cdata, int len)
+{
+ int port, fl;
+
+ ip1811drv_dbg("ip1811: +getPortForceLink...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetPortForceLink(port, &fl) != 0)
+ return -EINVAL;
+ ((struct ByPortSetting *)cdata) ->pdata = fl;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ ip1811drv_dbg("ip1811: -getPortForceLink...\n");
+ return 0;
+}
+
+int switchdSetPortUniDirection(int port, int uni)
+{
+ u16 u16dat;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if ( !(uni==OP_FUNC_ENABLE || uni==OP_FUNC_DISABLE) )
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("uni=%d\n", uni);
+
+ IP2Page(3);
+ u16dat = Read_Reg(P3REG_UNIDIRECT);
+ if (uni == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port);
+ else
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (uni == OP_FUNC_ENABLE)
+ u16dat |= (u16)(1 << port+1);
+ else
+ u16dat &= (u16)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P3REG_UNIDIRECT, u16dat & 0xFFFF);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetPortUniDirection);
+int setPortUniDirection(void *cdata, int len)
+{
+ int port, uni;
+
+ ip1811drv_dbg("ip1811: +setPortUniDirection...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port=((struct ByPortSetting *)cdata) ->port;
+ uni =((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetPortUniDirection(port, uni) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setPortUniDirection...\n");
+ return 0;
+}
+
+int switchdGetPortUniDirection(int port, int *ptrInt)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *ptrInt = (int)_ReadRegBits(3, P3REG_UNIDIRECT + port/16, (port-1)%16, 1);
+ ip1811drv_dbg("uni=0x%x\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetPortUniDirection);
+int getPortUniDirection(void *cdata, int len)
+{
+ int port, uni;
+
+ ip1811drv_dbg("ip1811: +getPortUniDirection...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetPortUniDirection(port, &uni) != 0)
+ return -EINVAL;
+ ((struct ByPortSetting *)cdata) ->pdata = uni;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ ip1811drv_dbg("ip1811: -getPortUniDirection...\n");
+ return 0;
+}
+
+//------------------------------------------------
+//common_cap
+int switchdSetL2CapAct(int ptcl, int act)
+{
+ u32 u32dat, mask;
+
+ if (ptcl < OP_CAP_PTCL_BPDU || ptcl > OP_CAP_PTCL_GRP3)
+ return -EINVAL;
+ if (act!=OP_CAP_ACT_FORWARD && act!=OP_CAP_ACT_TO_CPU && act!=OP_CAP_ACT_DROP)
+ return -EINVAL;
+ ip1811drv_dbg("ptcl=%d\n", ptcl);
+ ip1811drv_dbg("act=%d\n", act);
+
+ IP2Page(0);
+ u32dat = ( Read_Reg(P0REG_L2FRAMEGETCTRL1) << 16 | Read_Reg(P0REG_L2FRAMEGETCTRL) );
+ mask = (u32)~(0x3 << (ptcl*2));
+ u32dat &= mask;
+ u32dat |= (u32)(act << (ptcl*2));
+ Write_Reg(P0REG_L2FRAMEGETCTRL, (u16)(u32dat & 0xFFFF));
+ Write_Reg(P0REG_L2FRAMEGETCTRL1, (u16)(u32dat >> 16));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetL2CapAct);
+int setL2CapAct(void *cdata, int len)
+{
+ int ptcl, act;
+
+ ip1811drv_dbg("ip1811: +setL2CapAct...\n");
+ if (sizeof(struct CapActSetting) != len)
+ return -EINVAL;
+
+ ptcl= ((struct CapActSetting *)cdata) ->protocol;
+ act = ((struct CapActSetting *)cdata) ->act;
+
+ if(switchdSetL2CapAct(ptcl, act) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setL2CapAct...\n");
+ return 0;
+}
+
+int switchdSetCapInBand(int gdata)
+{
+ if( gdata != OP_CAP_ACT_TO_CPU && gdata != OP_CAP_ACT_DROP ){
+ ip1811drv_err("Error: gdata=%X\n", gdata);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", gdata);
+
+ _WriteRegBits(0, P0REG_MACBEHAVIOR, 6, 1, (gdata==OP_CAP_ACT_TO_CPU?0x1:0x0));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetCapInBand);
+int setCapInBand(void *cdata, int len)
+{
+ int gdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ gdata = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetCapInBand(gdata) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdSetCapSwitchMac(unsigned char * mac)
+{
+ int i;
+ u16 u16dat;
+
+ for(i=0; i<6; i++)
+ ip1811drv_dbg("cdata ->mac[%d]=%X\n", i, mac[i]);
+ IP2Page(0);
+ for(i=0; i<3; i++){
+ u16dat = ((((u16)mac[i*2])&0xFF)<<8) | (((u16)mac[i*2+1])&0xFF);
+ Write_Reg(P0REG_MACADDRESS+(2-i), u16dat);
+ }
+}
+EXPORT_SYMBOL(switchdSetCapSwitchMac);
+int setCapSwitchMac(void *cdata, int len)
+{
+ char mac[6];
+
+ FUNC_MSG_IN;
+ if (sizeof(struct MACSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ memcpy(mac, ((struct MACSetting *)cdata) ->mac, 6);
+
+ switchdSetCapSwitchMac(mac);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetCapIpv6TcpUdpEnable(int enable)
+{
+ if(enable!=OP_FUNC_ENABLE && enable!=OP_FUNC_DISABLE) {
+ ip1811drv_err("Error: enable=%X\n", enable);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("enable=%d\n", enable);
+
+ _WriteRegBits(0, P0REG_IPV6RLTCFG, 0, 1, enable);
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetCapIpv6TcpUdpEnable);
+int setCapIpv6TcpUdpEnable(void *cdata, int len)
+{
+ int ret, en;
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ en = ((struct GeneralSetting *)cdata) ->gdata;
+
+ ret = switchdSetCapIpv6TcpUdpEnable(en);
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+//------------------------------------------------
+//common_lut
+int switchdSetSMACLearning(int port, int en)
+{
+ u32 u32dat;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if ( !(en==OP_FUNC_DISABLE || en==OP_FUNC_ENABLE) )
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("en=%d\n", en);
+
+ IP2Page(1);
+ u32dat = (u32)Read_Reg(P1REG_SRCLEARN_ENABLE);
+ if (en == OP_FUNC_ENABLE)
+ u32dat |= (u32)(1 << port);
+ else
+ u32dat &= (u32)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9){
+ if (en == OP_FUNC_ENABLE)
+ u32dat |= (u32)(1 << port+1);
+ else
+ u32dat &= (u32)~(1 << port+1);
+ }
+#endif
+ Write_Reg(P1REG_SRCLEARN_ENABLE, (u32dat & 0xFFF));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetSMACLearning);
+int setSMACLearning(void *cdata, int len)
+{
+ int port, en;
+
+ ip1811drv_dbg("ip1811: +setSMACLearning...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port=((struct ByPortSetting *)cdata) ->port;
+ en = ((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetSMACLearning(port, en) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setSMACLearning...\n");
+ return 0;
+}
+
+int switchdGetSMACLearning(int port, int *ptrInt)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *ptrInt = (int)_ReadRegBits(1, P1REG_SRCLEARN_ENABLE, port, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetSMACLearning);
+int getSMACLearning(void *cdata, int len)
+{
+ int port, en;
+
+ ip1811drv_dbg("ip1811: +getSMACLearning...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetSMACLearning(port, &en) != 0)
+ return -EINVAL;
+
+ ((struct ByPortSetting *)cdata) ->pdata = en;
+
+ ip1811drv_dbg("ip1811: -getSMACLearning...\n");
+ return 0;
+}
+
+int switchdSetLutPortFlush(unsigned long pm, int en)
+{
+ u16 u16dat;
+
+ if (pm & 0xF000)
+ return -EINVAL;
+ if ( en != OP_LUT_FLUSH_DYNAMIC_ONLY &&
+ en != OP_LUT_FLUSH_STATIC_ONLY &&
+ en != OP_LUT_FLUSH_ALL )
+ return -EINVAL;
+ ip1811drv_dbg("pm=0x%04x\n", (u16)pm);
+ ip1811drv_dbg("en=%d\n", en);
+
+ /* start to flush LUT */
+ IP2Page(1);
+ u16dat = 0x80;
+ if (en == OP_LUT_FLUSH_ALL)
+ u16dat |= (u16)0x40; // flush static entries
+ Write_Reg(P1REG_PORTFLUSH, (u16)(pm & 0x0FFF));
+ Write_Reg(P1REG_LUTFLUSH_CFG, u16dat);
+ udelay(10000);//flush LUT needs waiting at least 4 ms
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLutPortFlush);
+int setLutPortFlush(void *cdata, int len)
+{
+ unsigned long pm;
+ int en;
+
+ ip1811drv_dbg("ip1811: +setLutPortFlush...\n");
+ if (sizeof(struct PortmapSetting) != len)
+ return -EINVAL;
+
+ pm = ((struct PortmapSetting *)cdata) ->portmap;
+ en = ((struct PortmapSetting *)cdata) ->pmdata;
+
+ if(switchdSetLutPortFlush(pm, en) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setLutPortFlush...\n");
+ return 0;
+}
+
+int switchdSetLutAgingTime(int time)
+{
+ if (time > 18000)
+ return -EINVAL;
+ ip1811drv_dbg("time=%d\n", time);
+
+ _WriteRegBits(1, P1REG_LUTAGINGTIME, 0, 15, (u16)(time*1000/AGING_TIME_UNIT));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLutAgingTime);
+int setLutAgingTime(void *cdata, int len)
+{
+ int time;
+
+ ip1811drv_dbg("ip1811: +setLutAgingTime...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ time = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetLutAgingTime(time) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setLutAgingTime...\n");
+ return 0;
+}
+
+void switchdGetLutAgingTime(int *ptrInt)
+{
+ *ptrInt = ((int)_ReadRegBits(1, P1REG_LUTAGINGTIME, 0, 15))*AGING_TIME_UNIT/1000;
+}
+EXPORT_SYMBOL(switchdGetLutAgingTime);
+int getLutAgingTime(void *cdata, int len)
+{
+ int time;
+
+ ip1811drv_dbg("ip1811: +getLutAgingTime...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ switchdGetLutAgingTime(&time);
+
+ ((struct GeneralSetting *)cdata) ->gdata = time;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getLutAgingTime...\n");
+ return 0;
+}
+
+int switchdSetLutAgingTimeEnable(int en)
+{
+ if ( !(en==OP_FUNC_DISABLE || en==OP_FUNC_ENABLE) )
+ return -EINVAL;
+
+ ip1811drv_dbg("en=%d\n", en);
+
+ _WriteRegBits(1, P1REG_LUTAGINGTIME, 15, 1, (en==OP_FUNC_ENABLE)?0:1);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLutAgingTimeEnable);
+int setLutAgingTimeEnable(void *cdata, int len)
+{
+ int en;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ en = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetLutAgingTimeEnable(en) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetLutLearningNullSA(int en)
+{
+ if ( !(en==OP_FUNC_DISABLE || en==OP_FUNC_ENABLE) )
+ return -EINVAL;
+
+ ip1811drv_dbg("en=%d\n", en);
+
+ _WriteRegBits(1, P1REG_SRCLEARNCFG, 1, 1, en);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLutLearningNullSA);
+int setLutLearningNullSA(void *cdata, int len)
+{
+ int en;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ en = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetLutLearningNullSA(en) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetLutHashingAlgorithm(int hash)
+{
+ if ( !(hash==OP_HASH_DIRECT || hash==OP_HASH_CRC) )
+ return -EINVAL;
+
+ ip1811drv_dbg("hash=%d\n", hash);
+
+ _WriteRegBits(1, P1REG_SRCLEARNCFG, 2, 1, (hash==OP_HASH_CRC)?0:1);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLutHashingAlgorithm);
+int setLutHashingAlgorithm(void *cdata, int len)
+{
+ int hash;
+
+ ip1811drv_dbg("ip1811: +setLutHashingAlgorithm...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ hash = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetLutHashingAlgorithm(hash) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setLutHashingAlgorithm...\n");
+ return 0;
+}
+
+int switchdSetLutBindingEnable(int en)
+{
+ if ( !(en==OP_FUNC_DISABLE || en==OP_FUNC_ENABLE) )
+ return -EINVAL;
+
+ ip1811drv_dbg("en=%d\n", en);
+
+ _WriteRegBits(1, P1REG_SRCLEARNCFG, 5, 1, (en==OP_FUNC_ENABLE)?1:0);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLutBindingEnable);
+int setLutBindingEnable(void *cdata, int len)
+{
+ int en;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ en = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetLutBindingEnable(en) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetLutBindingEnable(int *ptrInt)
+{
+ *ptrInt = (int)(_ReadRegBits(1, P1REG_SRCLEARNCFG, 5, 1)?OP_FUNC_ENABLE:OP_FUNC_DISABLE);
+}
+EXPORT_SYMBOL(switchdGetLutBindingEnable);
+int getLutBindingEnable(void *cdata, int len)
+{
+ int en;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ switchdGetLutBindingEnable(&en);
+
+ ((struct GeneralSetting *)cdata) ->gdata = en;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+//------------------------------------------------
+//common_sniffer
+int switchdSetSnifferSrc(unsigned long pm)
+{
+ if (pm & 0xFFFFF000)
+ return -EINVAL;
+ ip1811drv_dbg("pm=0x%08x\n",(unsigned long)pm);
+
+ IP2Page(1);
+ Write_Reg(P1REG_SNIFSRC, (u16)(pm & 0xFFF));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetSnifferSrc);
+int setSnifferSrc(void *cdata, int len)
+{
+ unsigned long pm;
+
+ ip1811drv_dbg("ip1811: +setSnifferSrc...\n");
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ pm = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetSnifferSrc(pm) != 0)
+ return -EINVAL;
+ ip1811drv_dbg("ip1811: -setSnifferSrc...\n");
+ return 0;
+}
+
+int switchdGetSnifferSrc(u16 *u16dat)
+{
+ IP2Page(1);
+ *u16dat = (u16)Read_Reg(P1REG_SNIFSRC);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *u16dat);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetSnifferSrc);
+int getSnifferSrc(void *cdata, int len)
+{
+ u16 u16dat;
+
+ ip1811drv_dbg("ip1811: +getSnifferSrc...\n");
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetSnifferSrc(&u16dat) != 0)
+ return -EINVAL;
+
+ ((struct PortMemberSetting *)cdata) ->member = (u16dat & 0xFFF);
+ ip1811drv_dbg("cdata ->gdata=0x%08x\n",(unsigned int)((struct PortMemberSetting *)cdata) ->member);
+ ip1811drv_dbg("ip1811: -getSnifferSrc...\n");
+ return 0;
+}
+
+int switchdSetSnifferDestGrp1(unsigned long pm)
+{
+ u32 u32dat;
+
+ if (pm & 0xFFFFF000)
+ return -EINVAL;
+ ip1811drv_dbg("pm=0x%08x\n", (unsigned int)pm);
+
+ IP2Page(1);
+ u32dat = (u32)Read_Reg(P1REG_SNIFDEST);
+ u32dat = ((u32dat & 0xFFFFF000) | pm);
+ Write_Reg(P1REG_SNIFDEST, (u16)(u32dat & 0xFFF));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetSnifferDestGrp1);
+int setSnifferDestGrp1(void *cdata, int len)
+{
+ unsigned long pm;
+
+ ip1811drv_dbg("ip1811: +setSnifferDestGrp1...\n");
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ pm = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetSnifferDestGrp1(pm) != 0)
+ return -EINVAL;
+ ip1811drv_dbg("ip1811: -setSnifferDestGrp1...\n");
+ return 0;
+}
+
+int switchdGetSnifferDestGrp1(u16 *u16dat)
+{
+ IP2Page(1);
+ *u16dat = (u16)Read_Reg(P1REG_SNIFDEST);
+ ip1811drv_dbg("cdata ->pdata=%d\n", *u16dat);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetSnifferDestGrp1);
+int getSnifferDestGrp1(void *cdata, int len)
+{
+ u16 u16dat;
+
+ ip1811drv_dbg("ip1811: +getSnifferDestGrp1...\n");
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetSnifferDestGrp1(&u16dat) != 0)
+ return -EINVAL;
+
+ ((struct PortMemberSetting *)cdata) ->member = (u16dat & 0xFFF);
+ ip1811drv_dbg("cdata ->gdata=0x%08x\n", (unsigned int)((struct PortMemberSetting *)cdata) ->member);
+ ip1811drv_dbg("ip1811: -getSnifferDestGrp1...\n");
+ return 0;
+}
+
+int switchdSetS1Method(int method)
+{
+ if (method<OP_SNIFFER1_METHOD_DISABLE || method>OP_SNIFFER1_METHOD_BOTHDIR)
+ return -EINVAL;
+ ip1811drv_dbg("method=%d\n", method);
+
+ _WriteRegBits(1, P1REG_SNIFCFG, 0, 2, method);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetS1Method);
+int setS1Method(void *cdata, int len)
+{
+ int method;
+
+ ip1811drv_dbg("ip1811: +setS1Method...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ method = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetS1Method(method) != 0)
+ return -EINVAL;
+ ip1811drv_dbg("ip1811: -setS1Method...\n");
+ return 0;
+}
+
+int switchdGetS1Method(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(1, P1REG_SNIFCFG, 0, 2);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetS1Method);
+int getS1Method(void *cdata, int len)
+{
+ int method;
+
+ ip1811drv_dbg("ip1811: +getS1Method...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetS1Method(&method) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = method;
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getS1Method...\n");
+ return 0;
+}
+//------------------------------------------------
+//common_storm
+int switchdSetStormFunc(int storm, int porten)
+{
+ u8 u8dat=0;
+
+ if (storm!=OP_STORM_BCST && storm!=OP_STORM_MCST && storm!=OP_STORM_DLF &&
+ storm!=OP_STORM_ARP && storm!=OP_STORM_ICMP)
+ return -EINVAL;
+ if (porten<0 || (porten&0xFFFFF000))
+ return -EINVAL;
+ ip1811drv_dbg("storm=0x%02X\n", storm);
+ ip1811drv_dbg("porten=0x%08x\n", (unsigned int)porten);
+
+ IP2Page(1);
+ switch (storm){
+ case OP_STORM_BCST:
+ u8dat = P1REG_BSTORMEN;
+ break;
+ case OP_STORM_MCST:
+ u8dat = P1REG_MSTORMEN;
+ break;
+
+ case OP_STORM_DLF:
+ u8dat = P1REG_DLFSTORMEN;
+ break;
+
+ case OP_STORM_ARP:
+ u8dat = P1REG_ARPSTORMEN;
+ break;
+
+ case OP_STORM_ICMP:
+ u8dat = P1REG_ICMPSTORMEN;
+ break;
+ }
+ Write_Reg(u8dat, (u16)(porten & 0xFFFF));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetStormFunc);
+int setStormFunc(void *cdata, int len)
+{
+ u8 storm;
+ long porten;
+
+ ip1811drv_dbg("ip1811: +setStormFunc...\n");
+ if (sizeof(struct StormGeneralSetting) != len)
+ return -EINVAL;
+
+ storm = ((struct StormGeneralSetting *)cdata) ->storm;
+ porten= ((struct StormGeneralSetting *)cdata) ->sdata;
+
+ if(switchdSetStormFunc(storm, porten) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setStormFunc...\n");
+ return 0;
+}
+
+int switchdGetStormFunc(int storm, u32 *u32dat)
+{
+ u8 u8dat=0;
+
+ if (storm!=OP_STORM_BCST && storm!=OP_STORM_MCST && storm!=OP_STORM_DLF &&
+ storm!=OP_STORM_ARP && storm!=OP_STORM_ICMP)
+ return -EINVAL;
+ ip1811drv_dbg("storm=0x%02X\n", storm);
+
+ IP2Page(1);
+ switch (storm){
+ case OP_STORM_BCST:
+ u8dat = P1REG_BSTORMEN;
+ break;
+ case OP_STORM_MCST:
+ u8dat = P1REG_MSTORMEN;
+ break;
+ case OP_STORM_DLF:
+ u8dat = P1REG_DLFSTORMEN;
+ break;
+ case OP_STORM_ARP:
+ u8dat = P1REG_ARPSTORMEN;
+ break;
+ case OP_STORM_ICMP:
+ u8dat = P1REG_ICMPSTORMEN;
+ break;
+ }
+ *u32dat = (u32)Read_Reg(u8dat);
+
+ ip1811drv_dbg("cdata ->sdata=0x%08x\n", *u32dat);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetStormFunc);
+int getStormFunc(void *cdata, int len)
+{
+ u8 storm;
+ u32 u32dat;
+
+ ip1811drv_dbg("ip1811: +getStormFunc...\n");
+ if (sizeof(struct StormGeneralSetting) != len)
+ return -EINVAL;
+
+ storm = ((struct StormGeneralSetting *)cdata) ->storm;
+
+ if(switchdGetStormFunc(storm, &u32dat) != 0)
+ return -EINVAL;
+ ((struct StormGeneralSetting *)cdata) ->sdata = (long)u32dat;
+
+ ip1811drv_dbg("ip1811: -getStormFunc...\n");
+ return 0;
+}
+
+int switchdSetStormThreshold(u8 storm, long threshold)
+{
+ u8 u8dat=0;
+
+ if (storm!=OP_STORM_BCST && storm!=OP_STORM_MCST && storm!=OP_STORM_DLF &&
+ storm!=OP_STORM_ARP && storm!=OP_STORM_ICMP)
+ return -EINVAL;
+ if (threshold<0 || threshold>0xFF)
+ return -EINVAL;
+ ip1811drv_dbg("storm=0x%02X\n", storm);
+ ip1811drv_dbg("threshold=0x%08x\n", (unsigned int)threshold);
+
+ switch (storm)
+ {
+ case OP_STORM_BCST:
+ case OP_STORM_MCST:
+ case OP_STORM_DLF:
+ u8dat = P1REG_BSTORMTHRESH; break;
+
+ case OP_STORM_ARP:
+ u8dat = P1REG_ARPSTORMCFG; break;
+
+ case OP_STORM_ICMP:
+ u8dat = P1REG_ICMPSTORMCFG; break;
+ }
+ _WriteRegBits(1, u8dat, 0, 8, (u16)threshold);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetStormThreshold);
+int setStormThreshold(void *cdata, int len)
+{
+ u8 storm;
+ long threshold;
+
+ ip1811drv_dbg("ip1811: +setStormThreshold...\n");
+ if (sizeof(struct StormGeneralSetting) != len)
+ return -EINVAL;
+
+ storm = ((struct StormGeneralSetting *)cdata) ->storm;
+ threshold = ((struct StormGeneralSetting *)cdata) ->sdata;
+
+ if(switchdSetStormThreshold(storm, threshold) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setStormThreshold...\n");
+ return 0;
+}
+
+int switchdGetStormThreshold(u8 storm, long *ptrLong)
+{
+ u8 u8dat=0;
+ if (storm!=OP_STORM_BCST && storm!=OP_STORM_MCST && storm!=OP_STORM_DLF &&
+ storm!=OP_STORM_ARP && storm!=OP_STORM_ICMP)
+ return -EINVAL;
+ ip1811drv_dbg("storm=0x%02X\n", storm);
+
+ switch (storm)
+ {
+ case OP_STORM_BCST:
+ case OP_STORM_MCST:
+ case OP_STORM_DLF:
+ u8dat = P1REG_BSTORMTHRESH; break;
+
+ case OP_STORM_ARP:
+ u8dat = P1REG_ARPSTORMCFG; break;
+
+ case OP_STORM_ICMP:
+ u8dat = P1REG_ICMPSTORMCFG; break;
+ }
+ *ptrLong = (long)_ReadRegBits(1, u8dat, 0, 8);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetStormThreshold);
+int getStormThreshold(void *cdata, int len)
+{
+ u8 storm;
+ long threshold;
+
+ ip1811drv_dbg("ip1811: +getStormThreshold...\n");
+ if (sizeof(struct StormGeneralSetting) != len)
+ return -EINVAL;
+
+ storm = ((struct StormGeneralSetting *)cdata) ->storm;
+
+ if(switchdGetStormThreshold(storm, &threshold) != 0)
+ return -EINVAL;
+
+ ((struct StormGeneralSetting *)cdata) ->sdata = threshold;
+ ip1811drv_dbg("cdata ->sdata=0x%08x\n", (unsigned int)((struct StormGeneralSetting *)cdata) ->sdata);
+ ip1811drv_dbg("ip1811: -getStormThreshold...\n");
+ return 0;
+}
+
+int switchdSetStormCntrClrPeriod(u8 storm, long period)
+{
+ u8 reg=0;
+
+ if ( storm!=OP_STORM_BCST
+ && storm!=OP_STORM_MCST
+ && storm!=OP_STORM_DLF
+ && storm!=OP_STORM_ARP
+ && storm!=OP_STORM_ICMP)
+ return -EINVAL;
+ if (period<0 || period>3)
+ return -EINVAL;
+ ip1811drv_dbg("storm=0x%02X\n", storm);
+ ip1811drv_dbg("period=0x%X\n", (unsigned int)period);
+
+ switch (storm)
+ {
+ case OP_STORM_BCST:
+ case OP_STORM_MCST:
+ case OP_STORM_DLF:
+ reg = P1REG_BSTORMTHRESH;
+ break;
+ case OP_STORM_ARP:
+ reg = P1REG_ARPSTORMCFG;
+ break;
+ case OP_STORM_ICMP:
+ reg = P1REG_ICMPSTORMCFG;
+ break;
+ }
+ ip1811drv_dbg("cdata ->sdata=0x%X\n", (s16)period);
+
+ _WriteRegBits(1, reg, 8, 2, period);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetStormCntrClrPeriod);
+int setStormCntrClrPeriod(void *cdata, int len)
+{
+ u8 storm;
+ long period;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct StormGeneralSetting) != len)
+ return -EINVAL;
+
+ storm = ((struct StormGeneralSetting *)cdata) ->storm;
+ period = ((struct StormGeneralSetting *)cdata) ->sdata;
+
+ if(switchdSetStormCntrClrPeriod(storm, period) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdGetStormCntrClrPeriod(u8 storm, long *ptrInt)
+{
+ u8 reg =0;
+
+ if ( storm!=OP_STORM_BCST
+ && storm!=OP_STORM_MCST
+ && storm!=OP_STORM_DLF
+ && storm!=OP_STORM_ARP
+ && storm!=OP_STORM_ICMP)
+ return -EINVAL;
+ ip1811drv_dbg("storm=0x%02X\n", storm);
+
+ switch (storm)
+ {
+ case OP_STORM_BCST:
+ case OP_STORM_MCST:
+ case OP_STORM_DLF:
+ reg = P1REG_BSTORMTHRESH;
+ break;
+ case OP_STORM_ARP:
+ reg = P1REG_ARPSTORMCFG;
+ break;
+ case OP_STORM_ICMP:
+ reg = P1REG_ICMPSTORMCFG;
+ break;
+ }
+
+ *ptrInt = _ReadRegBits(1, reg, 8, 2);
+
+ ip1811drv_dbg("cdata ->sdata=0x%X\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetStormCntrClrPeriod);
+int getStormCntrClrPeriod(void *cdata, int len)
+{
+ u8 storm;
+ long period=0;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("ip1811: +getStormCntrClrPeriod...\n");
+ if (sizeof(struct StormGeneralSetting) != len)
+ {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ storm = ((struct StormGeneralSetting *)cdata) ->storm;
+
+ if(switchdGetStormCntrClrPeriod(storm, &period) != 0)
+ return -EINVAL;
+
+ ((struct StormGeneralSetting *)cdata) ->sdata = period;
+
+ ip1811drv_dbg("ip1811: -getStormCntrClrPeriod...\n");
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetStormBlockFrm2Cpu(int storm, int en)
+{
+ u8 u8dat=0;
+
+ if (storm!=OP_STORM_BCST && storm!=OP_STORM_MCST && storm!=OP_STORM_ARP)
+ return -EINVAL;
+ if (en!=OP_FUNC_DISABLE && en!=OP_FUNC_ENABLE)
+ return -EINVAL;
+ ip1811drv_dbg("storm=0x%02X\n", storm);
+ ip1811drv_dbg("en=0x%08x\n", (unsigned int)en);
+
+ switch (storm)
+ {
+ case OP_STORM_BCST:
+ case OP_STORM_MCST:
+ u8dat = P1REG_BSTORMTHRESH; break;
+
+ case OP_STORM_ARP:
+ u8dat = P1REG_ARPSTORMCFG; break;
+ }
+ _WriteRegBits(1, u8dat, 10, 1, en);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetStormBlockFrm2Cpu);
+int setStormBlockFrm2Cpu(void *cdata, int len)
+{
+ u8 storm = 0;
+ long en;
+
+ ip1811drv_dbg("ip1811: +setStormBlockFrm2Cpu...\n");
+ if (sizeof(struct StormGeneralSetting) != len)
+ return -EINVAL;
+
+ storm = ((struct StormGeneralSetting *)cdata) ->storm;
+ en = ((struct StormGeneralSetting *)cdata) ->sdata;
+
+ if(switchdSetStormBlockFrm2Cpu(storm, en) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setStormBlockFrm2Cpu...\n");
+ return 0;
+}
+
+int switchdGetStormBlockFrm2Cpu(u8 storm, int *ptrInt)
+{
+ u8 u8dat=0;
+
+ if (storm!=OP_STORM_BCST && storm!=OP_STORM_MCST && storm!=OP_STORM_ARP)
+ return -EINVAL;
+ ip1811drv_dbg("storm=0x%02X\n", storm);
+
+ switch (storm)
+ {
+ case OP_STORM_BCST:
+ case OP_STORM_MCST:
+ u8dat = P1REG_BSTORMTHRESH; break;
+
+ case OP_STORM_ARP:
+ u8dat = P1REG_ARPSTORMCFG; break;
+ }
+
+ *ptrInt = (int)_ReadRegBits(1, u8dat, 10, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetStormBlockFrm2Cpu);
+int getStormBlockFrm2Cpu(void *cdata, int len)
+{
+ u8 storm;
+ int en;
+
+ ip1811drv_dbg("ip1811: +getStormBlockFrm2Cpu...\n");
+ if (sizeof(struct StormGeneralSetting) != len)
+ return -EINVAL;
+
+ storm = ((struct StormGeneralSetting *)cdata) ->storm;
+
+ if(switchdGetStormBlockFrm2Cpu(storm, &en) != 0)
+ return -EINVAL;
+
+ ((struct StormGeneralSetting *)cdata) ->sdata = en;
+ ip1811drv_dbg("cdata ->sdata=0x%08x\n", (unsigned int)((struct StormGeneralSetting *)cdata) ->sdata);
+ ip1811drv_dbg("ip1811: -getStormBlockFrm2Cpu...\n");
+ return 0;
+}
+
+int switchdSetStormDropInterrupt(u8 storm, int en)
+{
+ if (storm!=OP_STORM_ARP && storm!=OP_STORM_ICMP)
+ return -EINVAL;
+ if (en!=OP_FUNC_DISABLE && en!=OP_FUNC_ENABLE)
+ return -EINVAL;
+ ip1811drv_dbg("storm=0x%02X\n", storm);
+ ip1811drv_dbg("en=0x%08x\n", en);
+
+ switch (storm)
+ {
+ case OP_STORM_ARP:
+ _WriteRegBits(1, P1REG_ARPSTORMCFG, 11, 1, (en == OP_FUNC_DISABLE)?0:1);
+ break;
+
+ case OP_STORM_ICMP:
+ _WriteRegBits(1, P1REG_ICMPSTORMCFG, 10, 1, (en == OP_FUNC_DISABLE)?0:1);
+ break;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetStormDropInterrupt);
+int setStormDropInterrupt(void *cdata, int len)
+{
+ u8 storm;
+ int en;
+
+ ip1811drv_dbg("ip1811: +setStormDropInterrupt...\n");
+ if (sizeof(struct StormGeneralSetting) != len)
+ return -EINVAL;
+
+ storm = ((struct StormGeneralSetting *)cdata) ->storm;
+ en = ((struct StormGeneralSetting *)cdata) ->sdata;
+
+ if(switchdSetStormDropInterrupt(storm, en) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setStormDropInterrupt...\n");
+ return 0;
+}
+
+int switchdGetStormDropInterrupt(u8 storm, int *ptrInt)
+{
+ if (storm!=OP_STORM_ARP && storm!=OP_STORM_ICMP)
+ return -EINVAL;
+ ip1811drv_dbg("storm=0x%02X\n", storm);
+
+ switch (storm)
+ {
+ case OP_STORM_ARP:
+ *ptrInt = (int)_ReadRegBits(1, P1REG_ARPSTORMCFG, 11, 1);
+ break;
+
+ case OP_STORM_ICMP:
+ *ptrInt = (int)_ReadRegBits(1, P1REG_ICMPSTORMCFG, 10, 1);
+ break;
+ }
+
+ ip1811drv_dbg("cdata ->sdata=0x%08x\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetStormDropInterrupt);
+int getStormDropInterrupt(void *cdata, int len)
+{
+ u8 storm;
+ int en;
+
+ ip1811drv_dbg("ip1811: +getStormDropInterrupt...\n");
+ if (sizeof(struct StormGeneralSetting) != len)
+ return -EINVAL;
+
+ storm = ((struct StormGeneralSetting *)cdata) ->storm;
+
+ if(switchdGetStormDropInterrupt(storm, &en) != 0)
+ return -EINVAL;
+
+ ((struct StormGeneralSetting *)cdata) ->sdata = en;
+
+ ip1811drv_dbg("ip1811: -getStormDropInterrupt...\n");
+ return 0;
+}
+
+//------------------------------------------------
+//common_loop_detect
+int switchdSetLdFunc(unsigned int pm, int en)
+{
+ u16 u16dat;
+ if (pm & 0xF000)
+ return -EINVAL;
+
+ ip1811drv_dbg("pm=0x%08x\n", pm);
+ ip1811drv_dbg("en=%d\n", en);
+ _WriteRegBits(1, P1REG_MISCCFG, 11, 1, en);
+
+ IP2Page(0);
+ u16dat = Read_Reg(P0REG_LDEN);
+ u16dat = ((u16dat & 0xF000) | pm);
+ Write_Reg(P0REG_LDEN, u16dat);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLdFunc);
+
+int setLdFunc(void *cdata, int len)
+{
+ unsigned long pm;
+ int en, ret;
+ u32 u32dat;
+
+ ip1811drv_dbg("ip1811: +setLdFunc...\n");
+ if (sizeof(struct PortmapSetting) != len) {
+ ret = -EINVAL;
+ goto out_setLdFunc;
+ }
+
+ pm = ((struct PortmapSetting *)cdata) ->portmap;
+ en = ((struct PortmapSetting *)cdata) ->pmdata;
+ ret = switchdSetLdFunc(pm, en);
+
+out_setLdFunc:
+ ip1811drv_dbg("ip1811: -setLdFunc...\n");
+ return ret;
+}
+
+int switchdGetLdFunc(unsigned long *portmap, int *pmdata)
+{
+ u16 u16dat;
+
+ IP2Page(1);
+ u16dat = Read_Reg(P1REG_MISCCFG);
+ if(u16dat & 0x0800)
+ *pmdata = OP_FUNC_ENABLE;
+ else
+ *pmdata = OP_FUNC_DISABLE;
+
+ IP2Page(0);
+ u16dat = Read_Reg(P0REG_LDEN);
+ *portmap = (u16dat & 0xFFF);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetLdFunc);
+
+int getLdFunc(void *cdata, int len)
+{
+ int ret;
+ int pmdata;
+ unsigned long portmap;
+
+ ip1811drv_dbg("ip1811: +getLdFunc...\n");
+ if (sizeof(struct PortmapSetting) != len) {
+ ret = -EINVAL;
+ goto out_getLdFunc;
+ }
+
+ ret = switchdGetLdFunc(&portmap, &pmdata);
+
+ ((struct PortmapSetting *)cdata) ->portmap = portmap;
+ ((struct PortmapSetting *)cdata) ->pmdata = pmdata;
+
+ ip1811drv_dbg("cdata ->portmap=0x%08x\n", ((struct PortmapSetting *)cdata) ->portmap);
+ ip1811drv_dbg("cdata ->pmdata=%d\n", ((struct PortmapSetting *)cdata) ->pmdata);
+
+out_getLdFunc:
+ ip1811drv_dbg("ip1811: -getLdFunc...\n");
+ return ret;
+}
+
+int switchdSetLdTimeUnit(int time_unit)
+{
+ if (time_unit!=OP_LD_TIME_UNIT_500MS && time_unit!=OP_LD_TIME_UNIT_10S)
+ return -EINVAL;
+ ip1811drv_dbg("tunit=%d\n", time_unit);
+
+ _WriteRegBits(0, P0REG_LDCONFIG, 0, 1, time_unit);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLdTimeUnit);
+
+int setLdTimeUnit(void *cdata, int len)
+{
+ int tunit, ret;
+
+ ip1811drv_dbg("ip1811: +setLdTimeUnit...\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ret = -EINVAL;
+ goto out_setLdTimeUnit;
+ }
+
+ tunit = ((struct GeneralSetting *)cdata) ->gdata;
+ ret = switchdSetLdTimeUnit(tunit);
+
+out_setLdTimeUnit:
+ ip1811drv_dbg("ip1811: -setLdTimeUnit...\n");
+ return ret;
+}
+
+int switchdGetLdTimeUnit(int *time_unit_get)
+{
+ *time_unit_get = (int)_ReadRegBits(0, P0REG_LDCONFIG, 0, 1);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetLdTimeUnit);
+
+int getLdTimeUnit(void *cdata, int len)
+{
+ int val, ret;
+ ip1811drv_dbg("ip1811: +getLdTimeUnit...\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ret = -EINVAL;
+ }
+
+ ret = switchdGetLdTimeUnit(&val);
+ ((struct GeneralSetting *)cdata) ->gdata = val;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+
+out_getLdTimeUnit:
+ ip1811drv_dbg("ip1811: -getLdTimeUnit...\n");
+ return ret;
+}
+
+int switchdSetLdPktSendTimer(int timer)
+{
+ if (timer < 0 || timer > 0xFF)
+ return -EINVAL;
+ ip1811drv_dbg("timer=%d\n", timer);
+
+ _WriteRegBits(0, P0REG_LDTIMER, 0, 8, timer);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLdPktSendTimer);
+
+int setLdPktSendTimer(void *cdata, int len)
+{
+ int timer, ret;
+
+ ip1811drv_dbg("ip1811: +setLdPktSendTimer...\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ret = -EINVAL;
+ goto out_setLdPktSendTimer;
+ }
+
+ timer = ((struct GeneralSetting *)cdata) ->gdata;
+ ret = switchdSetLdPktSendTimer(timer);
+
+out_setLdPktSendTimer:
+ ip1811drv_dbg("ip1811: -setLdPktSendTimer...\n");
+ return ret;
+}
+
+int switchdGetLdPktSendTimer(int *send_timer_get)
+{
+ *send_timer_get = (int)_ReadRegBits(0, P0REG_LDTIMER, 0, 8);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetLdPktSendTimer);
+
+int getLdPktSendTimer(void *cdata, int len)
+{
+ int val, ret;
+ ip1811drv_dbg("ip1811: +getLdPktSendTimer...\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ret = -EINVAL;
+ goto out_getLdPktSendTimer;
+ }
+
+ ret = switchdGetLdPktSendTimer(&val);
+ ((struct GeneralSetting *)cdata) ->gdata = val;
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+
+out_getLdPktSendTimer:
+ ip1811drv_dbg("ip1811: -getLdPktSendTimer...\n");
+ return ret;
+}
+
+int switchdSetLdBlockReleaseTimer(int timer)
+{
+ if (timer < 0 || timer > 0xFF)
+ return -EINVAL;
+ ip1811drv_dbg("timer=%d\n", timer);
+
+ _WriteRegBits(0, P0REG_LDTIMER, 8, 8, timer);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLdBlockReleaseTimer);
+
+int setLdBlockReleaseTimer(void *cdata, int len)
+{
+ int timer, ret;
+
+ ip1811drv_dbg("ip1811: +setLdBlockReleaseTimer...\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ret = -EINVAL;
+ goto out_setLdBlockReleaseTimer;
+ }
+
+ timer = ((struct GeneralSetting *)cdata) ->gdata;
+ ret = switchdSetLdBlockReleaseTimer(timer);
+
+out_setLdBlockReleaseTimer:
+ ip1811drv_dbg("ip1811: -setLdBlockReleaseTimer...\n");
+ return ret;
+}
+
+int switchdGetLdBlockReleaseTimer(int *release_timer_get)
+{
+ *release_timer_get = (int)_ReadRegBits(0, P0REG_LDTIMER, 8, 8);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetLdBlockReleaseTimer);
+
+int getLdBlockReleaseTimer(void *cdata, int len)
+{
+ int val, ret;
+ ip1811drv_dbg("ip1811: +getLdBlockReleaseTimer...\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ret = -EINVAL;
+ goto out_getLdBlockReleaseTimer;
+ }
+
+ ret = switchdGetLdBlockReleaseTimer(&val);
+ ((struct GeneralSetting *)cdata) ->gdata = val;
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+
+out_getLdBlockReleaseTimer:
+ ip1811drv_dbg("ip1811: -getLdBlockReleaseTimer...\n");
+ return ret;
+}
+
+int switchdGetLdStatus(unsigned long *status)
+{
+ IP2Page(0);
+ *status = Read_Reg(P0REG_LDSTATUS);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetLdStatus);
+
+int getLdStatus(void *cdata, int len)
+{
+ unsigned long val;
+ int ret;
+
+ ip1811drv_dbg("ip1811: +getLdStatus...\n");
+ if (sizeof(struct PortMemberSetting) != len) {
+ ret = -EINVAL;
+ goto out_getLdStatus;
+ }
+
+ ret = switchdGetLdStatus(&val);
+ ((struct PortMemberSetting *)cdata) ->member = val;
+ ip1811drv_dbg("cdata ->member=%08lX\n", ((struct PortMemberSetting *)cdata) ->member);
+
+out_getLdStatus:
+ ip1811drv_dbg("ip1811: -getLdStatus...\n");
+ return ret;
+}
+
+//ip1811_loop_detect
+int switchdSetLdDMAC(unsigned char *mac)
+{
+ int i;
+ u16 u16dat;
+
+ IP2Page(0);
+ for (i=0; i<3; i++) {
+ u16dat = (u16)( (mac[i*2] << 8) | mac[i*2+1] );
+ Write_Reg(P0REG_LDDA0+2-i, u16dat);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLdDMAC);
+
+int setLdDMAC(void *cdata, int len)
+{
+ int i, ret;
+ u8 da[6];
+
+ ip1811drv_dbg("ip1811: +setLdDMAC...\n");
+ if (sizeof(struct LDDASetting) != len) {
+ ret = -EINVAL;
+ goto out_setLdDMAC;
+ }
+
+ ip1811drv_dbg("da=[");
+ for (i=0; i<6; i++) {
+ da[i] = ((struct LDDASetting *)cdata) ->da[i];
+ ip1811drv_dbg("0x%02X, ", da[i]);
+ }
+ ip1811drv_dbg("]\n");
+ ret = switchdSetLdDMAC(da);
+
+out_setLdDMAC:
+ ip1811drv_dbg("ip1811: -setLdDMAC...\n");
+ return 0;
+}
+
+int switchdSetLdSubType(int stype)
+{
+ IP2Page(0);
+ Write_Reg(P0REG_LDSUBTYPE, (u16)stype);
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLdSubType);
+
+int setLdSubType(void *cdata, int len)
+{
+ int stype, ret;
+
+ ip1811drv_dbg("ip1811: +setLdSubType...\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ret = -EINVAL;
+ goto out_setLdSubType;
+ }
+
+ stype = ((struct GeneralSetting *)cdata) ->gdata;
+ if (stype<0 && stype>0xFFFF) {
+ ret = -EINVAL;
+ goto out_setLdSubType;
+ }
+ ip1811drv_dbg("stype=%d\n", stype);
+
+ ret = switchdSetLdSubType(stype);
+
+out_setLdSubType:
+ ip1811drv_dbg("ip1811: -setLdSubType...\n");
+ return 0;
+}
+//------------------------------------------------
+//common_stag
+int switchdSetCpuPortLink(int clink)
+{
+ if (clink!=OP_CPU_PORT_NORMAL && clink!=OP_CPU_PORT_CPU)
+ return -EINVAL;
+ ip1811drv_dbg("clink=%d\n", clink);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetCpuPortLink);
+int setCpuPortLink(void *cdata, int len)
+{
+ int clink;
+
+ ip1811drv_dbg("ip1811: +setCpuPortLink...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ clink = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetCpuPortLink(clink) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setCpuPortLink...\n");
+ return 0;
+}
+
+int switchdSetSTagFunc(int en)
+{
+ if (en!=OP_FUNC_DISABLE && en!=OP_FUNC_ENABLE)
+ return -EINVAL;
+ ip1811drv_dbg("en=%d\n", en);
+
+ if(en == OP_FUNC_ENABLE){
+ _WriteRegBits(0xE, PEREG_CPUMODE, 0, 2 , 0x3);
+ }else{
+ _WriteRegBits(0xE, PEREG_CPUMODE, 0, 2 , 0x0);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetSTagFunc);
+int setSTagFunc(void *cdata, int len)
+{
+ int en;
+
+ ip1811drv_dbg("ip1811: +setSTagFunc...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ en = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetSTagFunc(en) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setSTagFunc...\n");
+ return 0;
+}
+
+void switchdGetSTagTypeLen(unsigned short *ptrLength, unsigned short *ptrType)
+{
+ IP2Page(0xE);
+ *ptrType= Read_Reg(PEREG_SPTAG);
+ *ptrLength = 0;
+ ip1811drv_dbg("cdata ->length=%d\n", *ptrLength);
+ ip1811drv_dbg("cdata ->type=0x%08x\n", *ptrType);
+}
+EXPORT_SYMBOL(switchdGetSTagTypeLen);
+int getSTagTypeLen(void *cdata, int len)
+{
+ unsigned short type, length;
+
+ ip1811drv_dbg("ip1811: +getSTagTypeLen...\n");
+ if (sizeof(struct STagTypeLenSetting) != len)
+ return -EINVAL;
+
+ switchdGetSTagTypeLen(&length, &type);
+
+ ((struct STagTypeLenSetting *)cdata) ->length = (unsigned int)length;
+ ((struct STagTypeLenSetting *)cdata) ->type = (unsigned int)type;
+ ip1811drv_dbg("ip1811: -getSTagTypeLen...\n");
+ return 0;
+}
+
+//------------ PTP functions:common Start -----------------------
+int setPTPEnable(void *cdata, int len)
+{
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0, P0REG_PTPCFG, 0);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getPTPEnable(void *cdata, int len)
+{
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0, P0REG_PTPCFG, 0);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int setPTPDA011B19000000(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0, P0REG_PTPCFG, 1);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getPTPDA011B19000000(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0, P0REG_PTPCFG, 1);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int setPTPDA0180C200000E(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0, P0REG_PTPCFG, 2);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getPTPDA0180C200000E(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0, P0REG_PTPCFG, 2);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int setPTPUdpDP(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0, P0REG_PTPCFG, 3);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getPTPUdpDP(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0, P0REG_PTPCFG, 3);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int setPTPUdpSP(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0, P0REG_PTPCFG, 4);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getPTPUdpSP(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0, P0REG_PTPCFG, 4);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int setPTPToCPU(void *cdata, int len)
+{
+ int gdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ gdata = ((struct GeneralSetting *)cdata) ->gdata;
+ if( gdata != OP_CAP_ACT_TO_CPU && gdata != OP_CAP_ACT_FORWARD )
+ {
+ ip1811drv_err("Error: gdata=%X\n", gdata);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", gdata);
+
+ _WriteRegBits(0, P0REG_PTPCFG, 5, 1, gdata==OP_CAP_ACT_TO_CPU?0x0:0x1);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int getPTPToCPU(void *cdata, int len)
+{
+ int gdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ gdata = (_ReadRegBits(0, P0REG_PTPCFG, 5, 1)==0x0?OP_CAP_ACT_TO_CPU:OP_CAP_ACT_FORWARD);
+ ((struct GeneralSetting *)cdata) ->gdata = gdata;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", gdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int setPTPSpecialTag(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0x07, P7REG_TXDMA, 5);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getPTPSpecialTag(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0x07, P7REG_TXDMA, 5);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int setPTPClockReset(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0x09, P9REG_PTP_CLOCK_RESET, 0);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getPTPTimeStamp(void *cdata, int len){
+ unsigned int cmd=0, port=0;
+ struct PTPReadSetting* ps=(struct PTPReadSetting*)cdata;
+
+ if(sizeof(struct PTPReadSetting) != len)
+ return -EINVAL;
+
+ cmd=ps->addr;
+ cmd|=(ps->in_out)<<4;
+ port = ps->port;
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ cmd|=(port)<<5;
+ cmd|=0x8000;
+
+ IP2Page(0x09);
+ Write_Reg(P9REG_PTP_TIMESTAMP_READ, (u16)cmd);
+
+ while((Read_Reg(P9REG_PTP_TIMESTAMP_READ) >> 15)&0x1);
+
+ ps->second=Read_Reg(P9REG_PTP_TIMEDATA_SEC2);
+ ps->second<<=16;
+ ps->second=Read_Reg(P9REG_PTP_TIMEDATA_SEC1);
+ ps->second<<=16;
+ ps->second|=Read_Reg(P9REG_PTP_TIMEDATA_SEC0);
+ ps->nanosecond=Read_Reg(P9REG_PTP_TIMEDATA_NANOSEC1);
+ ps->nanosecond<<=16;
+ ps->nanosecond|=Read_Reg(P9REG_PTP_TIMEDATA_NANOSEC0);
+
+ return 0;
+}
+
+int setPTPClockEnable(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0x09, P9REG_PTP_CONFIGURATION, 0);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getPTPClockEnable(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0x09, P9REG_PTP_CONFIGURATION, 0);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int setPTPOverwriteEnable(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0x09, P9REG_PTP_CONFIGURATION, 1);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getPTPOverwriteEnable(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0x09, P9REG_PTP_CONFIGURATION, 1);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int setPTPProgrammable(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0x09, P9REG_PTP_CONFIGURATION, 2);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getPTPProgrammable(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0x09, P9REG_PTP_CONFIGURATION, 2);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int setPTPProgrammableOut(void *cdata, int len){
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0x09, P9REG_PTP_CONFIGURATION, 9);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int setPTPTimestampEnable(void *cdata, int len){
+ unsigned int cmd=0, i=0;
+ struct PTPPortTSSetting* pts=(struct PTPPortTSSetting*)cdata;
+
+ if(sizeof(struct PTPPortTSSetting)!=len)
+ return -EINVAL;
+ IP2Page(0x09);
+ for(i=0;i<MAX_PHY_NUM;i++){
+ if((i%8)==0){
+ cmd=Read_Reg(P9REG_PTP_PORT_TIMESTAMP0+(i/8));
+ }
+
+ if((pts->portmap&(0x01<<i))!=0){
+ if(pts->pmdata==OP_FUNC_ENABLE){
+ if(pts->in_out){
+ //egress
+ cmd|=0x01<<(1+(2*(i%8)));
+ }
+ else{
+ //ingress
+ cmd|=0x01<<(2*(i%8));
+ }
+ }
+ else{
+ if(pts->in_out){
+ //egress
+ cmd&=~(0x01<<(1+(2*(i%8))));
+ }
+ else{
+ //ingress
+ cmd&=~(0x01<<(2*(i%8)));
+ }
+ }
+ }
+ if((i%8)==7){
+ Write_Reg(P9REG_PTP_PORT_TIMESTAMP0+(i/8), (u16)cmd);
+ }
+ }
+ Write_Reg(P9REG_PTP_PORT_TIMESTAMP0+(i/8), (u16)cmd);
+
+ return 0;
+}
+
+int getPTPTimestampEnable(void *cdata, int len){
+ unsigned int cmd=0, i=0;
+ struct PTPPortTSSetting* pts=(struct PTPPortTSSetting*)cdata;
+
+ if(sizeof(struct PTPPortTSSetting)!=len)
+ return -EINVAL;
+
+ pts->pmdata=OP_FUNC_ENABLE;
+ pts->portmap=0;
+ IP2Page(0x09);
+ for(i=0;i<MAX_PHY_NUM;i++){
+ if((i%8)==0)
+ cmd=Read_Reg(P9REG_PTP_PORT_TIMESTAMP0+(i/8));
+
+ if(pts->in_out){
+ //egress
+ if((cmd&(0x01<<(1+(2*(i%8)))))!=0)
+ pts->portmap|=(0x01<<i);
+ }
+ else{
+ //ingress
+ if((cmd&(0x01<<(2*(i%8))))!=0)
+ pts->portmap|=(0x01<<i);
+ }
+ }
+
+ return 0;
+}
+
+int setPTPTimestampClear(void *cdata, int len){
+ unsigned int cmd=0, i=0;
+ struct PTPPortTSSetting* pts=(struct PTPPortTSSetting*)cdata;
+
+ if(sizeof(struct PTPPortTSSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ for(i=0;i<MAX_PHY_NUM;i++){
+ if((pts->portmap&(0x01<<i))!=0){
+ if(pts->in_out){
+ //egress
+ cmd|=0x01<<(1+(2*(i%8)));
+ }
+ else{
+ //ingress
+ cmd|=0x01<<(2*(i%8));
+ }
+ }
+ if((i%8)==7 && cmd!=0){
+ Write_Reg(P9REG_PTP_TIMESTAMP_CLEAR0+(i/8), (u16)cmd);
+ cmd=0;
+ }
+ }
+ if(cmd){
+ Write_Reg(P9REG_PTP_TIMESTAMP_CLEAR0+(i/8), (u16)cmd);
+ }
+
+ return 0;
+}
+
+int setPTPTimeData(void *cdata, int len){
+ struct PTPTimeSetting* ts=(struct PTPTimeSetting*)cdata;
+
+ if(sizeof(struct PTPTimeSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ Write_Reg(P9REG_PTP_TIMEDATA_SEC0, (u16)(ts->second&0xFFFF));
+ Write_Reg(P9REG_PTP_TIMEDATA_SEC1, (u16)((ts->second>>16)&0xFFFF));
+ Write_Reg(P9REG_PTP_TIMEDATA_SEC2, (u16)((ts->second>>32)&0xFFFF));
+ Write_Reg(P9REG_PTP_TIMEDATA_NANOSEC0, (u16)(ts->nanosecond&0xFFFF));
+ Write_Reg(P9REG_PTP_TIMEDATA_NANOSEC1, (u16)((ts->nanosecond>>16)&0x3FFF));
+ Write_Reg(P9REG_PTP_CLOCK_CONTROL, 0x03);
+
+ return 0;
+}
+
+int getPTPTimeData(void *cdata, int len){
+ struct PTPTimeSetting* ts=(struct PTPTimeSetting*)cdata;
+
+ if(sizeof(struct PTPTimeSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ Write_Reg(P9REG_PTP_TIMESTAMP_READ, 0);
+ Write_Reg(P9REG_PTP_CLOCK_CONTROL, 0x01);
+
+ ts->second=Read_Reg(P9REG_PTP_TIMEDATA_SEC2);
+ ts->second<<=16;
+ ts->second=Read_Reg(P9REG_PTP_TIMEDATA_SEC1);
+ ts->second<<=16;
+ ts->second|=Read_Reg(P9REG_PTP_TIMEDATA_SEC0);
+
+ ts->nanosecond=Read_Reg(P9REG_PTP_TIMEDATA_NANOSEC1);
+ ts->nanosecond<<=16;
+ ts->nanosecond|=Read_Reg(P9REG_PTP_TIMEDATA_NANOSEC0);
+
+ return 0;
+}
+
+int addPTPTimeData(void *cdata, int len){
+ struct PTPTimeSetting* ts=(struct PTPTimeSetting*)cdata;
+
+ if(sizeof(struct PTPTimeSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ Write_Reg(P9REG_PTP_TIMEDATA_SEC0, (u16)(ts->second&0xFFFF));
+ Write_Reg(P9REG_PTP_TIMEDATA_SEC1, (u16)((ts->second>>16)&0xFFFF));
+// Write_Reg(P9REG_PTP_TIMEDATA_SEC2, (u16)((ts->second>>32)&0xFFFF));
+ Write_Reg(P9REG_PTP_TIMEDATA_NANOSEC0, (u16)(ts->nanosecond&0xFFFF));
+ Write_Reg(P9REG_PTP_TIMEDATA_NANOSEC1, (u16)((ts->nanosecond>>16)&0x3FFF));
+ Write_Reg(P9REG_PTP_CLOCK_CONTROL, 0x05);
+
+ return 0;
+}
+
+int subPTPTimeData(void *cdata, int len){
+ struct PTPTimeSetting* ts=(struct PTPTimeSetting*)cdata;
+
+ if(sizeof(struct PTPTimeSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ Write_Reg(P9REG_PTP_TIMEDATA_SEC0, (u16)(ts->second&0xFFFF));
+ Write_Reg(P9REG_PTP_TIMEDATA_SEC1, (u16)((ts->second>>16)&0xFFFF));
+// Write_Reg(P9REG_PTP_TIMEDATA_SEC2, (u16)((ts->second>>32)&0xFFFF));
+ Write_Reg(P9REG_PTP_TIMEDATA_NANOSEC0, (u16)(ts->nanosecond&0xFFFF));
+ Write_Reg(P9REG_PTP_TIMEDATA_NANOSEC1, (u16)((ts->nanosecond>>16)&0x3FFF));
+ Write_Reg(P9REG_PTP_CLOCK_CONTROL, 0x07);
+
+ return 0;
+}
+
+int setPTPFrequencyAdd(void *cdata, int len){
+ struct PTPFrequencySetting* fs=(struct PTPFrequencySetting*)cdata;
+
+ if(sizeof(struct PTPFrequencySetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ Write_Reg(P9REG_PTP_FREQUENCY_ADD0, (u16)(fs->frequency&0xFFFF));
+ Write_Reg(P9REG_PTP_FREQUENCY_ADD1, (u16)((fs->frequency>>16)&0xFFFF));
+
+ return 0;
+}
+
+int getPTPFrequencyAdd(void *cdata, int len){
+ struct PTPFrequencySetting* fs=(struct PTPFrequencySetting*)cdata;
+
+ if(sizeof(struct PTPFrequencySetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ fs->frequency=Read_Reg(P9REG_PTP_FREQUENCY_ADD1);
+ fs->frequency<<=16;
+ fs->frequency|=Read_Reg(P9REG_PTP_FREQUENCY_ADD0);
+
+ return 0;
+}
+
+int setPTPClockPeriod(void *cdata, int len){
+ if(sizeof(struct GeneralSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ Write_Reg(P9REG_PTP_CLOCK_PERIOD, (u16)(((struct GeneralSetting*)cdata)->gdata)&0xFFFF);
+
+ return 0;
+}
+
+int getPTPClockPeriod(void *cdata, int len){
+ if(sizeof(struct GeneralSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ ((struct GeneralSetting*)cdata)->gdata=Read_Reg(P9REG_PTP_CLOCK_PERIOD);
+
+ return 0;
+}
+
+int setPTPProgrammableConfig(void *cdata, int len){
+ if(sizeof(struct GeneralSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ Write_Reg(P9REG_PTP_PROGRAMMABLE_OUTPUT, (u16)(((struct GeneralSetting*)cdata)->gdata)&0xFFFF);
+
+ return 0;
+}
+
+int setPTPDurationFrequencyCompensation(void *cdata, int len){
+ struct PTPFrequencySetting* fs=(struct PTPFrequencySetting*)cdata;
+
+ if(sizeof(struct PTPFrequencySetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ Write_Reg(P9REG_PTP_FREQUENCY_COMPENSATION0, (u16)(fs->frequency&0xFFFF));
+ Write_Reg(P9REG_PTP_FREQUENCY_COMPENSATION1, (u16)((fs->frequency>>16)&0x3FF));
+ Write_Reg(P9REG_PTP_FREQUENCY_COMPENSATION2, (u16)(fs->clockcycle&0xFFFF));
+ Write_Reg(P9REG_PTP_FREQUENCY_COMPENSATION3, (u16)((fs->clockcycle>>16)&0x3FF));
+ if(fs->type==1){
+ //add
+ Write_Reg(P9REG_PTP_FREQUENCY_COMPENSATION_CONTROL, 0x03);
+ }
+ else{
+ //sub
+ Write_Reg(P9REG_PTP_FREQUENCY_COMPENSATION_CONTROL, 0x07);
+ }
+ //Wait a period of time
+ ndelay(fs->period_time);
+
+ Write_Reg(P9REG_PTP_FREQUENCY_COMPENSATION_CONTROL, 0x0);
+
+ return 0;
+}
+
+int setPTPAlwaysFrequencyCompensation(void *cdata, int len){
+ struct PTPFrequencyPPMSetting* fps=(struct PTPFrequencyPPMSetting*)cdata;
+
+ if(sizeof(struct PTPFrequencyPPMSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ Write_Reg(P9REG_PTP_FREQUENCY_COMPENSATION0, (u16)(fps->ppm_l));
+ Write_Reg(P9REG_PTP_FREQUENCY_COMPENSATION1, (u16)(fps->ppm_h));
+ if(fps->type==1){
+ //add
+ Write_Reg(P9REG_PTP_FREQUENCY_COMPENSATION_CONTROL, 0x01);
+ }
+ else{
+ //Sub
+ Write_Reg(P9REG_PTP_FREQUENCY_COMPENSATION_CONTROL, 0x05);
+ }
+
+ return 0;
+}
+
+int getPTPIngressLatency10(void *cdata, int len){
+ if(sizeof(struct GeneralSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ ((struct GeneralSetting*)cdata)->gdata=Read_Reg(P9REG_PTP_INGRESS_LATENCY_10TP);
+
+ return 0;
+}
+
+int getPTPIngressLatency100(void *cdata, int len){
+ if(sizeof(struct GeneralSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ ((struct GeneralSetting*)cdata)->gdata=Read_Reg(P9REG_PTP_INGRESS_LATENCY_100TP);
+
+ return 0;
+}
+
+int getPTPIngressLatencyFiber(void *cdata, int len){
+ if(sizeof(struct GeneralSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ ((struct GeneralSetting*)cdata)->gdata=Read_Reg(P9REG_PTP_INGRESS_LATENCY_FIBER);
+
+ return 0;
+}
+
+int getPTPEgressLatency10(void *cdata, int len){
+ if(sizeof(struct GeneralSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ ((struct GeneralSetting*)cdata)->gdata=Read_Reg(P9REG_PTP_EGRESS_LATENCY_10TP);
+
+ return 0;
+}
+
+int getPTPEgressLatency100(void *cdata, int len){
+ if(sizeof(struct GeneralSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ ((struct GeneralSetting*)cdata)->gdata=Read_Reg(P9REG_PTP_EGRESS_LATENCY_100TP);
+
+ return 0;
+}
+
+int getPTPEgressLatencyFiber(void *cdata, int len){
+ if(sizeof(struct GeneralSetting)!=len)
+ return -EINVAL;
+
+ IP2Page(0x09);
+ ((struct GeneralSetting*)cdata)->gdata=Read_Reg(P9REG_PTP_EGRESS_LATENCY_FIBER);
+
+ return 0;
+}
+//------------ PTP functions:common end -----------------------
+
+int switchdConfigCpuPort(int portid)
+{
+ ip1811drv_dbg("portid=%d\n", portid);
+ if (portid < 0 || portid >= 12)
+ return -EINVAL;
+
+ IP2Page(1);
+ Write_Reg(P1REG_CONFIG_CPUPORT, (portid + 1) | 0x20);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdConfigCpuPort);
+int configCpuPort(void *cdata, int len)
+{
+ int portid;
+
+ ip1811drv_dbg("ip1811: +configCpuPort...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ portid = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdConfigCpuPort(portid) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -configCpuPort...\n");
+ return 0;
+}
+
+int switchdGetCpuPort(int *ptrVal)
+{
+ *ptrVal = Read_Reg(P1REG_CONFIG_CPUPORT);
+ ip1811drv_dbg("portid=%d\n", *ptrVal);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetCpuPort);
+int getCpuPort(void *cdata, int len)
+{
+ int portid;
+
+ ip1811drv_dbg("ip1811: +getCpuPort...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+
+ if(switchdGetCpuPort(&portid) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = portid;
+ ip1811drv_dbg("ip1811: -getCpuPort...\n");
+ return 0;
+}
+//------------------------------------------------
+//common_misc
+
+int switchdSet8021xFunc(int en, unsigned long pm)
+{
+ unsigned long reg16;
+
+ if (pm & 0xF0000000)
+ return -EINVAL;
+ if (en != OP_FUNC_ENABLE && en != OP_FUNC_DISABLE)
+ return -EINVAL;
+
+ IP2Page(0);
+ if(en == OP_FUNC_ENABLE) {
+ reg16 = Read_Reg(P0REG_PORTLOCKEN);
+ Write_Reg(P0REG_PORTLOCKEN, (u16)(reg16 | pm));
+ } else {//OP_FUNC_DISABLE
+ reg16 = Read_Reg(P0REG_PORTLOCKEN);
+ Write_Reg(P0REG_PORTLOCKEN, (u16)(reg16 & ~pm));
+ }
+ return 0;
+}
+EXPORT_SYMBOL(switchdSet8021xFunc);
+
+int set8021xFunc(void *cdata, int len)
+{
+ unsigned long pm;
+ int en, ret;
+
+ ip1811drv_dbg("ip1811: +set8021xFunc...\n");
+ if (sizeof(struct PortmapSetting) != len)
+ return -EINVAL;
+
+ pm = ((struct PortmapSetting *)cdata) ->portmap;
+ en = ((struct PortmapSetting *)cdata) ->pmdata;
+
+ ip1811drv_dbg("pm=0x%08x\n", (unsigned int)pm);
+ ip1811drv_dbg("en=%d\n", en);
+ ret = switchdSet8021xFunc(en, pm);
+
+ ip1811drv_dbg("ip1811: -set8021xFunc...\n");
+ return ret;
+}
+
+int switchdGet8021xFunc(int *gdata_p)
+{
+ IP2Page(0);
+ *gdata_p = (int)Read_Reg(P0REG_PORTLOCKEN);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGet8021xFunc);
+
+int get8021xFunc(void *cdata, int len)
+{
+ int val, ret;
+
+ ip1811drv_dbg("ip1811: +get8021xFunc...\n");
+ if (sizeof(struct PortmapSetting) != len)
+ return -EINVAL;
+
+ ret = switchdGet8021xFunc(&val);
+ ((struct PortmapSetting *)cdata) ->portmap = (val & ALL_PHY_PORTS_LIST);
+ ((struct PortmapSetting *)cdata) ->pmdata = val?OP_FUNC_ENABLE:OP_FUNC_DISABLE;
+ ip1811drv_dbg("cdata ->portmap=0x%08x\n", (unsigned int)((struct PortmapSetting *)cdata) ->portmap);
+ ip1811drv_dbg("cdata ->pmdata=%d\n", ((struct PortmapSetting *)cdata) ->pmdata);
+ ip1811drv_dbg("ip1811: -get8021xFunc...\n");
+ return ret;
+}
+
+int switchdSetReg(u8 page, u8 reg, u16 val)
+{
+ if (page > 0xE)
+ return -EINVAL;
+ ip1811drv_dbg("page=0x%x\n", page);
+ ip1811drv_dbg("reg=0x%02X\n", reg);
+ ip1811drv_dbg("val=0x%04x\n", val);
+
+ _IP2Page(page);
+ // ip1811drv_dbg("RegList[%x][0x%02X]=0x%04x\n", pg, P2REG_VLANCFG,
+ // RegList[pg][P2REG_VLANCFG]);
+ _Write_Reg(reg, val);
+
+ // ip1811drv_dbg("RegList[%x][0x%02X]=0x%04x\n", pg, P2REG_VLANCFG,
+ // RegList[pg][P2REG_VLANCFG]);
+ ip1811drv_dbg("ip1811: -setReg...\n");
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetReg);
+int setReg(void *cdata, int len)
+{
+ u8 page, reg;
+ u16 val;
+
+ ip1811drv_dbg("ip1811: +setReg...\n");
+ if (sizeof(struct RegSetting) != len)
+ return -EINVAL;
+
+ page= ((struct RegSetting *)cdata) ->page;
+ reg = ((struct RegSetting *)cdata) ->reg;
+ val = ((struct RegSetting *)cdata) ->val;
+
+ if(switchdSetReg(page, reg, val) != 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+
+int switchdGetReg(u8 page, u8 reg, u16 *ptrVal)
+{
+
+ if (page > 0xE)
+ return -EINVAL;
+ ip1811drv_dbg("page=0x%x\n", page);
+ printk("page=0x%x\n", page);
+ ip1811drv_dbg("reg=0x%02X\n", reg);
+ printk("reg=0x%02X\n", reg);
+
+ _IP2Page(page);
+ // ip1811drv_dbg("RegList[%x][0x%02X]=0x%04x\n", pg, P2REG_VLANCFG,
+ // RegList[pg][P2REG_VLANCFG]);
+ *ptrVal= _Read_Reg(reg);
+ ip1811drv_dbg("u16dat=0x%04x\n", *ptrVal);
+ printk("u16dat=0x%04x\n", *ptrVal);
+
+ // ip1811drv_dbg("RegList[%x][0x%02X]=0x%04x\n", pg, P2REG_VLANCFG,
+ // RegList[pg][P2REG_VLANCFG]);
+ ip1811drv_dbg("cdata ->val=0x%04x\n", *ptrVal);
+ ip1811drv_dbg("ip1811: -getReg...\n");
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetReg);
+int getReg(void *cdata, int len)
+{
+ u8 page, reg;
+ u16 u16dat;
+
+ printk("ip1811: +getReg...\n");
+ ip1811drv_dbg("ip1811: +getReg...\n");
+ if (sizeof(struct RegSetting) != len)
+ return -EINVAL;
+
+ page= ((struct RegSetting *)cdata) ->page;
+ reg = ((struct RegSetting *)cdata) ->reg;
+
+ if(switchdGetReg(page, reg, &u16dat) != 0)
+ return -EINVAL;
+
+ ((struct RegSetting *)cdata) ->val = (unsigned short)u16dat;
+ return 0;
+}
+
+void switchdGetCPUReg(unsigned long reg, int * ptrVal)
+{
+ volatile unsigned int *p;
+
+ p = (unsigned int *)(reg);
+ *ptrVal = *p;
+
+ ip1811drv_dbg("reg=%lX\n", reg);
+ ip1811drv_dbg("get val=%X\n", *ptrVal);
+}
+EXPORT_SYMBOL(switchdGetCPUReg);
+int getCPUReg(void *cdata, int len)
+{
+ unsigned long reg;
+ int val;
+
+ FUNC_MSG_IN;
+
+ if (sizeof(struct PortmapSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ reg = ((struct PortmapSetting *)cdata) ->portmap;
+
+ switchdGetCPUReg(reg, &val);
+
+ ((struct PortmapSetting *)cdata) ->pmdata = val;
+ ip1811delay();
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdSetCPUReg(unsigned long reg, int val)
+{
+ volatile unsigned int *p;
+
+ p = (unsigned int *)(reg);
+ *p = val;
+
+ ip1811drv_dbg("reg=%lX\n", reg);
+ ip1811drv_dbg("set val=%X\n", val);
+}
+EXPORT_SYMBOL(switchdSetCPUReg);
+int setCPUReg(void *cdata, int len)
+{
+ unsigned long reg;
+ int val;
+
+ FUNC_MSG_IN;
+
+ if (sizeof(struct PortmapSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ reg = ((struct PortmapSetting *)cdata) ->portmap;
+ val = ((struct PortmapSetting *)cdata) ->pmdata;
+
+ switchdSetCPUReg(reg, val);
+
+ ip1811delay();
+
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetSwitchRestart(int en)
+{
+ if(en!=OP_FUNC_ENABLE){
+ ip1811drv_err("Error: en=%d\n", en);
+ return -EINVAL;
+ }
+ ip1811drv_dbg("reset the switch of IP1811, all parameters are maintained\n");
+ _WriteRegBits(0xE, PEREG_SW_RESET, 0, 1, en);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetSwitchRestart);
+int setSwitchRestart(void *cdata, int len)
+{
+ int en;
+ FUNC_MSG_IN;
+
+ if (sizeof(struct GeneralSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ en = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetSwitchRestart(en) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetSwitchReset(int en)
+{
+
+ if(en!=OP_FUNC_ENABLE){
+ ip1811drv_err("Error: en=%d\n", en);
+ return -EINVAL;
+ }
+ ip1811drv_dbg("reset the switch of IP1811, all parameters are reset to default\n");
+ _WriteRegBits(0xE, PEREG_SW_RESET, 4, 1, en);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetSwitchReset);
+int setSwitchReset(void *cdata, int len)
+{
+ int en;
+
+ FUNC_MSG_IN;
+
+ if (sizeof(struct GeneralSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ en = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetSwitchReset(en) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdSetCpuIfSpeed(int type)
+{
+ CPU_IF_SPEED_NORMAL = type;
+ printk("\nip1811: set CPU I/F speed to %s\n",CPU_IF_SPEED_NORMAL?"Normal":"High");
+}
+EXPORT_SYMBOL(switchdSetCpuIfSpeed);
+int setCpuIfSpeed(void *cdata, int len)
+{
+ int type;
+ FUNC_MSG_IN;
+
+ if (sizeof(struct GeneralSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ switchdSetCpuIfSpeed(type);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+//------------ CoS functions:common -----------------------------
+int setCosTcpUdpUserDefine(void *cdata, int len)
+{
+ unsigned int ptcl;
+ int act;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct CapActSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ ptcl = ((struct CapActSetting *)cdata) ->protocol;
+ act = ((struct CapActSetting *)cdata) ->act;
+
+ if( ptcl >= OP_TCPUDP_USER_TOTALNUM)
+ {
+ ip1811drv_err("Error: protocol=%X\n", ptcl);
+ return -EINVAL;
+ }
+
+ if( act < 0x0 || act > 0xFFFF )
+ {
+ ip1811drv_err("Error: act=%X\n", act);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->ptcl=%X\n", ptcl);
+ ip1811drv_dbg("cdata ->act=%X\n", act);
+
+ IP2Page(0);
+ Write_Reg(P0REG_TCPUDPUSERDEF + ptcl, (u16)act);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int getCosTcpUdpUserDefine(void *cdata, int len)
+{
+ unsigned int ptcl;
+ int act;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct CapActSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ ptcl = ((struct CapActSetting *)cdata) ->protocol;
+
+ if( ptcl >= OP_TCPUDP_USER_TOTALNUM)
+ {
+ ip1811drv_err("Error: protocol=%X\n", ptcl);
+ return -EINVAL;
+ }
+
+ IP2Page(0);
+ act = Read_Reg(P0REG_TCPUDPUSERDEF + ptcl);
+ ((struct CapActSetting *)cdata) ->act = act;
+
+ ip1811drv_dbg("cdata ->protocol=%X\n", ((struct CapActSetting *)cdata) ->protocol);
+ ip1811drv_dbg("cdata ->act=%X\n", ((struct CapActSetting *)cdata) ->act);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int setCosTcpUdpQueue(void *cdata, int len)
+{
+ unsigned int ptcl;
+ int act;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct CapActSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ ptcl = ((struct CapActSetting *)cdata) ->protocol;
+ act = ((struct CapActSetting *)cdata) ->act;
+
+ if( ptcl >= OP_TCPUDP_PTCL_TOTALNUM)
+ {
+ ip1811drv_err("Error: protocol=%X\n", ptcl);
+ return -EINVAL;
+ }
+
+ if( act < OP_TCPUDP_ACT_Q0 || act > OP_TCPUDP_ACT_ALL_PORT || act == 0x8)
+ {
+ ip1811drv_err("Error: act=%X\n", act);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->ptcl=%X\n", ptcl);
+ ip1811drv_dbg("cdata ->act=%X\n", act);
+
+ _WriteRegBits(0, P0REG_TCPUDPPRICFG + ptcl/4, (ptcl%4)*4, 4, act);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int getCosTcpUdpQueue(void *cdata, int len)
+{
+ unsigned int ptcl;
+ int act;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct CapActSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ ptcl = ((struct CapActSetting *)cdata) ->protocol;
+
+ if( ptcl >= OP_TCPUDP_PTCL_TOTALNUM)
+ {
+ ip1811drv_err("Error: protocol=%X\n", ptcl);
+ return -EINVAL;
+ }
+
+ act = _ReadRegBits(0, P0REG_TCPUDPPRICFG + (ptcl/4), (ptcl%4)*4, 4);
+ ((struct CapActSetting *)cdata) ->act = act;
+
+ ip1811drv_dbg("cdata ->protocol=%X\n", ((struct CapActSetting *)cdata) ->protocol);
+ ip1811drv_dbg("cdata ->act=%X\n", ((struct CapActSetting *)cdata) ->act);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int setCosTcpUdpEnable(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setPortmap(cdata, len, 0, P0REG_TCPUDFUNCEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int getCosTcpUdpEnable(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getPortmapMask(cdata, len, 0, P0REG_TCPUDFUNCEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int setCosTcpEnable(void *cdata, int len)
+{
+ unsigned int ptcl;
+ int act;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct CapActSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ ptcl = ((struct CapActSetting *)cdata) ->protocol;
+ act = ((struct CapActSetting *)cdata) ->act;
+
+ if( ptcl >= OP_TCPUDP_PTCL_TOTALNUM)
+ {
+ ip1811drv_err("Error: protocol=%X\n", ptcl);
+ return -EINVAL;
+ }
+
+ if( act != OP_FUNC_ENABLE && act != OP_FUNC_DISABLE)
+ {
+ ip1811drv_err("Error: act=%X\n", act);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->ptcl=%X\n", ptcl);
+ ip1811drv_dbg("cdata ->act=%X\n", act);
+
+ /* check L3 TCP action */
+ if(_ReadRegBits(0, P0REG_L3FRAMEGETCTRL, 2, 2) == OP_CAP_ACT_DROP)
+ {
+ ip1811drv_err("Error: L3 TCP action is drop\n");
+ return -EINVAL;
+ }
+
+ /* set register */
+ _WriteRegBits(0, P0REG_TCPCHECKEN + (ptcl/16), (ptcl%16), 1, act);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int getCosTcpEnable(void *cdata, int len)
+{
+ unsigned int ptcl;
+ int act;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct CapActSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ ptcl = ((struct CapActSetting *)cdata) ->protocol;
+
+ if( ptcl >= OP_TCPUDP_PTCL_TOTALNUM)
+ {
+ ip1811drv_err("Error: protocol=%X\n", ptcl);
+ return -EINVAL;
+ }
+
+ act = _ReadRegBits(0, P0REG_TCPCHECKEN + (ptcl/16), (ptcl%16), 1);
+ ((struct CapActSetting *)cdata) ->act = act;
+
+ ip1811drv_dbg("cdata ->protocol=%X\n", ((struct CapActSetting *)cdata) ->protocol);
+ ip1811drv_dbg("cdata ->act=%X\n", ((struct CapActSetting *)cdata) ->act);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int setCosUdpEnable(void *cdata, int len)
+{
+ unsigned int ptcl;
+ int act;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct CapActSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ ptcl = ((struct CapActSetting *)cdata) ->protocol;
+ act = ((struct CapActSetting *)cdata) ->act;
+
+ if( ptcl >= OP_TCPUDP_PTCL_TOTALNUM)
+ {
+ ip1811drv_err("Error: protocol=%X\n", ptcl);
+ return -EINVAL;
+ }
+
+ if( act != OP_FUNC_ENABLE && act != OP_FUNC_DISABLE)
+ {
+ ip1811drv_err("Error: act=%X\n", act);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->ptcl=%X\n", ptcl);
+ ip1811drv_dbg("cdata ->act=%X\n", act);
+
+ /* check L3 UDP action */
+ if(_ReadRegBits(0, P0REG_L3FRAMEGETCTRL, 4, 2) == OP_CAP_ACT_DROP)
+ {
+ ip1811drv_err("Error: L3 UDP action is drop\n");
+ return -EINVAL;
+ }
+
+ /* set register */
+ _WriteRegBits(0, (P0REG_UDPCHECKEN + ptcl/16), (ptcl%16), 1, act);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int getCosUdpEnable(void *cdata, int len)
+{
+ unsigned int ptcl;
+ int act;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct CapActSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ ptcl = ((struct CapActSetting *)cdata) ->protocol;
+
+ if( ptcl >= OP_TCPUDP_PTCL_TOTALNUM)
+ {
+ ip1811drv_err("Error: protocol=%X\n", ptcl);
+ return -EINVAL;
+ }
+
+ act = _ReadRegBits(0, (P0REG_UDPCHECKEN + ptcl/16), (ptcl%16), 1);
+ ((struct CapActSetting *)cdata) ->act = act;
+
+ ip1811drv_dbg("cdata ->protocol=%X\n", ((struct CapActSetting *)cdata) ->protocol);
+ ip1811drv_dbg("cdata ->act=%X\n", ((struct CapActSetting *)cdata) ->act);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int setCosTcpFlagDropNull(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0, P0REG_TCPFLGCFGGLB, 0);
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int getCosTcpFlagDropNull(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0, P0REG_TCPFLGCFGGLB, 0);
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int setCosTcpFlagDropAllset(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0, P0REG_TCPFLGCFGGLB, 1);
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int getCosTcpFlagDropAllset(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0, P0REG_TCPFLGCFGGLB, 1);
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int setCosTcpFlag(void *cdata, int len)
+{
+ unsigned int index;
+ int fdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct TcpFlagSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ index = ((struct TcpFlagSetting *)cdata) ->index;
+ if( index > OP_TCPFLAG_FLAG3 )
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ fdata = ((struct TcpFlagSetting *)cdata) ->fdata;
+ if( fdata < 0x0 || fdata > 0xFF )
+ {
+ ip1811drv_err("Error: flag=%X\n", fdata);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->index=%X\n", index);
+ ip1811drv_dbg("cdata ->fdata=%X\n", fdata);
+
+ _WriteRegBits(0, P0REG_TCPFLGCFG0 + index, 0, 8, fdata);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int getCosTcpFlag(void *cdata, int len)
+{
+ unsigned int index;
+ int fdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct TcpFlagSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ index = ((struct TcpFlagSetting *)cdata) ->index;
+ if( index > OP_TCPFLAG_FLAG3 )
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ fdata = _ReadRegBits(0, P0REG_TCPFLGCFG0 + index, 0, 8);
+ ((struct TcpFlagSetting *)cdata) ->index = fdata;
+ ip1811drv_dbg("cdata ->index=%X\n", index);
+ ip1811drv_dbg("cdata ->fdata=%X\n", fdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int setCosTcpFlagAct(void *cdata, int len)
+{
+ unsigned int index;
+ int fdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct TcpFlagSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ index = ((struct TcpFlagSetting *)cdata) ->index;
+ if( index > OP_TCPFLAG_FLAG3 )
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ fdata = ((struct TcpFlagSetting *)cdata) ->fdata;
+ if( fdata < OP_TCPFLAG_ACT_NONE || fdata > OP_TCPFLAG_ACT_DROP )
+ {
+ ip1811drv_err("Error: act=%X\n", fdata);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->index=%X\n", index);
+ ip1811drv_dbg("cdata ->fdata=%X\n", fdata);
+
+ IP2Page(0);
+
+ /* check L3 TCP action */
+ if(_ReadRegBits(0, P0REG_L3FRAMEGETCTRL, 2, 2) == OP_CAP_ACT_DROP)
+ {
+ ip1811drv_err("Error: L3 TCP action is drop\n");
+ return -EINVAL;
+ }
+
+ /* set register */
+ _WriteRegBits(0, P0REG_TCPFLGCFG0 + index, 12, 2, fdata);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int getCosTcpFlagAct(void *cdata, int len)
+{
+ unsigned int index;
+ int fdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct TcpFlagSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ index = ((struct TcpFlagSetting *)cdata) ->index;
+ if( index > OP_TCPFLAG_FLAG3 )
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ fdata = _ReadRegBits(0, P0REG_TCPFLGCFG0 + index, 12, 2);
+ ((struct TcpFlagSetting *)cdata) ->fdata = fdata;
+ ip1811drv_dbg("cdata ->index=%X\n", index);
+ ip1811drv_dbg("cdata ->fdata=%X\n", fdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int setCosTcpFlagPort(void *cdata, int len)
+{
+ unsigned int index;
+ int fdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct TcpFlagSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ index = ((struct TcpFlagSetting *)cdata) ->index;
+ if( index > OP_TCPFLAG_FLAG3 )
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ fdata = ((struct TcpFlagSetting *)cdata) ->fdata;
+ if( fdata & ~0xFFF )
+ {
+ ip1811drv_err("Error: portmap=%X\n", fdata);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->index=%X\n", index);
+ ip1811drv_dbg("cdata ->fdata=%X\n", fdata);
+
+ IP2Page(0);
+
+ Write_Reg(P0REG_TCPFLGPORTEN+index*2, fdata&0xFFF);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int getCosTcpFlagPort(void *cdata, int len)
+{
+ unsigned int index;
+ int fdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct TcpFlagSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ index = ((struct TcpFlagSetting *)cdata) ->index;
+ if( index > OP_TCPFLAG_FLAG3 )
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ IP2Page(0);
+ fdata = Read_Reg(P0REG_TCPFLGPORTEN+index*2);
+ ((struct TcpFlagSetting *)cdata) ->fdata = fdata;
+ ip1811drv_dbg("cdata ->index=%X\n", index);
+ ip1811drv_dbg("cdata ->fdata=%X\n", fdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+//------------ CoS functions:common end ------------------------
+
+//------------------------------------------------
+//common_stp
+int switchdSetMstpFunc(int en)
+{
+ if (en!=OP_FUNC_DISABLE && en!=OP_FUNC_ENABLE)
+ return -EINVAL;
+ ip1811drv_dbg("en=%d\n", en);
+
+ _WriteRegBits(2, P2REG_VLANCFG, 6, 1, en); //MSTP enable
+ _WriteRegBits(2, P2REG_VLANCFG, 2, 1, en); //IVL
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetMstpFunc);
+int setMstpFunc(void *cdata, int len)
+{
+ int en;
+
+ ip1811drv_dbg("ip1811: +setMstpFunc...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ en = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetMstpFunc(en) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setMstpFunc...\n");
+ return 0;
+}
+
+int switchdGetMstpFunc(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(2, P2REG_VLANCFG, 6, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetMstpFunc);
+int getMstpFunc(void *cdata, int len)
+{
+ int en;
+
+ ip1811drv_dbg("ip1811: +getMstpFunc...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetMstpFunc(&en) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = en;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getMstpFunc...\n");
+ return 0;
+}
+
+//common_lacp
+int switchdSetTrunkHashMthd(int mthd)
+{
+ if (mthd < OP_TRUNK_HASH_METHOD_PORT_ID || mthd > OP_TRUNK_HASH_METHOD_SP)
+ return -EINVAL;
+ ip1811drv_dbg("mthd=%d\n", mthd);
+
+ _WriteRegBits(1, P1REG_TRUNKCFG, 0, 3, mthd);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetTrunkHashMthd);
+int setTrunkHashMthd(void *cdata, int len)
+{
+ int mthd;
+
+ ip1811drv_dbg("ip1811: +setTrunkHashMthd...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ mthd = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetTrunkHashMthd(mthd) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setTrunkHashMthd...\n");
+ return 0;
+}
+
+int switchdGetTrunkHashMthd(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(1, P1REG_TRUNKCFG, 0, 3);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetTrunkHashMthd);
+int getTrunkHashMthd(void *cdata, int len)
+{
+ int mthd;
+
+ ip1811drv_dbg("ip1811: +getTrunkHashMthd...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetTrunkHashMthd(&mthd) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = mthd;
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getTrunkHashMthd...\n");
+ return 0;
+}
+
+int switchdSetTrunkMbr(unsigned long pmask, unsigned long state)
+{
+ unsigned long u32dat;
+
+ if ((pmask & 0xFFFFF000) || !pmask)
+ return -EINVAL;
+ if ((state & 0xFFFFF000) || (state & ~pmask))
+ return -EINVAL;
+ ip1811drv_dbg("pmask=0x%08X\n", pmask);
+ ip1811drv_dbg("state=0x%08X\n", state);
+
+ IP2Page(1);
+ u32dat= (unsigned long)( Read_Reg(P1REG_TRUNKGRP) );
+ pmask = (unsigned long)( pmask&0xFFF );
+ state = (unsigned long)( state&0xFFF );
+ u32dat &= (~pmask);
+ u32dat |= state;
+#ifdef COMBINED_PORT
+ u32dat |= 0x600;
+#endif
+
+ Write_Reg(P1REG_TRUNKGRP, (u32dat & 0xFFF));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetTrunkMbr);
+int setTrunkMbr(void *cdata, int len)
+{
+ unsigned long pmask, state, u32dat;
+
+ ip1811drv_dbg("ip1811: +setTrunkMbr...\n");
+ if (sizeof(struct TrunkMemberSetting) != len)
+ return -EINVAL;
+
+ pmask = ((struct TrunkMemberSetting *)cdata) ->portmask;
+ state = ((struct TrunkMemberSetting *)cdata) ->tstate;
+
+ if(switchdSetTrunkMbr(pmask, state) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setTrunkMbr...\n");
+ return 0;
+}
+
+int switchdGetTrunkMbr(unsigned long pmask, unsigned long *ptrInt)
+{
+ if ((pmask & 0xFFFFF000) || !pmask)
+ return -EINVAL;
+ ip1811drv_dbg("pmask=0x%08X\n", pmask);
+
+ IP2Page(1);
+ *ptrInt = (unsigned long)( (Read_Reg(P1REG_TRUNKGRP) & 0xFFF) & pmask );
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetTrunkMbr);
+int getTrunkMbr(void *cdata, int len)
+{
+ unsigned long pmask, u32dat;
+
+ ip1811drv_dbg("ip1811: +getTrunkMbr...\n");
+ if (sizeof(struct TrunkMemberSetting) != len)
+ return -EINVAL;
+
+ pmask = ((struct TrunkMemberSetting *)cdata) ->portmask;
+
+ if(switchdGetTrunkMbr(pmask, &u32dat) != 0)
+ return -EINVAL;
+
+ ((struct TrunkMemberSetting *)cdata) ->tstate = u32dat;
+ ip1811drv_dbg("cdata ->tstate=0x%08x\n", (unsigned int)((struct TrunkMemberSetting *)cdata) ->tstate);
+ ip1811drv_dbg("ip1811: -getTrunkMbr...\n");
+ return 0;
+}
+
+int switchdSetCpuNCareTrunkAndVlan(int en)
+{
+ if (en!=OP_FUNC_DISABLE && en!=OP_FUNC_ENABLE)
+ return -EINVAL;
+ ip1811drv_dbg("en=%d\n", en);
+
+ _WriteRegBits(1, P1REG_TRUNKCFG, 4, 1, en);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetCpuNCareTrunkAndVlan);
+int setCpuNCareTrunkAndVlan(void *cdata, int len)
+{
+ int en;
+
+ ip1811drv_dbg("ip1811: +setCpuNCareTrunkAndVlan...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+ en = ((struct GeneralSetting *)cdata) ->gdata;
+
+ switchdSetCpuNCareTrunkAndVlan(en);
+
+ ip1811drv_dbg("ip1811: -setCpuNCareTrunkAndVlan...\n");
+ return 0;
+}
+
+int switchdGetCpuNCareTrunkAndVlan(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(1, P1REG_TRUNKCFG, 4, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetCpuNCareTrunkAndVlan);
+int getCpuNCareTrunkAndVlan(void *cdata, int len)
+{
+ int en;
+
+ ip1811drv_dbg("ip1811: +getCpuNCareTrunkAndVlan...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetCpuNCareTrunkAndVlan(&en) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = en;
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getCpuNCareTrunkAndVlan...\n");
+ return 0;
+}
+
+//------------------------------------------------
+//common_vlan
+int switchdSetVlanEgressFrame(int mode)
+{
+ if (mode > 0x7 )
+ {
+ ip1811drv_err("Error: mode=%X\n", mode);
+ return -EINVAL;
+ }
+ ip1811drv_dbg("mode=0x%08x\n", mode);
+
+ _WriteRegBits(2, P2REG_VLAN_EGRESS_CFG1, 0, 3, mode);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanEgressFrame);
+int setVlanEgressFrame(void *cdata, int len)
+{
+ u16 mode;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ mode = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetVlanEgressFrame(mode) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanEgressFrame(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(2,P2REG_VLAN_EGRESS_CFG1, 0, 3);
+}
+EXPORT_SYMBOL(switchdGetVlanEgressFrame);
+int getVlanEgressFrame(void *cdata, int len)
+{
+ int ftype;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanEgressFrame(&ftype);
+
+ ((struct GeneralSetting *)cdata) ->gdata = ftype;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanTagging(int mode)
+{
+ if ((mode != OP_VLAN_TAGGING_BY_PORT) && (mode != OP_VLAN_TAGGING_BY_VID))
+ {
+ ip1811drv_err("Error: mode=%X\n", mode);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("mode=0x%08x\n", mode);
+
+ _WriteRegBits(2, P2REG_VLANCFG, 3, 1, mode);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanTagging);
+int setVlanTagging(void *cdata, int len)
+{
+ u16 mode;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ mode = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetVlanTagging(mode) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanType(int mode)
+{
+ if ((mode != OP_VLAN_TYPE_TAG) && (mode != OP_VLAN_TYPE_GROUP))
+ {
+ ip1811drv_err("Error: mode=%X\n", mode);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("mode=0x%08x\n", mode);
+
+ /* set vlan type: port/tag base */
+ _WriteRegBits(2, P2REG_VLANCFG, 1, 1, mode);
+ /* set vlan protocol base */
+ _WriteRegBits(2, P2REG_VLANCFG, 0, 1, mode);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanType);
+int setVlanType(void *cdata, int len)
+{
+ u16 mode;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ mode = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetVlanType(mode) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanGroup(unsigned long pm, int option)
+{
+ u32 u32dat;
+ int i;
+
+ if (pm & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: portmap=%08lX\n", pm);
+ return -EINVAL;
+ }
+ if (option & ~0x1)
+ {
+ ip1811drv_err("Error: option=%X\n", option);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("pm=0x%08lx\n", pm);
+ ip1811drv_dbg("option=%x\n", option);
+
+ IP2Page(2);
+ for(i=0;i<MAX_PHY_NUM; i++)
+ {
+ if(!((pm>>i)&0x1))
+ continue;
+
+ u32dat = (u32)Read_Reg(P2REG_VLANGROUP+2*i);
+ if(option)
+ u32dat |= pm;
+ else
+ u32dat &= ~pm;
+
+ Write_Reg(P2REG_VLANGROUP+2*i, (u16)(u32dat & 0xFFFF));
+ //Write_Reg(P2REG_VLANGROUP+1+2*i, (u16)(u32dat >> 16));
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanGroup);
+int setVlanGroup(void *cdata, int len)
+{
+ unsigned long pm;
+ int option;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortmapSetting) != len)
+ return -EINVAL;
+
+ pm = ((struct PortmapSetting *)cdata) ->portmap;
+ option = ((struct PortmapSetting *)cdata) ->pmdata;
+
+ if(switchdSetVlanGroup(pm, option) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanQinQPType(int type)
+{
+ if (type&(~0xFFFF))
+ {
+ ip1811drv_err("Error: type=%d\n", type);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("type=0x%08x\n", type);
+
+ IP2Page(7);
+ Write_Reg(P7REG_QINQEGTYPELEN, type);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanQinQPType);
+int setVlanQinQPType(void *cdata, int len)
+{
+ int type;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ type = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetVlanQinQPType(type) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanQinQPAddtag(int member)
+{
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%08X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("member=0x%08x\n", member);
+
+ IP2Page(7);
+ Write_Reg(P7REG_QINQ_ADDTAG, (u16)(member & 0xFFFF));
+ //Write_Reg(P7REG_QINQ_ADDTAG+1, (u16)(member >> 16));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanQinQPAddtag);
+int setVlanQinQPAddtag(void *cdata, int len)
+{
+ int member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ member = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetVlanQinQPAddtag(member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanQinQPAddtag(u32 *u32dat)
+{
+ IP2Page(7);
+ *u32dat = (u32)Read_Reg(P7REG_QINQ_ADDTAG);
+}
+EXPORT_SYMBOL(switchdGetVlanQinQPAddtag);
+int getVlanQinQPAddtag(void *cdata, int len)
+{
+ u32 u32dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanQinQPAddtag(&u32dat);
+
+ ((struct PortMemberSetting *)cdata) ->member = (int)u32dat;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", (u16)((struct PortMemberSetting *)cdata) ->member);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanQinQPRmvtag(int member)
+{
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%08X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("member=0x%08x\n", member);
+
+ IP2Page(7);
+ Write_Reg(P7REG_QINQ_RMVTAG, (u16)(member & 0xFFFF));
+ //Write_Reg(P7REG_QINQ_RMVTAG+1, (u16)(member >> 16));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanQinQPRmvtag);
+int setVlanQinQPRmvtag(void *cdata, int len)
+{
+ int member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ member = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetVlanQinQPRmvtag(member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanQinQPRmvtag(u32 *u32dat)
+{
+ IP2Page(7);
+ *u32dat = (u32)Read_Reg(P7REG_QINQ_RMVTAG);
+}
+EXPORT_SYMBOL(switchdGetVlanQinQPRmvtag);
+int getVlanQinQPRmvtag(void *cdata, int len)
+{
+ u32 u32dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanQinQPRmvtag(&u32dat);
+
+ ((struct PortMemberSetting *)cdata) ->member = (int)u32dat;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", (u16)((struct PortMemberSetting *)cdata) ->member);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanQinQPRxdet(int member)
+{
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%08X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("member=0x%08x\n", member);
+
+ IP2Page(7);
+ Write_Reg(P7REG_QINQ_DET_RX, (u16)(member & 0xFFFF));
+ //Write_Reg(P7REG_QINQ_DET_RX+1, (u16)(member >> 16));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanQinQPRxdet);
+int setVlanQinQPRxdet(void *cdata, int len)
+{
+ int member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ member = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetVlanQinQPRxdet(member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanQinQPRxdet(u32 *u32dat)
+{
+ IP2Page(7);
+ *u32dat = (u32)Read_Reg(P7REG_QINQ_DET_RX);
+}
+EXPORT_SYMBOL(switchdGetVlanQinQPRxdet);
+int getVlanQinQPRxdet(void *cdata, int len)
+{
+ u32 u32dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanQinQPRxdet(&u32dat);
+
+ ((struct PortMemberSetting *)cdata) ->member = (int)u32dat;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", (u16)((struct PortMemberSetting *)cdata) ->member);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanQinQPKeep(int member)
+{
+ int i;
+
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%08X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("member=0x%08x\n", member);
+
+ for(i=0; i<MAX_PHY_NUM; i++)
+ {
+ _WriteRegBits(7, P7REG_QINQ_P_DATA+i, 12, 1, ((member>>i)&0x1));
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanQinQPKeep);
+int setVlanQinQPKeep(void *cdata, int len)
+{
+ int member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ member = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetVlanQinQPKeep(member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanQinQPKeep(u32 *u32dat)
+{
+ int i;
+ u16 u16dat;
+
+ IP2Page(7);
+ for(i=0; i<MAX_PHY_NUM; i++)
+ {
+ u16dat = Read_Reg(P7REG_QINQ_P_DATA+i);
+ *u32dat |= ((u16dat>>12)&0x1)<<i;
+ }
+}
+EXPORT_SYMBOL(switchdGetVlanQinQPKeep);
+int getVlanQinQPKeep(void *cdata, int len)
+{
+ u32 member=0;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanQinQPKeep(&member);
+
+ ((struct PortMemberSetting *)cdata) ->member = member;
+ ip1811drv_dbg("cdata ->gdata=%d\n", (u16)((struct PortMemberSetting *)cdata) ->member);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanQinQPIndex(int port, int index)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ {
+ ip1811drv_err("Error: port=%X\n", port);
+ return -EINVAL;
+ }
+
+ if (index < 0 || index > 15)
+ {
+ ip1811drv_err("Error: pmdata=%X\n", index);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("index=%d\n", index);
+
+ //index |= (0x0001 << 8);
+ _WriteRegBits(7, P7REG_QINQ_P_DATA+port, 0, 4, index);
+#ifdef COMBINED_PORT
+ if (port==9)
+ _WriteRegBits(7, P7REG_QINQ_P_DATA+port+1, 0, 4, index);
+#endif
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanQinQPIndex);
+int setVlanQinQPIndex(void *cdata, int len)
+{
+ int port, index;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+ index= ((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetVlanQinQPIndex(port, index) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdGetVlanQinQPIndex(int port, int *index)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ {
+ ip1811drv_err("Error: port=%X\n", port);
+ return -EINVAL;
+ }
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *index= _ReadRegBits(7,P7REG_QINQ_P_DATA+port, 0, 4);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetVlanQinQPIndex);
+int getVlanQinQPIndex(void *cdata, int len)
+{
+ int port;
+ int index;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetVlanQinQPIndex(port, &index) != 0)
+ return -EINVAL;
+
+ ((struct ByPortSetting *)cdata) ->pdata = index;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanQinQIndex(int index, int value)
+{
+ if (index<0 || index>15) {
+ ip1811drv_err("Error: index=%d\n", index);
+ return -EINVAL;
+ }
+
+ if (value & (~0xFFFF)) {
+ ip1811drv_err("Error: data=%x\n", value);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("index=%d\n", index);
+ ip1811drv_dbg("value=0x%x\n", value);
+
+ IP2Page(7);
+
+ Write_Reg(P7REG_QINQ_DATA+index, (u16)value);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanQinQIndex);
+int setVlanQinQIndex(void *cdata, int len)
+{
+ int type, data, ret;
+ struct VlanSetting *vs = (struct VlanSetting *)cdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct VlanSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ type = vs ->vtype;
+ data = vs ->vdata;
+ ret = switchdSetVlanQinQIndex(type, data);
+
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int switchdSetVlanQinQStagSelectMethod(int port, int method)
+{
+ if (port<0 || port>=MAX_PHY_NUM) {
+ ip1811drv_err("Error: port=%X\n", port);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("method=%d\n", method);
+
+ _WriteRegBits(7, P7REG_QINQ_P_DATA+port, 8, 4, method);
+#ifdef COMBINED_PORT
+ if (port==9)
+ _WriteRegBits(7, P7REG_QINQ_P_DATA+port+1, 8, 4, method);
+#endif
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanQinQStagSelectMethod);
+int setVlanQinQStagSelectMethod(void *cdata, int len)
+{
+ int port, method, ret;
+ struct ByPortSetting *bps = (struct ByPortSetting *)cdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ port = bps ->port;
+ method = bps ->pdata;
+ ret = switchdSetVlanQinQStagSelectMethod(port, method) ;
+
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int switchdSetVlanPortAddtag(int member)
+{
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%08X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("member=0x%08x\n", member);
+
+ IP2Page(2);
+ Write_Reg(P2REG_VLAN_ADDTAG, (u16)(member & 0xFFFF));
+ //Write_Reg(P2REG_VLAN_ADDTAG+1, (u16)(member >> 16));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanPortAddtag);
+int setVlanPortAddtag(void *cdata, int len)
+{
+ int member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ member = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetVlanPortAddtag(member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanPortAddtag(u32 *u32dat)
+{
+ IP2Page(2);
+ *u32dat = (u32)Read_Reg(P2REG_VLAN_ADDTAG);
+}
+EXPORT_SYMBOL(switchdGetVlanPortAddtag);
+int getVlanPortAddtag(void *cdata, int len)
+{
+ u32 u32dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanPortAddtag(&u32dat);
+
+ ((struct PortMemberSetting *)cdata) ->member = (int)u32dat;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", (u16)((struct PortMemberSetting *)cdata) ->member);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanPortRmvtag(int member)
+{
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%08X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("member=0x%08x\n", member);
+
+ IP2Page(2);
+ Write_Reg(P2REG_VLAN_RMVTAG, (u16)(member & 0xFFFF));
+ //Write_Reg(P2REG_VLAN_RMVTAG+1, (u16)(member >> 16));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanPortRmvtag);
+int setVlanPortRmvtag(void *cdata, int len)
+{
+ int member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ member = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetVlanPortRmvtag(member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanPortRmvtag(u32 *u32dat)
+{
+ IP2Page(2);
+ *u32dat = (u32)Read_Reg(P2REG_VLAN_RMVTAG);
+}
+EXPORT_SYMBOL(switchdGetVlanPortRmvtag);
+int getVlanPortRmvtag(void *cdata, int len)
+{
+ u32 u32dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanPortRmvtag(&u32dat);
+
+ ((struct PortMemberSetting *)cdata) ->member = (int)u32dat;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", (u16)((struct PortMemberSetting *)cdata) ->member);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanPortForce(int member)
+{
+ int i;
+
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%08X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("member=0x%08x\n", member);
+
+ for(i=0; i<MAX_PHY_NUM; i++)
+ {
+ _WriteRegBits(2, P2REG_VLANGROUP+2*i, 12, 1, (member>>i)&0x1);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanPortForce);
+int setVlanPortForce(void *cdata, int len)
+{
+ int member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ member = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetVlanPortForce(member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanPortForce(u32 *u32dat)
+{
+ u16 u16dat;
+ int i;
+
+ IP2Page(2);
+ for(i=0; i<MAX_PHY_NUM; i++)
+ {
+ u16dat = Read_Reg(P2REG_VLANGROUP+2*i);
+ *u32dat |= ((u16dat>>12)&0x1)<<i;
+ }
+}
+EXPORT_SYMBOL(switchdGetVlanPortForce);
+int getVlanPortForce(void *cdata, int len)
+{
+ u32 member=0;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanPortForce(&member);
+
+ ((struct PortMemberSetting *)cdata) ->member = member;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", (u16)((struct PortMemberSetting *)cdata) ->member);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanPortUplink(int member)
+{
+ //u16 u16dat;
+
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%08X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("member=0x%08x\n", member);
+
+ IP2Page(2);
+ Write_Reg(P2REG_VLAN_UPLINK, (u16)((member & 0xFFFF) | 0x1000));
+ //u16dat = (u16)(member >> 16);
+ //u16dat |= (u16)0x1<<13; //enable uplink
+ //_WriteRegBits(2, P2REG_VLAN_UPLINK+1, 0, 14, u16dat);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanPortUplink);
+int setVlanPortUplink(void *cdata, int len)
+{
+ int member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ member = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetVlanPortUplink(member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanPortUplink(u32 *u32dat)
+{
+ IP2Page(2);
+ *u32dat = (u32)Read_Reg(P2REG_VLAN_UPLINK);
+ *u32dat &= 0x0FFF;
+}
+EXPORT_SYMBOL(switchdGetVlanPortUplink);
+int getVlanPortUplink(void *cdata, int len)
+{
+ u32 u32dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanPortUplink(&u32dat);
+ ((struct PortMemberSetting *)cdata) ->member = (int)u32dat;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", (u16)((struct PortMemberSetting *)cdata) ->member);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanPortExclusive(int member)
+{
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%08X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("member=0x%08x\n", member);
+
+ IP2Page(2);
+ Write_Reg(P2REG_VLAN_EXCLUSIVE, (u16)(member & 0xFFFF));
+ //Write_Reg(P2REG_VLAN_EXCLUSIVE+1, (u16)(member >> 16));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanPortExclusive);
+int setVlanPortExclusive(void *cdata, int len)
+{
+ int member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ member = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetVlanPortExclusive(member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanPortExclusive(u32 *u32dat)
+{
+ IP2Page(2);
+ *u32dat = (u32)Read_Reg(P2REG_VLAN_EXCLUSIVE);
+}
+EXPORT_SYMBOL(switchdGetVlanPortExclusive);
+int getVlanPortExclusive(void *cdata, int len)
+{
+ u32 u32dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanPortExclusive(&u32dat);
+ ((struct PortMemberSetting *)cdata) ->member = (int)u32dat;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", (u16)((struct PortMemberSetting *)cdata) ->member);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanPortEgress(int member)
+{
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%08X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("member=0x%08x\n", member);
+
+ IP2Page(2);
+ Write_Reg(P2REG_VLAN_EGRESS_CFG, (u16)(member & 0xFFFF));
+ //_WriteRegBits(2, P2REG_VLAN_EGRESS_CFG+1, 0, 13, (u16)(member >> 16));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanPortEgress);
+int setVlanPortEgress(void *cdata, int len)
+{
+ int member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ member = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetVlanPortEgress(member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanPortEgress(u32 *u32dat)
+{
+ IP2Page(2);
+ *u32dat = (u32)Read_Reg(P2REG_VLAN_EGRESS_CFG);
+ //u32dat &= 0x1FFFFFFF;
+}
+EXPORT_SYMBOL(switchdGetVlanPortEgress);
+int getVlanPortEgress(void *cdata, int len)
+{
+ u32 u32dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanPortEgress(&u32dat);
+ ((struct PortMemberSetting *)cdata) ->member = (int)u32dat;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", (u16)((struct PortMemberSetting *)cdata) ->member);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanPortIngressFrame(int port, int pdata)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ {
+ ip1811drv_err("Error: port=%d\n", port);
+ return -EINVAL;
+ }
+
+ if (pdata < 0 || pdata > 0x3)
+ {
+ ip1811drv_err("Error: pdata=0x%X\n", pdata);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("pdata=0x%X\n", pdata);
+
+ _WriteRegBits(2, P2REG_VLAN_INGRESS_FRAME_0, port, 1, (pdata&0x1));
+ _WriteRegBits(2, P2REG_VLAN_INGRESS_FRAME_1, port, 1, ((pdata>>1)&0x1));
+#ifdef COMBINED_PORT
+ if (port==9){
+ _WriteRegBits(2, P2REG_VLAN_INGRESS_FRAME_0, port+1, 1, (pdata&0x1));
+ _WriteRegBits(2, P2REG_VLAN_INGRESS_FRAME_1, port+1, 1, ((pdata>>1)&0x1));
+ }
+#endif
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanPortIngressFrame);
+int setVlanPortIngressFrame(void *cdata, int len)
+{
+ int port, pdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+ pdata = ((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetVlanPortIngressFrame(port, pdata) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanPortIngressCheck(int member)
+{
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%08X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("member=0x%08x\n", member);
+
+ IP2Page(2);
+ Write_Reg(P2REG_VLAN_INGRESS_CHK, (u16)(member & 0xFFFF));
+ //Write_Reg(P2REG_VLAN_INGRESS_CHK+1, (u16)(member >> 16));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanPortIngressCheck);
+int setVlanPortIngressCheck(void *cdata, int len)
+{
+ int member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ member = ((struct PortMemberSetting *)cdata) ->member;
+
+ if(switchdSetVlanPortIngressCheck(member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+void switchdGetVlanPortIngressCheck(u32 *u32dat)
+{
+ IP2Page(2);
+ *u32dat = (u32)Read_Reg(P2REG_VLAN_INGRESS_CHK);
+}
+EXPORT_SYMBOL(switchdGetVlanPortIngressCheck);
+int getVlanPortIngressCheck(void *cdata, int len)
+{
+ u32 u32dat;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortMemberSetting) != len)
+ return -EINVAL;
+
+ switchdGetVlanPortIngressCheck(&u32dat);
+
+ ((struct PortMemberSetting *)cdata) ->member = (int)u32dat;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", (u16)((struct PortMemberSetting *)cdata) ->member);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanPortVid(int port, int pvid)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ {
+ ip1811drv_err("Error: port=%X\n", port);
+ return -EINVAL;
+ }
+
+ if (pvid < 0 || pvid >= MAX_PVID_NUM)
+ {
+ ip1811drv_err("Error: pmdata=%X\n", pvid);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("pvid=%d\n", pvid);
+
+ _WriteRegBits(2, P2REG_VLAN_PVIDCFG+port, 0, 12, pvid);
+#ifdef COMBINED_PORT
+ if (port==9)
+ _WriteRegBits(2, P2REG_VLAN_PVIDCFG+port+1, 0, 12, pvid);
+#endif
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanPortVid);
+int setVlanPortVid(void *cdata, int len)
+{
+ int port, pvid;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+ pvid= ((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetVlanPortVid(port, pvid) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanProtocolMode(int index, int mode)
+{
+ if (index < 0 || index >= MAX_PRO_VLAN_ENTRY_NUM)
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ if( (mode!=OP_VLAN_PROTOCOL_INVALID)
+ && (mode!=OP_VLAN_PROTOCOL_ETHER)
+ && (mode!=OP_VLAN_PROTOCOL_LLC)
+ && (mode!=OP_VLAN_PROTOCOL_1042) )
+ {
+ ip1811drv_err("Error: mode=%X\n", mode);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("index=%d\n", index);
+ ip1811drv_dbg("mode=%d\n", mode);
+
+ _WriteRegBits(2, P2REG_VLAN_PROCOTOL_CFG+1+index*2, 12, 2, mode);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanProtocolMode);
+int setVlanProtocolMode(void *cdata, int len)
+{
+ int index, mode;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct VlanSetting) != len)
+ return -EINVAL;
+
+ index = (((struct VlanSetting *)cdata) ->vtype) - 1;
+ mode= ((struct VlanSetting *)cdata) ->vdata;
+
+ if(switchdSetVlanProtocolMode(index, mode) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanProtocolVid(int index, int vid)
+{
+ if (index < 0 || index >= MAX_PRO_VLAN_ENTRY_NUM)
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ if( (vid < 0) || (vid>=MAX_PVID_NUM) )
+ {
+ ip1811drv_err("Error: vid=%X\n", vid);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("index=%d\n", index);
+ ip1811drv_dbg("vid=%d\n", vid);
+
+ _WriteRegBits(2, P2REG_VLAN_PROCOTOL_CFG+1+index*2, 0, 12, vid);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanProtocolVid);
+int setVlanProtocolVid(void *cdata, int len)
+{
+ int index, vid;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct VlanSetting) != len)
+ return -EINVAL;
+
+ index = (((struct VlanSetting *)cdata) ->vtype) - 1;
+ vid= ((struct VlanSetting *)cdata) ->vdata;
+
+ if(switchdSetVlanProtocolVid(index, vid) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanProtocolType(int index, int type)
+{
+ if (index < 0 || index >= MAX_PRO_VLAN_ENTRY_NUM)
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ if (type & (~0xFFFF))
+ {
+ ip1811drv_err("Error: type=%X\n", type);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("index=%d\n", index);
+ ip1811drv_dbg("type=%d\n", type);
+
+ IP2Page(2);
+
+ Write_Reg(P2REG_VLAN_PROCOTOL_CFG+index*2, (u16)type);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanProtocolType);
+int setVlanProtocolType(void *cdata, int len)
+{
+ int index, type;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct VlanSetting) != len)
+ return -EINVAL;
+
+ index = (((struct VlanSetting *)cdata) ->vtype) - 1;
+ type= ((struct VlanSetting *)cdata) ->vdata;
+
+ if(switchdSetVlanProtocolType(index, type) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanProtocolClear(int index)
+{
+ if (index < 0 || index >= MAX_PRO_VLAN_ENTRY_NUM)
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("index=0x%08x\n", index);
+
+ IP2Page(2);
+ Write_Reg(P2REG_VLAN_PROCOTOL_CFG+index*2, 0 );
+ Write_Reg(P2REG_VLAN_PROCOTOL_CFG+index*2+1, 0 );
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanProtocolClear);
+int setVlanProtocolClear(void *cdata, int len)
+{
+ int index;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ index = (((struct GeneralSetting *)cdata) ->gdata) - 1;
+
+ if(switchdSetVlanProtocolClear(index) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanMACBased(int mode)
+{
+ if (mode!=OP_FUNC_DISABLE && mode!=OP_FUNC_ENABLE){
+ ip1811drv_err("Error: mode=%X\n", mode);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("mode=0x%08x\n", mode);
+
+ _WriteRegBits(2, P2REG_VLANCFG, 11, 1, mode);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanMACBased);
+int setVlanMACBased(void *cdata, int len)
+{
+ int mode;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ mode = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetVlanMACBased(mode) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanMACBasedtableconfig(unsigned int index, unsigned int data)
+{
+ if (index < 0 || index >= MAX_FID_NUM)
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ if (data & (~0x1FFF))
+ {
+ ip1811drv_err("Error: data=%X\n", data);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("index=%d data=0x%08x\n", index, data);
+
+ IP2Page(2);
+ Write_Reg(P2REG_VLAN_MACBASED_ENTRY_0+index, (u16)data);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanMACBasedtableconfig);
+int setVlanMACBasedtableconfig(void *cdata, int len)
+{
+ unsigned int index, data;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct MACVlanSetting) != len)
+ return -EINVAL;
+
+ index = ((struct MACVlanSetting *)cdata) ->index;
+ data = ((struct MACVlanSetting *)cdata) ->mvdata;
+
+ if(switchdSetVlanMACBasedtableconfig(index, data) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdGetVlanMACBasedtableconfig(unsigned int index, unsigned int *data)
+{
+ if (index < 0 || index >= MAX_FID_NUM)
+ {
+ ip1811drv_err("Error: index=%X\n", index);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("index=%d\n", index);
+
+ IP2Page(2);
+ *data = (unsigned int)Read_Reg(P2REG_VLAN_MACBASED_ENTRY_0+index);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetVlanMACBasedtableconfig);
+int getVlanMACBasedtableconfig(void *cdata, int len)
+{
+ unsigned int index, data;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct MACVlanSetting) != len)
+ return -EINVAL;
+
+ index = ((struct MACVlanSetting *)cdata) ->index;
+
+ if(switchdGetVlanMACBasedtableconfig(index, &data) != 0)
+ return -EINVAL;
+
+ ((struct MACVlanSetting *)cdata) ->mvdata = data;
+
+ ip1811drv_dbg("cdata ->mvdata=%d\n", ((struct MACVlanSetting *)cdata) ->mvdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanMACBasedunknown(unsigned int data)
+{
+ if (data & (~0x1FFF))
+ {
+ ip1811drv_err("Error: data=%X\n", data);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("data=0x%08x\n", data);
+
+ IP2Page(2);
+ Write_Reg(P2REG_VLAN_MACBASED_UNKNOWN, (u16)data);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanMACBasedunknown);
+int setVlanMACBasedunknown(void *cdata, int len)
+{
+ unsigned int data;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ data = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetVlanMACBasedunknown(data) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+//ip1811_vlan
+int switchdSetVlanEntryMember(int vid, int member)
+{
+ u16 u16dat;
+
+ if (vid < 0 || vid >= MAX_PVID_NUM)
+ {
+ ip1811drv_err("Error: vid=%X\n", vid);
+ return -EINVAL;
+ }
+
+ if (member & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: member=%X\n", member);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("vid=%d\n", vid);
+ ip1811drv_dbg("member=%d\n", member);
+
+ IP2Page(2);
+ /* read data from VLAN table */
+ u16dat = 0x8000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+
+ /* set entry memeber */
+ u16dat = Read_Reg(P2REG_VLANDAT0);
+ u16dat &= ~0xFFF;
+ u16dat |= (u16)member&0x0FFF;
+ Write_Reg(P2REG_VLANDAT0, u16dat);
+
+ u16dat = Read_Reg(P2REG_VLANDAT0+1);
+ Write_Reg(P2REG_VLANDAT0+1, u16dat);
+ u16dat = Read_Reg(P2REG_VLANDAT0+2);
+ Write_Reg(P2REG_VLANDAT0+2, u16dat);
+
+ /* set valid bit to 1 */
+ u16dat = (u16)0x1;
+ Write_Reg(P2REG_VLANDAT0+3, u16dat);
+
+ /* Write data to VLAN table */
+ u16dat = 0xC000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanEntryMember);
+int setVlanEntryMember(void *cdata, int len)
+{
+ int vid, member;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortmapSetting) != len)
+ return -EINVAL;
+
+ vid = ((struct PortmapSetting *)cdata) ->pmdata;
+ member= ((struct PortmapSetting *)cdata) ->portmap;
+
+ if(switchdSetVlanEntryMember(vid, member) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanEntryAddtag(int vid, int addtag)
+{
+ u16 u16dat;
+
+ if (vid < 0 || vid >= MAX_PVID_NUM)
+ {
+ ip1811drv_err("Error: vid=%X\n", vid);
+ return -EINVAL;
+ }
+
+ if (addtag & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: addtag=%X\n", addtag);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("vid=%d\n", vid);
+ ip1811drv_dbg("addtag=%d\n", addtag);
+
+ IP2Page(2);
+ /* read data from VLAN table */
+ u16dat = 0x8000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+
+ /* set entry addtag */
+ u16dat = Read_Reg(P2REG_VLANDAT0);
+ u16dat &= ~0xF000;
+ u16dat |= (u16)(addtag&0xF)<<12;
+ Write_Reg(P2REG_VLANDAT0, u16dat);
+
+ u16dat = Read_Reg(P2REG_VLANDAT0+1);
+ u16dat &= ~0x00FF;
+ u16dat |= (u16)(addtag>>4)&0x00FF;
+ Write_Reg(P2REG_VLANDAT0+1, u16dat);
+
+ u16dat = Read_Reg(P2REG_VLANDAT0+2);
+ Write_Reg(P2REG_VLANDAT0+2, u16dat);
+
+ /* set valid bit to 1 */
+ u16dat = (u16)0x1;
+ Write_Reg(P2REG_VLANDAT0+3, u16dat);
+
+ /* Write data to VLAN table */
+ u16dat = 0xC000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanEntryAddtag);
+int setVlanEntryAddtag(void *cdata, int len)
+{
+ int vid, addtag;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortmapSetting) != len)
+ return -EINVAL;
+
+ vid = ((struct PortmapSetting *)cdata) ->pmdata;
+ addtag= ((struct PortmapSetting *)cdata) ->portmap;
+
+ if(switchdSetVlanEntryAddtag(vid, addtag) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanEntryRmvtag(int vid, int rmvtag)
+{
+ u16 u16dat;
+
+ if (vid < 0 || vid >= MAX_PVID_NUM)
+ {
+ ip1811drv_err("Error: vid=%X\n", vid);
+ return -EINVAL;
+ }
+
+ if (rmvtag & ~(0x0FFF))
+ {
+ ip1811drv_err("Error: rmvtag=%X\n", rmvtag);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("vid=%d\n", vid);
+ ip1811drv_dbg("rmvtag=%d\n", rmvtag);
+
+ IP2Page(2);
+ /* read data from VLAN table */
+ u16dat = 0x8000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+ u16dat = Read_Reg(P2REG_VLANDAT0);
+ Write_Reg(P2REG_VLANDAT0, u16dat);
+
+ /* set entry rmvtag */
+ u16dat = Read_Reg(P2REG_VLANDAT0+1);
+ u16dat &= ~0xFF00;
+ u16dat |= (u16)(rmvtag&0xFF)<<8;
+ Write_Reg(P2REG_VLANDAT0+1, u16dat);
+
+ u16dat = Read_Reg(P2REG_VLANDAT0+2);
+ u16dat &= ~0xF;
+ u16dat |= (u16)(rmvtag>>8)&0xF;
+ Write_Reg(P2REG_VLANDAT0+2, u16dat);
+
+ /* set valid bit to 1 */
+ u16dat = (u16)0x1;
+ Write_Reg(P2REG_VLANDAT0+3, u16dat);
+
+ /* Write data to VLAN table */
+ u16dat = 0xC000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanEntryRmvtag);
+int setVlanEntryRmvtag(void *cdata, int len)
+{
+ int vid, rmvtag;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct PortmapSetting) != len)
+ return -EINVAL;
+
+ vid = ((struct PortmapSetting *)cdata) ->pmdata;
+ rmvtag= ((struct PortmapSetting *)cdata) ->portmap;
+
+ if(switchdSetVlanEntryRmvtag(vid, rmvtag) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanEntryPriority(int vid, int priority)
+{
+ u16 u16dat;
+
+ if (vid < 0 || vid >= MAX_PVID_NUM)
+ {
+ ip1811drv_err("Error: vid=%X\n", vid);
+ return -EINVAL;
+ }
+
+ if (priority & ~(0xF))
+ {
+ ip1811drv_err("Error: priority=%X\n", priority);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("vid=%d\n", vid);
+ ip1811drv_dbg("priority=%d\n", priority);
+
+ IP2Page(2);
+ /* read data from VLAN table */
+ u16dat = 0x8000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+ u16dat = Read_Reg(P2REG_VLANDAT0);
+ Write_Reg(P2REG_VLANDAT0, u16dat);
+ u16dat = Read_Reg(P2REG_VLANDAT0+1);
+ Write_Reg(P2REG_VLANDAT0+1, u16dat);
+
+ /* set entry priority */
+ u16dat = Read_Reg(P2REG_VLANDAT0+2);
+ u16dat &= ~0x00F0;
+ u16dat |= (u16)(priority&0xF)<<4;
+ Write_Reg(P2REG_VLANDAT0+2, u16dat);
+
+ /* set valid bit to 1 */
+ u16dat = (u16)0x1;
+ Write_Reg(P2REG_VLANDAT0+3, u16dat);
+
+ /* Write data to VLAN table */
+ u16dat = 0xC000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanEntryPriority);
+int setVlanEntryPriority(void *cdata, int len)
+{
+ int vid, priority;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct VlanSetting) != len)
+ return -EINVAL;
+
+ vid = ((struct VlanSetting *)cdata) ->vtype;
+ priority= ((struct VlanSetting *)cdata) ->vdata;
+
+ if(switchdSetVlanEntryPriority(vid, priority) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanEntryFid(int vid, int fid)
+{
+ u16 u16dat;
+
+ if (vid < 0 || vid >= MAX_PVID_NUM)
+ {
+ ip1811drv_err("Error: vid=%X\n", vid);
+ return -EINVAL;
+ }
+
+ if (fid & ~(0xF))
+ {
+ ip1811drv_err("Error: fid=%X\n", fid);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("vid=%d\n", vid);
+ ip1811drv_dbg("fid=%d\n", fid);
+
+ IP2Page(2);
+ /* read data from VLAN table */
+ u16dat = 0x8000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+ u16dat = Read_Reg(P2REG_VLANDAT0);
+ Write_Reg(P2REG_VLANDAT0, u16dat);
+ u16dat = Read_Reg(P2REG_VLANDAT0+1);
+ Write_Reg(P2REG_VLANDAT0+1, u16dat);
+
+ /* set entry fid */
+ u16dat = Read_Reg(P2REG_VLANDAT0+2);
+ u16dat &= ~0xFF00;
+ u16dat |= (u16)(fid&0xF)<<8;
+ u16dat |= (u16)(fid&0xF)<<12;
+ Write_Reg(P2REG_VLANDAT0+2, u16dat);
+
+ /* set valid bit to 1 */
+ u16dat = (u16)0x1;
+ Write_Reg(P2REG_VLANDAT0+3, u16dat);
+
+ /* Write data to VLAN table */
+ u16dat = 0xC000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanEntryFid);
+int setVlanEntryFid(void *cdata, int len)
+{
+ int vid, fid;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct VlanSetting) != len)
+ return -EINVAL;
+
+ vid = ((struct VlanSetting *)cdata) ->vtype;
+ fid= ((struct VlanSetting *)cdata) ->vdata;
+
+ if(switchdSetVlanEntryFid(vid, fid) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdGetVlanEntryFid(int vid, int *ptrFid)
+{
+ u16 u16dat;
+
+ if (vid < 0 || vid >= MAX_PVID_NUM){
+ ip1811drv_err("Error: vtype=%X\n", vid);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("vid=%d\n", vid);
+
+ IP2Page(2);
+ /* read data from VLAN table */
+ u16dat = 0x8000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+ /* get entry fid */
+ u16dat = Read_Reg(P2REG_VLANDAT0+2);
+ *ptrFid = (int)(u16dat>>8)&0xF;
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetVlanEntryFid);
+int getVlanEntryFid(void *cdata, int len)
+{
+ int vid, fid=0;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct VlanSetting) != len)
+ return -EINVAL;
+
+ vid = ((struct VlanSetting *)cdata) ->vtype;
+
+ if(switchdGetVlanEntryFid(vid, &fid) != 0)
+ return -EINVAL;
+
+ ((struct VlanSetting *)cdata) ->vdata = fid;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct VlanSetting *)cdata) ->vdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetVlanEntryClear(int vid)
+{
+ u16 u16dat;
+ int i;
+
+ if (vid < 0 || vid >= MAX_PVID_NUM)
+ {
+ ip1811drv_err("Error: vid=%X\n", vid);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("vid=%d\n", vid);
+
+ IP2Page(2);
+
+ /* clear entry data */
+ for(i=0; i<4; i++)
+ Write_Reg(P2REG_VLANDAT0+i, 0 );
+
+ /* Write data from VLAN table */
+ u16dat = 0xC000 | vid;
+ Write_Reg(P2REG_VLANCMD, u16dat);
+ /* wait for command ack */
+ while(Read_Reg(P2REG_VLANCMD)&0x8000);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetVlanEntryClear);
+int setVlanEntryClear(void *cdata, int len)
+{
+ int vid;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ vid = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetVlanEntryClear(vid) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+//------------------------------------------------
+//ip1811_lut
+int switchdSetLutUnknownSARule(int rule)
+{
+ if ( !( rule==OP_LUT_UNKNOWN_SA_DROP ||
+ rule==OP_LUT_UNKNOWN_SA_FWD_2_CPU ||
+ rule==OP_LUT_UNKNOWN_SA_FWD) )
+ return -EINVAL;
+
+ ip1811drv_dbg("rule=%d\n", rule);
+
+ _WriteRegBits(1, P1REG_SRCLEARNCFG, 3, 2, rule);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLutUnknownSARule);
+int setLutUnknownSARule(void *cdata, int len)
+{
+ int rule;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ rule = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetLutUnknownSARule(rule) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetLutEntry(struct IP1811LUTSetting *luts)
+{
+ int i;
+ unsigned char f_notMatch = 0;
+ u16 u16dat, index;
+ u8 block;
+ int temp_offset = -1;
+ struct IP1811LUTSetting tmp_luts;
+
+ if( luts ->action!=OP_ENTRY_CREATE &&
+ luts ->action!=OP_ENTRY_CONFIG &&
+ luts ->action!=OP_ENTRY_DELETE &&
+ luts ->action!=OP_ENTRY_CREATE_REG)
+ {
+ ip1811drv_err("action error:%d\n", luts ->action);
+ return -EINVAL;
+ }
+ if( luts ->action == OP_ENTRY_CREATE ||
+ luts ->action == OP_ENTRY_CONFIG)
+ {
+ if(luts ->entry.fid > 15)
+ {
+ ip1811drv_err("fid error:%d\n", luts ->entry.fid);
+ return -EINVAL;
+ }
+ if(luts ->entry.srcport > 31)
+ {
+ ip1811drv_err("srcport error:%d\n", luts ->entry.srcport);
+ return -EINVAL;
+ }
+ if(luts ->entry.aging > 15)
+ {
+ ip1811drv_err("aging error:%d\n", luts ->entry.aging);
+ return -EINVAL;
+ }
+ if(luts ->entry.priority > 15)
+ {
+ ip1811drv_err("priority error:%d\n", luts ->entry.priority);
+ return -EINVAL;
+ }
+ if(luts ->entry.cfg > OP_LUT_CFG_MVT)
+ {
+ ip1811drv_err("cfg error:%d\n", luts ->entry.cfg);
+ return -EINVAL;
+ }
+ }
+
+ /* initialize retval value */
+ luts ->retval = 0;
+ /* calculate hash value */
+ index = 0;//LUT_hash(luts ->entry.mac, luts ->entry.fid);
+
+ ip1811drv_dbg("index=%d\n", index);
+ ip1811drv_dbg("MAC=\n");
+ for(i=0; i<6; i++)
+ ip1811drv_dbg("[%02X]\n", luts ->entry.mac[i]);
+ ip1811drv_dbg("fid=%d\n", luts ->entry.fid);
+ ip1811drv_dbg("srcport=%d\n", luts ->entry.srcport);
+ ip1811drv_dbg("aging=%d\n", luts ->entry.aging);
+ ip1811drv_dbg("priority=%d\n", luts ->entry.priority);
+ ip1811drv_dbg("drop=%d\n", luts ->entry.flag.drop);
+ ip1811drv_dbg("snif=%d\n", luts ->entry.flag.snif);
+ ip1811drv_dbg("sflow=%d\n", luts ->entry.flag.sflow);
+ ip1811drv_dbg("cfg=%d\n", luts ->entry.cfg);
+
+ IP2Page(1);
+ if(luts ->action==OP_ENTRY_CREATE_REG)
+ {
+ ip1811drv_dbg("OP_ENTRY_CREATE_REG\n");
+ for(i=0; i<5; i++)
+ Write_Reg(P1REG_LUTDATA_0+i, luts ->data[i] );
+ Write_Reg(P1REG_LUTDATA_0+5, luts ->data[5]|0x0800 ); //hw_calc
+
+ u16dat = 0;
+ u16dat |= (u16)0x3<<14; //set write command & command trigger
+ Write_Reg(P1REG_LUTCFG, u16dat );
+ /* need to check does trigger bit has been pull up */
+ while(!(Read_Reg(P1REG_LUTCFG)&0x8000));
+ return 0;
+ }
+
+ /* search the index of target entry */
+ /* cause use hw_calc bit can't get entry index */
+// if((luts ->action==OP_ENTRY_CONFIG) || (luts ->action==OP_ENTRY_DELETE))
+ {
+ memset(&tmp_luts, 0, sizeof(struct IP1811LUTSetting));
+ /* search all entries */
+ tmp_luts.action = OP_LUT_STATE_ALL;
+ tmp_luts.tarports = ALL_PHY_PORTS_LIST;
+ while(1)
+ {
+ /* try to get a valid MAC entry */
+ tmp_luts.retval = 0;
+ getLutValidEntry(&tmp_luts, sizeof(struct IP1811LUTSetting));
+ if(tmp_luts.retval != OP_ENTRY_EXISTS)
+ break;
+
+ /* get a valid static entry */
+
+ /* check MAC address & FID */
+ f_notMatch = 0;
+ for(i=0; i<6; i++)
+ {
+ if(luts ->entry.mac[i] != tmp_luts.entry.mac[i])
+ {
+ f_notMatch = 1;
+ break;
+ }
+ }
+ if(luts ->entry.fid != tmp_luts.entry.fid)
+ f_notMatch = 1;
+
+ if(!f_notMatch){
+ /* if match, record the index */
+ temp_offset = tmp_luts.index;
+ break;
+ }
+
+ /* search next valid entry */
+ tmp_luts.index++;
+ }
+ }
+
+ if(luts ->action==OP_ENTRY_CREATE)
+ {
+ ip1811drv_dbg("OP_ENTRY_CREATE\n");
+ if(tmp_luts.entry.aging == 0xf)
+ {
+ ip1811drv_dbg("target entry has existed!!\n");
+ luts ->retval = OP_ENTRY_EXISTS;
+ return 0;
+ }
+ for(i=0; i<3; i++)
+ {
+ u16dat = (u16)(luts ->entry.mac[4 - i*2])<<8 | (u16)(luts ->entry.mac[5 - i*2]);
+ Write_Reg(P1REG_LUTDATA_0+i, u16dat );
+ }
+ u16dat = 0;
+ u16dat = luts ->entry.fid;
+ u16dat |= (u16)luts ->entry.srcport<<4;
+ u16dat |= (u16)0x0f<<9; //set aging to static
+ u16dat |= (u16)((luts ->entry.priority & 0x7)<<13);
+ Write_Reg(P1REG_LUTDATA_3, u16dat );
+
+ u16dat = (u16)((luts ->entry.priority >> 3)&0x1);
+ u16dat |= (u16)luts ->entry.flag.sflow<<1;
+ u16dat |= (u16)luts ->entry.flag.snif<<2;
+ u16dat |= (u16)luts ->entry.flag.drop<<3;
+ if (luts ->entry.cfg < OP_LUT_CFG_TRAN)
+ u16dat |= (u16)((luts ->entry.cfg & 0x3)<<4);
+ else
+ {
+ u16dat |= (u16)0x0020; // cfg[1] = 1
+ if (luts ->entry.cfg == OP_LUT_CFG_MVT)
+ u16dat |= (u16)0x0008; // drop = 1
+ }
+ Write_Reg(P1REG_LUTDATA_4, u16dat );
+
+ u16dat = 0x01<<11;//hw_calc
+ Write_Reg(P1REG_LUTDATA_5, u16dat );
+
+ u16dat = 0; //set index
+ u16dat |= (u16)0x3<<14; //set write command & command trigger
+ Write_Reg(P1REG_LUTCFG, u16dat );
+
+ /* need to check does trigger bit has been pull up */
+ while(!(Read_Reg(P1REG_LUTCFG)&0x8000));
+ }
+ else if(luts ->action==OP_ENTRY_CONFIG)
+ {
+ ip1811drv_dbg("OP_ENTRY_CONFIG\n");
+ /* if MAC or FID isn't match, we should abort this configuration */
+ if(f_notMatch)
+ {
+ ip1811drv_dbg("MAC or FID not match!!\n");
+ luts ->retval = OP_ENTRY_NOT_MATCH;
+ return 0;
+ }
+
+ for (i=0; i < 3; i++)
+ Write_Reg(P1REG_LUTDATA_0+i, tmp_luts.data[i]);
+
+ u16dat = luts ->entry.fid;
+ u16dat |= (u16)luts ->entry.srcport<<4;
+ u16dat |= (u16)0x0f<<9; //set aging to static
+ u16dat |= (u16)((luts ->entry.priority & 0x7)<<13);
+ Write_Reg(P1REG_LUTDATA_3, u16dat );
+
+ u16dat = (u16)((luts ->entry.priority >> 3)&0x1);
+ u16dat |= (u16)luts ->entry.flag.sflow<<1;
+ u16dat |= (u16)luts ->entry.flag.snif<<2;
+ if (luts ->entry.cfg < OP_LUT_CFG_TRAN)
+ {
+ u16dat |= (u16)luts ->entry.flag.drop<<3;
+ u16dat |= (u16)((luts ->entry.cfg & 0x3)<<4);
+ }
+ else
+ {
+ u16dat |= (u16)0x0020; // cfg[1] = 1
+ if (luts ->entry.cfg == OP_LUT_CFG_MVT)
+ u16dat |= (u16)0x0008; // drop = 1
+ }
+ Write_Reg(P1REG_LUTDATA_4, u16dat );
+
+ u16dat = 0x01<<11;//hw_calc
+ Write_Reg(P1REG_LUTDATA_5, u16dat );
+
+ u16dat = 0; //set index
+ u16dat |= (u16)0x3<<14; //set write command & command trigger
+ Write_Reg(P1REG_LUTCFG, u16dat );
+
+ /* need to check does trigger bit has been pull up */
+ while(!(Read_Reg(P1REG_LUTCFG)&0x8000));
+ }
+ else if(luts ->action==OP_ENTRY_DELETE)
+ {
+ ip1811drv_dbg("OP_ENTRY_DELETE\n");
+ if(f_notMatch)
+ {
+ ip1811drv_dbg("MAC or FID not match!!\n");
+ luts ->retval = OP_ENTRY_NOT_MATCH;
+ return 0;
+ }
+ if(tmp_luts.entry.aging != 0xf)
+ {
+ /* only static entry can be deleted */
+ ip1811drv_dbg("not static entry!!\n");
+ luts ->retval = OP_ENTRY_NOT_FOUND;
+ return 0;
+ }
+
+ for (i=0; i < 3; i++)
+ Write_Reg(P1REG_LUTDATA_0+i, tmp_luts.data[i]);
+
+ u16dat = 0x0; //set aging to invalid
+ Write_Reg(P1REG_LUTDATA_3, u16dat );
+
+ u16dat = 0x01<<11;//hw_calc
+ Write_Reg(P1REG_LUTDATA_5, u16dat );
+
+ u16dat = 0; //set index
+ u16dat |= (u16)0x3<<14; //set write command & command trigger
+ Write_Reg(P1REG_LUTCFG, u16dat );
+
+ /* need to check does trigger bit has been pull up */
+ while(!(Read_Reg(P1REG_LUTCFG)&0x8000));
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetLutEntry);
+int setLutEntry(void *cdata, const int len)
+{
+ struct IP1811LUTSetting *luts;
+
+ FUNC_MSG_IN;
+ /* check cdata length */
+ if (sizeof(struct IP1811LUTSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ luts = (struct IP1811LUTSetting *)cdata;
+
+ if(switchdSetLutEntry(luts) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+u8 getLutCfgFromReg(u16 reg)
+{
+ if (reg & 0x0020) // cfg[1] = 1
+ {
+ if (reg & 0x8) // drop = 1
+ return (u8)OP_LUT_CFG_MVT;
+ else
+ return (u8)OP_LUT_CFG_TRAN;
+ }
+ else // cfg[1] = 0
+ return (u8)((reg >> 4) & 0x1);
+}
+
+int switchdGetLutEntry(struct IP1811LUTSetting *luts)
+{
+ int i;
+ bool f_notMatch = 0;
+ u16 u16dat, lutdat_3, lutdat_4;
+ int val_aging;
+ u8 op_cfg;
+
+ /* check index range */
+ if(luts ->index >= MAX_LUT_ENTRY_NUM){
+ ip1811drv_err("Error: index=%d\n", luts ->index);
+ return -EINVAL;
+ }
+
+ /* set to register page 1 */
+ IP2Page(1);
+
+ /* check command action */
+ if(luts ->action == OP_ENTRY_GET_BY_INFO){
+ if(luts ->entry.fid >= MAX_FID_NUM){
+ ip1811drv_err("Error: fid=%d\n", luts ->entry.fid);
+ return -EINVAL;
+ }
+
+ /* copy mac to register from cdata */
+ for(i=0; i<3; i++){
+ u16dat = (u16)(luts ->entry.mac[4 - i*2])<<8 | (u16)(luts ->entry.mac[5 - i*2]);
+ Write_Reg(P1REG_LUTDATA_0 + i, u16dat );
+ }
+
+ /* set fid to register from cdata */
+ Write_Reg(P1REG_LUTDATA_3, luts ->entry.fid );
+
+ /* setup table address access method by HW */
+ Write_Reg(P1REG_LUTDATA_5, 0x0800 );
+ }
+ else if(luts ->action == OP_ENTRY_GET_BY_INDEX){
+ /* setup table address access method by CPU */
+ Write_Reg(P1REG_LUTDATA_5, 0 );
+ }
+ else{
+ ip1811drv_err("Error: action=%d\n", luts ->action);
+ return -EINVAL;
+ }
+
+ /* initialize return value */
+ luts ->retval = 0;
+
+ u16dat = luts ->index; //set index
+ u16dat |= (u16)0x2<<14; //set read command & command trigger
+ Write_Reg(P1REG_LUTCFG, u16dat );
+
+ /* check does trigger bit has been pull up */
+ while(!(Read_Reg(P1REG_LUTCFG)&0x8000));
+
+ /* catch aging time to check entry state */
+ lutdat_3 = Read_Reg(P1REG_LUTDATA_3);
+ lutdat_4 = Read_Reg(P1REG_LUTDATA_4);
+ val_aging = (lutdat_3 >> 9) & 0x0F;
+ if(val_aging == 0x0){
+ luts ->retval = OP_ENTRY_NOT_FOUND;
+ return 0;
+ }
+
+ /* get lut cfg */
+ op_cfg = getLutCfgFromReg(lutdat_4);
+
+ if(luts ->action == OP_ENTRY_GET_BY_INFO){
+ /* if action is get by entry info, check if register value is same with input data */
+ /* catch MAC address */
+ for(i=0; i<3; i++){
+ u16dat = Read_Reg(P1REG_LUTDATA_0 + i);
+ if( luts ->entry.mac[5 - i*2] != (u8)(u16dat&0xFF) )
+ f_notMatch = 1;
+ if( luts ->entry.mac[4 - i*2] != (u8)((u16dat>>8)&0xFF) )
+ f_notMatch = 1;
+ }
+
+ /* check whether fid is matched to input cdata */
+ if( luts ->entry.fid != (lutdat_3 & 0x000f))
+ f_notMatch = 1;
+
+ /* check whether cfg is matched to input cdata */
+ if( luts ->entry.cfg != op_cfg)
+ f_notMatch = 1;
+
+ if(val_aging == 0xf){//static entry
+ if(f_notMatch){
+ ip1811drv_err("Error: MAC or FID is not match\n");
+ luts ->retval = OP_ENTRY_NOT_MATCH;
+ return 0;
+ }
+ else
+ luts ->retval = OP_ENTRY_EXISTS;
+ }
+ else{//dynamic entry
+ if(f_notMatch){
+ ip1811drv_err("Error: MAC or FID is not match\n");
+ luts ->retval = OP_ENTRY_NOT_MATCH;
+ return 0;
+ }
+ else
+ luts ->retval = OP_ENTRY_EXISTS_DYNAMIC;
+ }
+ }
+ else{//if(luts ->action == OP_ENTRY_GET_BY_INDEX)
+ if( ((lutdat_3 >> 9) & 0x000F ) == 0x000F )
+ luts ->retval = OP_ENTRY_EXISTS;
+ else
+ luts ->retval = OP_ENTRY_EXISTS_DYNAMIC;
+
+ /* if action is get by entry index, copy the register value into output data */
+ /* catch MAC address */
+ for(i=0; i<3; i++){
+ u16dat = Read_Reg(P1REG_LUTDATA_0 + i);
+ luts ->entry.mac[5 - i*2] = (u8)(u16dat&0xFF);
+ luts ->entry.mac[4 - i*2] = (u8)((u16dat>>8)&0xFF);
+ }
+
+ lutdat_3 = Read_Reg(P1REG_LUTDATA_3);
+ luts ->entry.fid = lutdat_3 & 0x000F;
+ }
+
+ luts ->entry.priority = ((lutdat_4 & 0x0001) << 3) | ((lutdat_3>>13) & 0x0007);
+ if (op_cfg < OP_LUT_CFG_TRAN)
+ luts ->entry.flag.drop = (lutdat_4>>3) & 0x0001;
+ else
+ luts ->entry.flag.drop = 0;
+ luts ->entry.flag.sflow = (lutdat_4>>1) & 0x0001;
+ luts ->entry.flag.snif = (lutdat_4>>2) & 0x0001;
+ luts ->entry.srcport = (lutdat_3>>4) & 0x001F;
+
+ luts ->entry.aging = val_aging;
+ luts ->entry.cfg = op_cfg;
+
+ ip1811drv_dbg("cdata ->MAC=");
+ for(i=0; i<6; i++)
+ ip1811drv_dbg("[%02X]", luts ->entry.mac[i]);
+ ip1811drv_dbg("\ncdata ->fid=%d\n", luts ->entry.fid);
+ ip1811drv_dbg("cdata ->srcport=%d\n", luts ->entry.srcport);
+ ip1811drv_dbg("cdata ->aging=%d\n", luts ->entry.aging);
+ ip1811drv_dbg("cdata ->priority=%d\n", luts ->entry.priority);
+ ip1811drv_dbg("cdata ->drop=%d\n", luts ->entry.flag.drop);
+ ip1811drv_dbg("cdata ->snif=%d\n", luts ->entry.flag.snif);
+ ip1811drv_dbg("cdata ->sflow=%d\n", luts ->entry.flag.sflow);
+ ip1811drv_dbg("cdata ->cfg=%d\n", luts ->entry.cfg);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetLutEntry);
+int getLutEntry(void *cdata, const int len)
+{
+ struct IP1811LUTSetting *luts;
+
+ FUNC_MSG_IN;
+ /* check cdata length */
+ if (sizeof(struct IP1811LUTSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ luts = (struct IP1811LUTSetting *)cdata;
+
+ if(switchdGetLutEntry(luts) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdGetLutValidEntry(struct IP1811LUTSetting *luts)
+{
+ int i, retrytimes=25;
+ u16 u16dat, lutdat[6];
+ unsigned short index;
+ unsigned char block;
+ int temp_offset;
+
+ u16 hashvid;
+
+ /* check index range */
+ if(luts ->index >= MAX_LUT_ENTRY_NUM)
+ {
+ ip1811drv_err("Error: index=%d\n", luts ->index);
+ return -EINVAL;
+ }
+ index = luts ->index;
+
+ ip1811drv_dbg("action=%d\n", luts ->action);
+ /* set to register page 1 */
+ IP2Page(1);
+
+ /* setup table address access method by CPU */
+ Write_Reg(P1REG_LUTDATA_5, 0 );
+
+ /* initialize return value */
+ luts ->retval = 0;
+
+ u16dat = index; //set index
+ u16dat |= (u16)0x2000; //sequential search for valid entry
+ u16dat |= (u16)0x2<<14; //set read command & command trigger
+ Write_Reg(P1REG_LUTCFG, u16dat );
+
+ while (1)
+ {
+ memset(lutdat, 0, sizeof(lutdat));
+
+ /* check does trigger bit has been pull up */
+ for (i=0; i < retrytimes; i++)
+ {
+ udelay(100);
+ u16dat = Read_Reg(P1REG_LUTCFG);
+ if (u16dat & 0x8000)
+ break;
+ }
+ if (i == retrytimes)
+ goto out_switchdGetLutValidEntry;
+
+ /* read out all registers of lut data */
+ for (i=0; i < 6; i++)
+ lutdat[i] = Read_Reg(P1REG_LUTDATA_0+i);
+
+ /* check if there is any entry data */
+ if (lutdat[0]==0 && lutdat[1]==0 && lutdat[2]==0){
+ /* no data in lut table */
+ goto out_switchdGetLutValidEntry;
+ }
+
+ /* check if there is no more new data */
+ if (!(u16dat & 0x2000)){
+ /* lut table has been scanned to the end */
+ goto out_switchdGetLutValidEntry;
+ }
+
+ /* catch aging time to check entry state */
+ if((lutdat[3] &0x1e00) == 0x0){
+ /* invalid entry */
+ continue;
+ }
+ if( ((lutdat[3] >> 9) & 0xf) == 0xf &&
+ !(luts ->action & OP_LUT_STATE_STATIC)
+ )
+ {
+ /* action don't need static entry */
+ continue;
+ }
+ if( ((lutdat[3] >> 9) & 0xf) != 0xf &&
+ !(luts ->action & OP_LUT_STATE_DYNAMIC) )
+ {
+ /* action don't need dynamic entry */
+ continue;
+ }
+
+ /* check whether source port bigger than CPU port num */
+ if((((lutdat[3]>>4) & 0x001f) + 1) > MAX_PHY_NUM)
+ continue;
+
+ /* check whether this entry is in target portlist */
+ if(!((1UL << ((lutdat[3]>>4) & 0x001f))&luts ->tarports))
+ continue;
+
+ break;
+ }
+
+ /* if find a valid entry, copy the register value into output data */
+ /* catch MAC address */
+ for(i=0; i<6; i++)
+ {
+ luts ->data[i] = lutdat[i];
+ if (i < 3)
+ {
+ luts ->entry.mac[5 - i*2] = (u8)(lutdat[i]&0xFF);
+ luts ->entry.mac[4 - i*2] = (u8)((lutdat[i]>>8)&0xFF);
+ }
+ }
+
+ luts ->entry.fid = lutdat[3] & 0x000f;
+ luts ->entry.srcport = (lutdat[3]>>4) & 0x001f;
+ luts ->entry.aging = (lutdat[3]>>9) & 0x000f;
+ luts ->entry.priority = (lutdat[3]>>13) & 0x0007;
+ luts ->entry.priority |= ((lutdat[4] & 0x0001) << 3);
+
+ luts ->entry.flag.sflow = (lutdat[4]>>1) & 0x0001;
+ luts ->entry.flag.snif = (lutdat[4]>>2) & 0x0001;
+ luts -> entry.cfg = getLutCfgFromReg(lutdat[4]);
+ if (luts -> entry.cfg < OP_LUT_CFG_TRAN)
+ luts ->entry.flag.drop = (lutdat[4]>>3) & 0x0001;
+ else
+ luts ->entry.flag.drop = 0;
+
+ luts ->retval = OP_ENTRY_EXISTS;
+
+ ip1811drv_dbg("=====================================\n");
+ ip1811drv_dbg("index=%d\n", luts ->index);
+ ip1811drv_dbg("retval=%lX\n", luts ->retval);
+ ip1811drv_dbg("MAC=");
+ for(i=0; i<6; i++)
+ ip1811drv_dbg("[%02X]", luts ->entry.mac[i]);
+ ip1811drv_dbg("\nfid=%d\n", luts ->entry.fid);
+ ip1811drv_dbg("srcport=%d\n", luts ->entry.srcport);
+ ip1811drv_dbg("aging=%d\n", luts ->entry.aging);
+ ip1811drv_dbg("priority=%d\n", luts ->entry.priority);
+ ip1811drv_dbg("drop=%d\n", luts ->entry.flag.drop);
+ ip1811drv_dbg("snif=%d\n", luts ->entry.flag.snif);
+ ip1811drv_dbg("sflow=%d\n", luts ->entry.flag.sflow);
+ ip1811drv_dbg("cfg=%d\n", luts ->entry.cfg);
+
+out_switchdGetLutValidEntry:
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetLutValidEntry);
+int getLutValidEntry(void *cdata, const int len)
+{
+ struct IP1811LUTSetting *luts;
+
+ FUNC_MSG_IN;
+ /* check cdata length */
+ if (sizeof(struct IP1811LUTSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ luts = (struct IP1811LUTSetting *)cdata;
+
+ if(switchdGetLutValidEntry(luts) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+//------------------------------------------------
+//ip1811_igmp
+int switchdSetIGMPSnooping(int enable)
+{
+ switch(enable) {
+ case OP_FUNC_ENABLE:
+ ip1811drv_dbg("Enable IGMP\n");
+ break;
+ case OP_FUNC_DISABLE:
+ ip1811drv_dbg("Disable IGMP\n");
+ break;
+ default:
+ ip1811drv_dbg("Option can't find\n");
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("Set IGMPSNOP: %x\n", enable);
+ _WriteRegBits(1, P1REG_IGMPSNOP, 0, 1, enable);
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetIGMPSnooping);
+
+int setIGMPSnooping(void *cdata, int len)
+{
+ int ret, func_en;
+ struct GeneralSetting *igmp;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In setIGMPSnoopin.\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct GeneralSetting *)cdata;
+ func_en = igmp ->gdata;
+ ret = switchdSetIGMPSnooping(func_en);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetIGMPSnooping(int *gdata_p)
+{
+ *gdata_p = (int)_ReadRegBits(1, P1REG_IGMPSNOP, 0, 1)?OP_FUNC_ENABLE:OP_FUNC_DISABLE;
+ ip1811drv_dbg("IGMP %s",(*gdata_p==OP_FUNC_ENABLE)?"ENABLE":"DISABLE");
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetIGMPSnooping);
+
+int getIGMPSnooping(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *igmp;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In getIGMPSnoopin.\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct GeneralSetting *)cdata;
+ ret = switchdGetIGMPSnooping(&(igmp ->gdata))
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int switchdSetIGMPMctByCPU(int enable)
+{
+ switch(enable) {
+ case OP_FUNC_ENABLE:
+ ip1811drv_dbg("Enable MCT By CPU\n");
+ break;
+ case OP_FUNC_DISABLE:
+ ip1811drv_dbg("Disable MCT By CPU\n");
+ break;
+ default:
+ ip1811drv_dbg("Option can't find\n");
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("Set MCT By CPU: %x\n", enable);
+ _WriteRegBits(1, P1REG_IGMPSNOP, 1, 1, enable);
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetIGMPMctByCPU);
+
+int setIGMPMctByCPU(void *cdata, int len)
+{
+ int ret, func_en;
+ struct GeneralSetting *igmp;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In setIGMPMctByCPU.\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct GeneralSetting *)cdata;
+ func_en = igmp ->gdata;
+ ret = switchdSetIGMPMctByCPU(func_en);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetIGMPMctByCPU(int *gdata_p)
+{
+ *gdata_p = (int)_ReadRegBits(1, P1REG_IGMPSNOP, 1, 1)?OP_FUNC_ENABLE:OP_FUNC_DISABLE;
+ ip1811drv_dbg("IGMPMctByCPU %s",(*gdata_p==OP_FUNC_ENABLE)?"ENABLE":"DISABLE");
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetIGMPMctByCPU);
+
+int getIGMPMctByCPU(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *igmp;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In getIGMPMctByCPU.\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct GeneralSetting *)cdata;
+ ret = switchdGetIGMPMctByCPU(&(igmp ->gdata));
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetIGMPRltByCPU(int enable)
+{
+ switch(enable) {
+ case OP_FUNC_ENABLE:
+ ip1811drv_dbg("Enable router list by CPU\n");
+ break;
+ case OP_FUNC_DISABLE:
+ ip1811drv_dbg("Disable router list by CPU\n");
+ break;
+ default:
+ ip1811drv_dbg("Option can't find\n");
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("Set router list by CPU: %x\n", enable);
+ _WriteRegBits(1, P1REG_IGMPSNOP, 5, 1, enable);
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetIGMPRltByCPU);
+
+int setIGMPRltByCPU(void *cdata, int len)
+{
+ int ret, func_en;
+ struct GeneralSetting *igmp;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In setIGMPRltByCPU.\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct GeneralSetting *)cdata;
+ func_en = igmp ->gdata;
+ ret = switchdSetIGMPRltByCPU(func_en);
+ FUNC_MSG_OUT;
+
+ return 0;
+}
+
+int switchdGetIGMPRltByCPU(int *gdata_p)
+{
+ *gdata_p = (int)_ReadRegBits(1, P1REG_IGMPSNOP, 5, 1)?OP_FUNC_ENABLE:OP_FUNC_DISABLE;
+ ip1811drv_dbg("IGMPRltByCPU %s",(*gdata_p==OP_FUNC_ENABLE)?"ENABLE":"DISABLE");
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetIGMPRltByCPU);
+
+int getIGMPRltByCPU(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *igmp;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In getIGMPRltByCPU.\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct GeneralSetting *)cdata;
+ ret = switchdGetIGMPRltByCPU(&(igmp ->gdata));
+ FUNC_MSG_OUT;
+
+ return 0;
+}
+
+int switchdSetIGMPPktForward(unsigned int type, unsigned int rule)
+{
+ u16 regdata;
+ u16 rule_t;
+
+ IP2Page(1);
+ switch(type){
+ case OP_IGMP_PACKET_QUERY:
+ case OP_IGMP_PACKET_LEAVE:
+ case OP_IGMP_PACKET_UN_REG_DATA:
+ case OP_IGMP_PACKET_UN_DEFINED:
+ if(rule >= OP_IGMP_RULE_GROUP_MEM){
+ ip1811drv_dbg("Select Type can't support Rule 'OP_IGMP_RULE_GROUP_MEM'.\n");
+ return -EINVAL;
+ }
+ regdata = Read_Reg(P1REG_IGMPPKTFWD_0);
+ ip1811drv_dbg("Read IGMPPktForward_0 : %x\n", regdata);
+ rule_t = 0x000F<<type;
+ regdata &= ~rule_t;
+ regdata |= rule<<type;
+ ip1811drv_dbg("type : %d\n", type);
+ ip1811drv_dbg("rule : %x\n", rule);
+ ip1811drv_dbg("Write IGMPPktForward_0 : %x\n",regdata);
+ Write_Reg(P1REG_IGMPPKTFWD_0, regdata);
+ break;
+ case OP_IGMP_PACKET_REPORT:
+ case OP_IGMP_PACKET_GROUP_SPECIFIC_QUERY:
+ case OP_IGMP_PACKET_REG_DATA:
+ regdata = Read_Reg(P1REG_IGMPPKTFWD_1);
+ ip1811drv_dbg("Read IGMPPktForward_1 : %x\n", regdata);
+ rule_t = 0x001F<<(type-1);
+ regdata &= ~rule_t;
+ regdata |=rule<<(type-1);
+ ip1811drv_dbg("type : %d\n", type);
+ ip1811drv_dbg("rule : %x\n", rule);
+ ip1811drv_dbg("Write IGMPPktForward_1 : %x\n", regdata);
+ Write_Reg(P1REG_IGMPPKTFWD_1, regdata);
+ break;
+ default:
+ ip1811drv_dbg("Option can't find.\n");
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetIGMPPktForward);
+
+int setIGMPPktForward(void *cdata, int len)
+{
+ int ret;
+ struct IgmpPacketRule *igmp;
+ unsigned int pkt_type;
+ unsigned int pkt_rule;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In setIGMPPktForward.\n");
+ if (sizeof(struct IgmpPacketRule) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+ igmp = (struct IgmpPacketRule *)cdata;
+ pkt_type = igmp ->packet_type;
+ pkt_rule = igmp ->rule;
+ ret = switchdSetIGMPPktForward(pkt_type, pkt_rule);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetIGMPPktForward(unsigned int type, int *rule_p)
+{
+ u16 regdata;
+ u16 rule_t;
+
+ IP2Page(1);
+ switch(type){
+ case OP_IGMP_PACKET_QUERY:
+ case OP_IGMP_PACKET_LEAVE:
+ case OP_IGMP_PACKET_UN_REG_DATA:
+ case OP_IGMP_PACKET_UN_DEFINED:
+ regdata = Read_Reg(P1REG_IGMPPKTFWD_0);
+ ip1811drv_dbg("Read IGMPPktForward_0 : %x\n", regdata);
+ rule_t = 0x000F<<type;
+ regdata &= rule_t;
+ *rule_p = regdata>>(type);
+ ip1811drv_dbg("type : %d\n", type);
+ ip1811drv_dbg("Get rule : %x\n", *rule_p);
+ break;
+ case OP_IGMP_PACKET_REPORT:
+ case OP_IGMP_PACKET_GROUP_SPECIFIC_QUERY:
+ case OP_IGMP_PACKET_REG_DATA:
+ regdata = Read_Reg(P1REG_IGMPPKTFWD_1);
+ ip1811drv_dbg("Read IGMPPktForward_1 : %x\n", regdata);
+ rule_t = 0x001F<<(type-1);
+ regdata &= rule_t;
+ *rule_p = regdata>>(type-1);
+ ip1811drv_dbg("type : %d\n", type);
+ ip1811drv_dbg("Get rule : %x\n", *rule_p);
+ break;
+ default:
+ ip1811drv_dbg("Option can't find.\n");
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetIGMPPktForward);
+
+int getIGMPPktForward(void *cdata, int len)
+{
+ unsigned int pkt_type;
+ struct IgmpPacketRule *igmp;
+ int ret;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In getIGMPPktForward.\n");
+ if (sizeof(struct IgmpPacketRule) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+ igmp = (struct IgmpPacketRule *)cdata;
+ pkt_type = igmp ->packet_type;
+ ret = switchdGetIGMPPktForward(pkt_type, &(igmp ->rule));
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetIGMPRlt(unsigned int map, unsigned int tstate)
+{
+ u16 regdata;
+ u16 i, mask;
+
+ IP2Page(1);
+ regdata = Read_Reg(P1REG_ROUTLIST);
+ ip1811drv_dbg("Read [12-01] : %x\n", regdata);
+ mask = 0x01;
+ for(i=0; i<12;i++){
+ if((map&mask)!=0) {
+ if((tstate&mask)!=0)
+ regdata |= mask;
+ else
+ regdata &= ~mask;
+ }
+ mask <<= 1;
+ }
+ ip1811drv_dbg("Write new [12-01] : %x\n", regdata);
+ Write_Reg(P1REG_ROUTLIST, regdata);
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetIGMPRlt);
+
+int setIGMPRlt(void *cdata, int len)
+{
+ u16 map, value;
+ struct IgmpRouterListSetting *igmp;
+ int ret;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In setIGMPRlt.\n");
+ if (sizeof(struct IgmpRouterListSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct IgmpRouterListSetting *)cdata;
+ map = 0xFFF&(igmp ->portmask);
+ value = 0xFFF&(igmp ->tstate);
+
+ ip1811drv_dbg("map [12-01] : %x\n", map);
+ ip1811drv_dbg("val [12-01] : %x\n", value);
+
+ ret = switchdSetIGMPRlt(map, value);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetIGMPRlt(unsigned int map, int *value_p)
+{
+ u16 regdata, value, i, mask;
+
+ IP2Page(1);
+ regdata = Read_Reg(P1REG_ROUTLIST);
+ ip1811drv_dbg("Read [12-01] : %x\n", regdata&0xFFF);
+ mask = 0x01;
+ for(i=0; i<12; i++) {
+ if((map&mask)!=0){
+ if((regdata&mask)!=0)
+ value |= mask;
+ else
+ value &= ~mask;
+ }
+ mask <<= 1;
+ }
+
+ *value_p = value;
+ ip1811drv_dbg("Return value : %lx\n", *value_p);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetIGMPRlt);
+
+int getIGMPRlt(void *cdata, int len)
+{
+ u16 map, value, i, mask;
+ struct IgmpRouterListSetting *igmp;
+ int ret;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In getIGMPRlt.\n");
+ if (sizeof(struct IgmpRouterListSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+ igmp = (struct IgmpRouterListSetting *)cdata;
+
+ map = 0xFFF&(igmp ->portmask);
+ ip1811drv_dbg("map [12-01] : %x\n", map);
+
+ ret = switchdGetIGMPRlt(map, &(igmp ->tstate));
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetIGMPHashMethod(int hash_method)
+{
+ if (!(hash_method==OP_HASH_DIRECT || hash_method==OP_HASH_CRC))
+ return -EINVAL;
+
+ ip1811drv_dbg("Set Hash Method: %s\n", (hash_method==OP_HASH_DIRECT)?"DIRECT":"CRC");
+ _WriteRegBits(1, P1REG_IGMPSNOP, 6, 1,(hash_method==OP_HASH_DIRECT)?1:0);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetIGMPHashMethod);
+
+int setIGMPHashMethod(void *cdata, int len)
+{
+ int hash, ret;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ hash = ((struct GeneralSetting *)cdata) ->gdata;
+ ret = switchdSetIGMPHashMethod(hash);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetIGMPHashMethod(int *gdata_p)
+{
+ *gdata_p = (int)_ReadRegBits(1, P1REG_IGMPSNOP, 6, 1)?OP_HASH_DIRECT:OP_HASH_CRC;
+ ip1811drv_dbg("HASH METHOD %s",(*gdata_p==OP_HASH_DIRECT)?"DIRECT":"CRC");
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetIGMPHashMethod);
+
+int getIGMPHashMethod(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *igmp;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In getIGMPHashMethod.\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ igmp = (struct GeneralSetting *)cdata;
+ ret = switchdGetIGMPHashMethod(&(igmp ->gdata));
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetIGMPMldRule(int forwarding)
+{
+
+ ip1811drv_dbg("set ICMPv6 MLD forwarding: %x\n", forwarding);
+ _WriteRegBits(0, P0REG_IPV6RLTFWD, 8, 2, forwarding);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetIGMPMldRule);
+
+int setIGMPMldRule(void *cdata, int len)
+{
+ struct GeneralSetting *igmp;
+ int ret, forward;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In setIGMPMldRule.\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct GeneralSetting *)cdata;
+ forward = igmp ->gdata;
+ ret = switchdSetIGMPMldRule(forward);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetIGMPMldRule(int *gdata_p)
+{
+ *gdata_p = (int)_ReadRegBits(0, P0REG_IPV6RLTFWD, 8, 2);
+ ip1811drv_dbg("get ICMPv6 MLD forwarding: %x\n", *gdata_p);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetIGMPMldRule);
+
+int getIGMPMldRule(void *cdata, int len)
+{
+ struct GeneralSetting *igmp;
+ int ret;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In getIGMPMldRule.\n");
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct GeneralSetting *)cdata;
+ ret = switchdGetIGMPMldRule(&(igmp ->gdata));
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+void makeTable(u16 *tmpbuf, u16 offset, u32 value, u8 len)
+{
+ u16 ptr, set, tmpvalue;
+
+ ptr = offset/16;
+ set = offset%16;
+ ip1811drv_dbg("\n\nMakeTable:\noffset : %d\nvalue : %x\nlen : %d\n", offset, value, len);
+ ip1811drv_dbg("\nbuf[%d]=%x buf[%d]=%x\n", ptr, tmpbuf[ptr], ptr+1, tmpbuf[ptr+1]);
+ tmpvalue = (0xFFFF&value)<<set;
+ tmpbuf[ptr] |= tmpvalue;
+ ip1811drv_dbg("Result:\nbuf[%d] | %x = %x\n", ptr, tmpvalue, tmpbuf[ptr]);
+ if(len>(16-set)) {
+ len -= (16-set);
+ tmpvalue = 0xFFFF&(value>>(16-set));
+ tmpbuf[ptr+1] |= tmpvalue;
+ ip1811drv_dbg("buf[%d] | %x = %x\n", ptr+1, tmpvalue, tmpbuf[ptr+1]);
+ if(len>16){
+ tmpvalue = 0xFFFF&(value>>(32-set));
+ tmpbuf[ptr+2] |= tmpvalue;
+ ip1811drv_dbg("buf[%d] | %x = %x\n", ptr+2, tmpvalue, tmpbuf[ptr+2]);
+ }
+ }
+}
+
+u32 getTable(u16 *tmpbuf, u16 offset, u8 len)
+{
+ u32 value;
+ u16 ptr, set, tmpvalue, i, mask;
+ u16 debug;
+ ip1811drv_dbg("getTable:\n");
+ ip1811drv_dbg("offset = %d, len = %d", offset, len);
+ debug = offset/16;
+ ip1811drv_dbg("tmpbuf[%d] offset value:\n", debug);
+ for(i=0; i<3; i++)
+ ip1811drv_dbg("%04x ", tmpbuf[debug+i]);
+ ptr = (offset+len)/16;
+ set = (offset+len)%16;
+
+ if(len>=set){
+ mask = 0;
+ for(i=0; i<set; i++){
+ mask <<= 1;
+ mask |= 0x01;
+ }
+ tmpvalue = tmpbuf[ptr]&mask;
+ value = tmpvalue;
+ if((len-set)>=16) {
+ value <<= 16;
+ value |= tmpbuf[ptr-1];
+ if((len-set-16)>0){
+ value <<= (len-set-16);
+ value |= tmpbuf[ptr-2]>>(16-(len-set-16));
+ }
+ } else {
+ if(len!=set) {
+ value <<= (len-set);
+ value |= tmpbuf[ptr-1]>>(16-(len-set));
+ }
+ }
+ } else {
+ mask = 0;
+ for(i=0; i<set; i++){
+ mask <<= 1;
+ mask |= 0x01;
+ }
+ tmpvalue = tmpbuf[ptr]&mask;
+ value = tmpvalue>>(set-len);
+ }
+ ip1811drv_dbg("return %x\n",value);
+ return value;
+}
+
+/* ipv: 4: IPv4
+ * 6: IPv6
+ * addr: IP address
+ * method: 1: Direct
+ * 0: CRC
+ * */
+u8 tb_calc_index(u8 ipv, void *addr, u8 method)
+{
+ u8 index = 0;
+ u8 *u8_addr = (u8*)addr;
+
+ // Direct
+ if(method) {
+ if(ipv == 4) {
+ index = u8_addr[3];
+ } else if(ipv == 6) {
+ index = u8_addr[15];
+ }
+ } else { // CRC
+ int i;
+ bool crc[8], d[32];
+ bool c[8] = {1,1,1,1,1,1,1,1};
+
+ // init data
+ if(ipv == 4) {
+ for(i=0; i<32; i++)
+ d[i] = (bool)((u8_addr[i/8] >> (7-(i%8))) & 0x1);
+ } else if(ipv == 6) {
+ for(i=0; i<32; i++)
+ d[i] = (bool)((u8_addr[12+(i/8)] >> (7-(i%8))) & 0x1);
+ }
+
+ // calculate crc
+ crc[0] = d[31] ^ d[30] ^ d[28] ^ d[23] ^ d[21] ^ d[19] ^ d[18] ^ d[16] ^ d[14] ^ d[12] ^ d[8] ^ d[7] ^ d[6] ^ d[0] ^ c[4] ^ c[6] ^ c[7];
+
+ crc[1] = d[30] ^ d[29] ^ d[28] ^ d[24] ^ d[23] ^ d[22] ^ d[21] ^ d[20] ^ d[18] ^ d[17] ^ d[16] ^ d[15] ^ d[14] ^ d[13] ^ d[12] ^ d[9] ^ d[6] ^ d[1] ^ d[0] ^ c[0] ^ c[4] ^ c[5] ^ c[6];
+
+ crc[2] = d[29] ^ d[28] ^ d[25] ^ d[24] ^ d[22] ^ d[17] ^ d[15] ^ d[13] ^ d[12] ^ d[10] ^ d[8] ^ d[6]^ d[2] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[4] ^ c[5];
+
+ crc[3] = d[30] ^ d[29] ^ d[26] ^ d[25] ^ d[23] ^ d[18] ^ d[16] ^ d[14] ^ d[13] ^ d[11] ^ d[9] ^ d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[1] ^ c[2] ^ c[5] ^ c[6];
+
+ crc[4] = d[31] ^ d[30] ^ d[27] ^ d[26] ^ d[24] ^ d[19] ^ d[17] ^ d[15] ^ d[14] ^ d[12] ^ d[10] ^ d[8] ^ d[4] ^ d[3] ^ d[2] ^ c[0] ^ c[2] ^ c[3] ^ c[6] ^ c[7];
+
+ crc[5] = d[31] ^ d[28] ^ d[27] ^ d[25] ^ d[20] ^ d[18] ^ d[16] ^ d[15] ^ d[13] ^ d[11] ^ d[9] ^ d[5] ^ d[4] ^ d[3] ^ c[1] ^ c[3] ^ c[4] ^ c[7];
+
+ crc[6] = d[29] ^ d[28] ^ d[26] ^ d[21] ^ d[19] ^ d[17] ^ d[16] ^ d[14] ^ d[12] ^ d[10] ^ d[6] ^ d[5] ^ d[4] ^ c[2] ^ c[4] ^ c[5];
+
+ crc[7] = d[30] ^ d[29] ^ d[27] ^ d[22] ^ d[20] ^ d[18] ^ d[17] ^ d[15] ^ d[13] ^ d[11] ^ d[7] ^ d[6] ^ d[5] ^ c[3] ^ c[5] ^ c[6];
+
+ // get index
+ for(i=0; i<8; i++)
+ index |= ((u8)crc[i])<<i;
+ }
+
+ ip1811drv_dbg("tb_calc_index() index = %02u\n", index);
+ return index;
+}
+
+int switchdSetIGMPMctTable(int index, struct mt_rule *mt_data)
+{
+ u16 regdata[6] = {0};
+ u16 i, tmpvalue;
+
+ memset(regdata, 0, 11);
+ ip1811drv_dbg("driver:index: %x\n", index);
+ ip1811drv_dbg("driver:group: %x : %x : %x : %x\n", mt_data->group[0], mt_data->group[1], mt_data->group[2], mt_data->group[3]);
+ ip1811drv_dbg("driver:Set FID: %x\n", mt_data->fid);
+ ip1811drv_dbg("driver:Set age port:: %lx\n", mt_data->port_mem);
+ ip1811drv_dbg("driver:Set SIP: %x\n", mt_data->slt_index);
+ ip1811drv_dbg("driver:Set flag: %x\n", mt_data->flag);
+
+ //set Group
+ regdata[0] = (mt_data->group[2] << 8) | mt_data->group[3];
+ regdata[1] = (mt_data->group[0] << 8) | mt_data->group[1];
+ //set FID
+ makeTable(regdata, 32, mt_data->fid, 4);
+ //set Aging Member
+ for(i=0; i<12; i++) {
+ if(mt_data->port_mem & BIT(i)) {
+ makeTable(regdata, 36+i, 0x1, 1);
+ makeTable(regdata, 36+i+12, 0x1, 1);
+ makeTable(regdata, 36+i+24, 0x1, 1);
+ }
+ }
+ //set Pri
+ makeTable(regdata, 72, mt_data->pri, 4);
+ //set SIP
+ makeTable(regdata, 76, mt_data->slt_index, 5);
+ //set ver and CPU
+ makeTable(regdata, 81, mt_data->flag, 2);
+
+ IP2Page(1);
+ ip1811drv_dbg("driver:Write Mct Table Data:\n");
+ for(i=0; i<6; i++) {
+ ip1811drv_dbg("%04x ", regdata[i]);
+ Write_Reg(P1REG_MEM_MCT_TABLE_0+i, regdata[i]);
+ }
+ ip1811drv_dbg("\n");
+
+ tmpvalue = index;
+ tmpvalue |= 0xC000;
+ ip1811drv_dbg("\ndirver:Start Write [%04x]", tmpvalue);
+ Write_Reg(P1REG_MEM_MCT_COMMAND, tmpvalue);
+
+ tmpvalue = Read_Reg(P1REG_MEM_MCT_COMMAND);
+ while((tmpvalue&0x8000)!=0)
+ tmpvalue = Read_Reg(P1REG_MEM_MCT_COMMAND);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetIGMPMctTable);
+
+int setIGMPMctTable(void *cdata, int len){
+
+ int ret, index;
+ struct MtRuleSetting *igmp;
+ struct mt_rule *mt;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In setIGMPMctTable.\n");
+ if (sizeof(struct MtRuleSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct MtRuleSetting *)cdata;
+ index = igmp ->index;
+ mt = &(igmp ->mt_data);
+ ret = switchdSetIGMPMctTable(index, mt);
+ FUNC_MSG_OUT;
+
+ return 0;
+}
+
+int switchdGetIGMPMctTable(int index, struct mt_rule *mt_data)
+{
+ u16 regdata[6] = {0};
+ u16 i, j, tmpvalue;
+ u32 mask;
+
+ tmpvalue = index;
+ tmpvalue |= 0x8000;
+ IP2Page(1);
+ Write_Reg(P1REG_MEM_MCT_COMMAND, tmpvalue);
+ ip1811drv_dbg("driver:start read: %x\n", tmpvalue);
+
+ tmpvalue = Read_Reg(P1REG_MEM_MCT_COMMAND);
+ while((tmpvalue&0x8000)!=0)
+ tmpvalue = Read_Reg(P1REG_MEM_MCT_COMMAND);
+
+ ip1811drv_dbg("driver:index: %x\n", index);
+ ip1811drv_dbg("driver:Read Table Data:\n");
+ for(i=0; i<6; i++) {
+ regdata[i] = Read_Reg(P1REG_MEM_MCT_TABLE_0+i);
+ ip1811drv_dbg("%04x ", regdata[i]);
+ }
+ ip1811drv_dbg("\nRead Group:\n");
+ for(i=0; i<4; i++) {
+ mt_data->group[i] = getTable(regdata, (0+(8*i)), 8);
+ ip1811drv_dbg("%x ", mt_data->group[i]);
+ }
+
+ ip1811drv_dbg("\nRead FID:\n");
+ mt_data->fid = getTable(regdata, 32, 4);
+ ip1811drv_dbg("%x\n",mt_data->fid);
+
+ ip1811drv_dbg("Read Aging:\n");
+ mask = 0;
+ for(i=0; i<12; i++){
+ int val = 0;
+ for(j=0; j<3; j++) {
+ if(getTable(regdata, (36+i+(12*j)), 1)!=0 )
+ val++;
+ }
+ if(val)
+ mask |= 0x01<<i;
+ }
+ ip1811drv_dbg("%x\n", mask);
+ mt_data->port_mem = mask;
+
+ ip1811drv_dbg("Read Priority:\n");
+ mt_data->pri = getTable(regdata, 72, 4);
+ ip1811drv_dbg("%x\n",mt_data->pri);
+
+ ip1811drv_dbg("Read SLT index:\n");
+ mt_data->slt_index = getTable(regdata, 76, 5);
+ ip1811drv_dbg("%x\n",mt_data->slt_index);
+
+ ip1811drv_dbg("Read flag:\n");
+ mt_data->flag = getTable(regdata, 81, 2);
+ ip1811drv_dbg("%x\n",mt_data->flag);
+
+ printk(KERN_ERR "\nGroup:");
+ for(i=0;i<4;i++)
+ printk(KERN_ERR " %d", mt_data->group[i]);
+ printk(KERN_ERR "\nFID: %x", mt_data->fid);
+ printk(KERN_ERR "\nPort member: %lx", (unsigned long)mt_data->port_mem);
+ printk(KERN_ERR "\nPriority: %d", (mt_data->pri&0x07));
+ printk(KERN_ERR "\nSLT index: %x", mt_data->slt_index);
+ printk(KERN_ERR "\nFlag: %x\n", mt_data->flag);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetIGMPMctTable);
+
+int getIGMPMctTable(void *cdata, int len){
+ int ret, index;
+ struct MtRuleSetting *igmp;
+ struct mt_rule *mt;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In getIGMPMctTable.\n");
+ if (sizeof(struct MtRuleSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct MtRuleSetting *)cdata;
+ index = igmp ->index;
+ mt = &(igmp ->mt_data);
+ ret = switchdGetIGMPMctTable(index, mt);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetIGMPSltTable(int index, struct slt_rule *slt_data)
+{
+ u16 regdata[19] = {0};
+ u16 i, j, tmpvalue;
+
+ if(slt_data->type == OP_IGMP_SLT_IPV4) {
+ //set IP
+ for(i=0; i<6; i++){
+ regdata[i*2] = (slt_data->data.ipv4.ip[i][2] << 8) | slt_data->data.ipv4.ip[i][3];
+ regdata[i*2+1] = (slt_data->data.ipv4.ip[i][0] << 8) | slt_data->data.ipv4.ip[i][1];
+ }
+ //set User Define
+ for(i=0; i<6; i++)
+ makeTable(regdata, (192+(12*i)), slt_data->data.ipv4.used_port[i], 12);
+ }else{
+ //set IP
+ for(i=0; i<2; i++){
+ for(j=0; j<8; j++)
+ makeTable(regdata, ((128*i)+(16*j)), slt_data->data.ipv6.ip[i][7-j], 16);
+ }
+ //set User Define
+ for(i=0; i<2 ;i++)
+ makeTable(regdata, (256+(12*i)), slt_data->data.ipv6.used_port[i], 12);
+ }
+
+ ip1811drv_dbg("SLT Table Data:");
+ IP2Page(1);
+ for(i=0; i<19; i++) {
+ if((i%16)==0)
+ ip1811drv_dbg("\n");
+ ip1811drv_dbg("%04x ", regdata[i]);
+ Write_Reg(P1REG_MEM_SLT_TABLE_0+i, regdata[i]);
+ }
+ tmpvalue = index;
+ tmpvalue |= 0xC000;
+ ip1811drv_dbg("\ndirver:Start Write [%04x]", tmpvalue);
+ Write_Reg(P1REG_MEM_SLT_COMMAND, tmpvalue);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetIGMPSltTable);
+
+int setIGMPSltTable(void *cdata, int len){
+ int ret, index;
+ struct SltRuleSetting *igmp;
+ struct slt_rule *slt;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In setIGMPSltTable.\n");
+ if (sizeof(struct SltRuleSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct SltRuleSetting *)cdata;
+ index = igmp ->index;
+ slt = &(igmp ->slt_data);
+ ret = switchdSetIGMPSltTable(index, slt);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetIGMPSltTable(int index, struct slt_rule *slt_data)
+{
+ u16 regdata[19] = {0};
+ u16 i, j, tmpvalue;
+
+ tmpvalue = index;
+ tmpvalue |= 0x8000;
+ IP2Page(1);
+ Write_Reg(P1REG_MEM_SLT_COMMAND, tmpvalue);
+
+ tmpvalue = Read_Reg(P1REG_MEM_SLT_COMMAND);
+ while( (tmpvalue&0x8000)!=0 )
+ tmpvalue = Read_Reg(P1REG_MEM_SLT_COMMAND);
+
+ ip1811drv_dbg("Read SLT Table:");
+ for(i=0; i<19; i++) {
+ regdata[i] = Read_Reg(P1REG_MEM_SLT_TABLE_0+i);
+ if(i%16==0)
+ ip1811drv_dbg("\n");
+ ip1811drv_dbg("%04x ", regdata[i]);
+ }
+
+ if(slt_data->type == OP_IGMP_SLT_IPV4){
+ ip1811drv_dbg("Read IPv4:\n");
+ printk(KERN_ERR "\nRead IPv4:");
+ for(i=0; i<6; i++) {
+ printk(KERN_ERR "\n");
+ for(j=0; j<4; j++) {
+ slt_data->data.ipv4.ip[i][j] = getTable(regdata, ((32*i)+(8*j)), 8 );
+ printk(KERN_ERR " %d", slt_data->data.ipv4.ip[i][j]);
+ }
+ }
+ ip1811drv_dbg("Read Used Define:\n");
+ printk(KERN_ERR "\nUsed Define:\n");
+ for(i=0; i<6; i++) {
+ slt_data->data.ipv4.used_port[i] = getTable(regdata, (192+(12*i)), 12);
+ printk(KERN_ERR " %04lx", (unsigned long)slt_data->data.ipv4.used_port[i]);
+ }
+ }else{
+ ip1811drv_dbg("Read IPv6:\n");
+ printk(KERN_ERR "\nRead IPv6:");
+ for(i=0; i<2; i++) {
+ printk(KERN_ERR "\n");
+ for(j=0; j<8; j++) {
+ slt_data->data.ipv6.ip[i][j] = getTable(regdata, ((128*i)+(16*j)), 16);
+ printk(KERN_ERR " %04x", slt_data->data.ipv6.ip[i][j]);
+ }
+ }
+ ip1811drv_dbg("Read Used Define:\n");
+ printk(KERN_ERR "\nUsed Define:\n");
+ for(i=0; i<2;i++) {
+ slt_data->data.ipv6.used_port[i] = getTable(regdata, (256+(12*i)), 12);
+ printk(KERN_ERR " %04lx", (unsigned long)slt_data->data.ipv6.used_port[i]);
+ }
+ }
+ printk(KERN_ERR "\n");
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetIGMPSltTable);
+
+int getIGMPSltTable(void *cdata, int len){
+ int ret, index;
+ struct SltRuleSetting *igmp;
+ struct slt_rule *slt;
+
+ FUNC_MSG_IN;
+ ip1811drv_dbg("In getIGMPSltTable.\n");
+ if (sizeof(struct SltRuleSetting) != len) {
+ ip1811drv_err("length error!\n");
+ return -EINVAL;
+ }
+
+ igmp = (struct SltRuleSetting *)cdata;
+ index = igmp ->index;
+ slt = &(igmp ->slt_data);
+ ret = switchdGetIGMPSltTable(index, slt);
+ FUNC_MSG_OUT;
+
+ return 0;
+}
+
+//------------------------------------------------
+//ip1811_sniffer
+int switchdSetS1PktModify(int modify)
+{
+ if (modify!=OP_SNIFFER1_PKT_MODIFY && modify!=OP_SNIFFER1_PKT_KEEP)
+ return -EINVAL;
+ ip1811drv_dbg("modify=%d\n", modify);
+
+ _WriteRegBits(1, P1REG_SNIFCFG, 2, 1, modify);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetS1PktModify);
+int setS1PktModify(void *cdata, int len)
+{
+ int modify;
+
+ ip1811drv_dbg("ip1811: +setS1PktModify...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ modify = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetS1PktModify(modify) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setS1PktModify...\n");
+ return 0;
+}
+
+int switchdGetS1PktModify(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(1, P1REG_SNIFCFG, 2, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetS1PktModify);
+int getS1PktModify(void *cdata, int len)
+{
+ int modify;
+
+ ip1811drv_dbg("ip1811: +getS1PktModify...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetS1PktModify(&modify) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = modify;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getS1PktModify...\n");
+ return 0;
+}
+
+int switchdSetS1TM4CpuSTag(int modify)
+{
+ if (modify!=OP_SNIFFER1_TAG_KEEP && modify!=OP_SNIFFER1_TAG_MODIFY)
+ return -EINVAL;
+ ip1811drv_dbg("modify=%d\n", modify);
+
+ _WriteRegBits(1, P1REG_SNIFCFG, 5, 1, modify);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetS1TM4CpuSTag);
+int setS1TM4CpuSTag(void *cdata, int len)
+{
+ int modify;
+
+ ip1811drv_dbg("ip1811: +setS1TM4CpuSTag...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ modify = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetS1TM4CpuSTag(modify) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setS1TM4CpuSTag...\n");
+ return 0;
+}
+
+int switchdGetS1TM4CpuSTag(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(1, P1REG_SNIFCFG, 5, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetS1TM4CpuSTag);
+int getS1TM4CpuSTag(void *cdata, int len)
+{
+ int modify;
+
+ ip1811drv_dbg("ip1811: +getS1TM4CpuSTag...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetS1TM4CpuSTag(&modify) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = modify;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getS1TM4CpuSTag...\n");
+ return 0;
+}
+
+int switchdSetS1TM4Acl2Cpu(int modify)
+{
+ if (modify!=OP_SNIFFER1_TAG_KEEP && modify!=OP_SNIFFER1_TAG_MODIFY)
+ return -EINVAL;
+ ip1811drv_dbg("modify=%d\n", modify);
+
+ _WriteRegBits(1, P1REG_SNIFCFG, 6, 1, modify);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetS1TM4Acl2Cpu);
+int setS1TM4Acl2Cpu(void *cdata, int len)
+{
+ int modify;
+
+ ip1811drv_dbg("ip1811: +setS1TM4Acl2Cpu...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ modify = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetS1TM4Acl2Cpu(modify) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setS1TM4Acl2Cpu...\n");
+ return 0;
+}
+
+int switchdGetS1TM4Acl2Cpu(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(1, P1REG_SNIFCFG, 6, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetS1TM4Acl2Cpu);
+int getS1TM4Acl2Cpu(void *cdata, int len)
+{
+ int modify;
+
+ ip1811drv_dbg("ip1811: +getS1TM4Acl2Cpu...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetS1TM4Acl2Cpu(&modify) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = modify;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getS1TM4Acl2Cpu...\n");
+ return 0;
+}
+
+int switchdSetS1TM4Pkt2MPort(int modify)
+{
+ if (modify!=OP_SNIFFER1_TAG_KEEP && modify!=OP_SNIFFER1_TAG_MODIFY)
+ return -EINVAL;
+ ip1811drv_dbg("modify=%d\n", modify);
+
+ _WriteRegBits(1, P1REG_SNIFCFG, 7, 1, modify);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetS1TM4Pkt2MPort);
+int setS1TM4Pkt2MPort(void *cdata, int len)
+{
+ int modify;
+
+ ip1811drv_dbg("ip1811: +setS1TM4Pkt2MPort...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ modify = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetS1TM4Pkt2MPort(modify) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setS1TM4Pkt2MPort...\n");
+ return 0;
+}
+
+int switchdGetS1TM4Pkt2MPort(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(1, P1REG_SNIFCFG, 7, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetS1TM4Pkt2MPort);
+int getS1TM4Pkt2MPort(void *cdata, int len)
+{
+ int modify;
+
+ ip1811drv_dbg("ip1811: +getS1TM4Pkt2MPort...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetS1TM4Pkt2MPort(&modify) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = modify;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getS1TM4Pkt2MPort...\n");
+ return 0;
+}
+
+int switchdSetS2LTT4Grp1(int ltt)
+{
+ if (ltt!=OP_SNIFFER2_LUT_TRIGGER_TARGET_DA && ltt!=OP_SNIFFER2_LUT_TRIGGER_TARGET_SA)
+ return -EINVAL;
+ ip1811drv_dbg("ltt=%d\n", ltt);
+
+ _WriteRegBits(1, P1REG_SNIFCFG, 3, 1, ltt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetS2LTT4Grp1);
+int setS2LTT4Grp1(void *cdata, int len)
+{
+ int ltt;
+
+ ip1811drv_dbg("ip1811: +setS2LTT4Grp1...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ ltt = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetS2LTT4Grp1(ltt) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setS2LTT4Grp1...\n");
+ return 0;
+}
+
+int switchdGetS2LTT4Grp1(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(1, P1REG_SNIFCFG, 3, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetS2LTT4Grp1);
+int getS2LTT4Grp1(void *cdata, int len)
+{
+ int ltt;
+
+ ip1811drv_dbg("ip1811: +getS2LTT4Grp1...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetS2LTT4Grp1(<t) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = ltt;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getS2LTT4Grp1...\n");
+ return 0;
+}
+
+//------------------------------------------------
+//ip1811_storm
+int switchdSetMStormNBlockIpPkt(int nb)
+{
+ if (nb!=OP_FUNC_DISABLE && nb!=OP_FUNC_ENABLE)
+ return -EINVAL;
+ ip1811drv_dbg("nb=%d\n", nb);
+
+ _WriteRegBits(1, P1REG_BSTORMTHRESH, 11, 1, nb);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetMStormNBlockIpPkt);
+int setMStormNBlockIpPkt(void *cdata, int len)
+{
+ int nb;
+
+ ip1811drv_dbg("ip1811: +setMStormNBlockIpPkt...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ nb = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetMStormNBlockIpPkt(nb) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setMStormNBlockIpPkt...\n");
+ return 0;
+}
+
+int switchdGetMStormNBlockIpPkt(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(1, P1REG_BSTORMTHRESH, 11, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetMStormNBlockIpPkt);
+int getMStormNBlockIpPkt(void *cdata, int len)
+{
+ int nb;
+
+ ip1811drv_dbg("ip1811: +getMStormNBlockIpPkt...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetMStormNBlockIpPkt(&nb) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = nb;
+
+ ip1811drv_dbg("ip1811: -getMStormNBlockIpPkt...\n");
+ return 0;
+}
+
+int switchdSetMStormIgnr01005EXXXXXX(int ignr)
+{
+ if (ignr!=OP_FUNC_DISABLE && ignr!=OP_FUNC_ENABLE)
+ return -EINVAL;
+ ip1811drv_dbg("ignr=%d\n", ignr);
+
+ _WriteRegBits(1, P1REG_BSTORMTHRESH, 12, 1, ignr);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetMStormIgnr01005EXXXXXX);
+int setMStormIgnr01005EXXXXXX(void *cdata, int len)
+{
+ int ignr;
+
+ ip1811drv_dbg("ip1811: +setMStormIgnr01005EXXXXXX...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ ignr = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetMStormIgnr01005EXXXXXX(ignr) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setMStormIgnr01005EXXXXXX...\n");
+ return 0;
+}
+
+int switchdGetMStormIgnr01005EXXXXXX(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(1, P1REG_BSTORMTHRESH, 12, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetMStormIgnr01005EXXXXXX);
+int getMStormIgnr01005EXXXXXX(void *cdata, int len)
+{
+ int en=0;
+
+ ip1811drv_dbg("ip1811: +getMStormIgnr01005EXXXXXX...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetMStormIgnr01005EXXXXXX(&en) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = en;
+
+ ip1811drv_dbg("ip1811: -getMStormIgnr01005EXXXXXX...\n");
+ return 0;
+}
+
+//ip1811_stp
+int switchdSetBpduCapMode(int bcmode)
+{
+ if (bcmode!=OP_BPDU_CMODE_GLOBAL && bcmode!=OP_BPDU_CMODE_BY_PORT)
+ return -EINVAL;
+ ip1811drv_dbg("bcmode=%d\n", bcmode);
+
+ _WriteRegBits(0, P0REG_MACBEHAVIOR, 10, 1, bcmode);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetBpduCapMode);
+int setBpduCapMode(void *cdata, int len)
+{
+ int bcmode;
+
+ ip1811drv_dbg("ip1811: +setBpduCapMode...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ bcmode = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetBpduCapMode(bcmode) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setBpduCapMode...\n");
+ return 0;
+}
+
+int switchdGetBpduCapMode(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(0, P0REG_MACBEHAVIOR, 10, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetBpduCapMode);
+int getBpduCapMode(void *cdata, int len)
+{
+ int bcmode;
+
+ ip1811drv_dbg("ip1811: +getBpduCapMode...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetBpduCapMode(&bcmode) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = bcmode;
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getBpduCapMode...\n");
+ return 0;
+}
+
+int switchdSetBpduPortAct(int port, int state)
+{
+ u16 u16dat;
+
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if (state!=OP_CAP_ACT_FORWARD && state!=OP_CAP_ACT_TO_CPU && state!=OP_CAP_ACT_DROP)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("state=%d\n", state);
+
+ IP2Page(0);
+ u16dat = Read_Reg(P0REG_BPDUPORTCAPCFG);
+ u16dat |= (u16)((state&0x1) << (port));
+#ifdef COMBINED_PORT
+ if (port==9)
+ u16dat |= (u16)((state&0x1) << (port+1));
+#endif
+ Write_Reg(P0REG_BPDUPORTCAPCFG, u16dat);
+
+ u16dat = Read_Reg(P0REG_BPDUPORTCAPCFG+2);
+ u16dat |= (u16)(((state>>1)&0x1) << (port));
+#ifdef COMBINED_PORT
+ if (port==9)
+ u16dat |= (u16)(((state>>1)&0x1) << (port+1));
+#endif
+ Write_Reg(P0REG_BPDUPORTCAPCFG+2, u16dat);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetBpduPortAct);
+int setBpduPortAct(void *cdata, int len)
+{
+ int port, state;
+
+ ip1811drv_dbg("ip1811: +setBpduPortAct...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+ state= ((struct ByPortSetting *)cdata) ->pdata;
+
+ if(switchdSetBpduPortAct(port, state) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setBpduPortAct...\n");
+ return 0;
+}
+
+int switchdGetBpduPortAct(int port, int *ptrInt)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *ptrInt = (int)(_ReadRegBits(0, P0REG_BPDUPORTCAPCFG+2, port, 1) | _ReadRegBits(0, P0REG_BPDUPORTCAPCFG, port, 1));
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetBpduPortAct);
+int getBpduPortAct(void *cdata, int len)
+{
+ int port, state;
+
+ ip1811drv_dbg("ip1811: +getBpduPortAct...\n");
+ if (sizeof(struct ByPortSetting) != len)
+ return -EINVAL;
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ if(switchdGetBpduPortAct(port, &state) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = state;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ ip1811drv_dbg("ip1811: -getBpduPortAct...\n");
+ return 0;
+}
+
+int switchdSetStpPortState(int fid, int port, int state)
+{
+ u16 u16dat=0;
+
+ if (fid < 1 || fid > 16)
+ return -EINVAL;
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if (state < OP_STP_STATE_DISCARD || state > OP_STP_STATE_FORWARD)
+ return -EINVAL;
+ ip1811drv_dbg("fid=%d\n", fid);
+ ip1811drv_dbg("port=%d\n", port);
+ ip1811drv_dbg("state=%d\n", state);
+
+ fid--;
+ IP2Page(2);
+ Write_Reg(P2REG_SPANTREE_PORTCMD, (u16)(0x8010 | fid));
+ u16dat = Read_Reg(P2REG_SPANTREE_PORTDTA);
+ switch(state){
+ case OP_STP_STATE_DISCARD:
+ case OP_STP_STATE_BLOCK:
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9)
+ u16dat &= (u16)~(1 << port+1);
+#endif
+ break;
+ case OP_STP_STATE_LEARN:
+ case OP_STP_STATE_FORWARD:
+ u16dat |= (u16)(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9)
+ u16dat |= (u16)(1 << port+1);
+#endif
+ break;
+ }
+ Write_Reg(P2REG_SPANTREE_PORTDTA, u16dat & 0xFFFF);
+ Write_Reg(P2REG_SPANTREE_PORTCMD, (u16)(0xC010 | fid));
+
+ Write_Reg(P2REG_SPANTREE_PORTCMD, (u16)(0x8000 | fid));
+ u16dat = Read_Reg(P2REG_SPANTREE_PORTDTA);
+ switch(state){
+ case OP_STP_STATE_DISCARD:
+ case OP_STP_STATE_LEARN:
+ u16dat &= (u16)~(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9)
+ u16dat &= (u16)~(1 << port+1);
+#endif
+ break;
+ case OP_STP_STATE_BLOCK:
+ case OP_STP_STATE_FORWARD:
+ u16dat |= (u16)(1 << port);
+#ifdef COMBINED_PORT
+ if (port==9)
+ u16dat |= (u16)(1 << port+1);
+#endif
+ break;
+ }
+ Write_Reg(P2REG_SPANTREE_PORTDTA, u16dat & 0xFFFF);
+ Write_Reg(P2REG_SPANTREE_PORTCMD, (u16)(0xC000 | fid));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetStpPortState);
+int setStpPortState(void *cdata, int len)
+{
+ int fid, port, state;
+
+ ip1811drv_dbg("ip1811: +setStpPortState...\n");
+ if (sizeof(struct StpByFPSetting) != len)
+ return -EINVAL;
+
+ fid = ((struct StpByFPSetting *)cdata) ->fid;
+ port= ((struct StpByFPSetting *)cdata) ->port;
+ state=((struct StpByFPSetting *)cdata) ->pstate;
+
+ if(switchdSetStpPortState(fid, port, state) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setStpPortState...\n");
+ return 0;
+}
+
+int switchdGetStpPortState(int fid, int port, int *ptrInt)
+{
+ int state;
+ u16 u16dat=0;
+
+ if (fid < 1 || fid > 16)
+ return -EINVAL;
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ ip1811drv_dbg("fid=%d\n", fid);
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ fid--;
+ IP2Page(2);
+ Write_Reg(P2REG_SPANTREE_PORTCMD, (u16)(0x8010 | fid));
+ u16dat = Read_Reg(P2REG_SPANTREE_PORTDTA);
+ state = ((u16dat>>port)&0x1)<<1;
+ Write_Reg(P2REG_SPANTREE_PORTCMD, (u16)(0x8000 | fid));
+ u16dat = Read_Reg(P2REG_SPANTREE_PORTDTA);
+ state |= ((u16dat>>port)&0x1);
+
+ *ptrInt = state;
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetStpPortState);
+int getStpPortState(void *cdata, int len)
+{
+ int fid, port, state;
+
+ ip1811drv_dbg("ip1811: +getStpPortState...\n");
+ if (sizeof(struct StpByFPSetting) != len)
+ return -EINVAL;
+
+ fid = ((struct StpByFPSetting *)cdata) ->fid;
+ port= ((struct StpByFPSetting *)cdata) ->port;
+
+ if(switchdGetStpPortState(fid, port, &state) != 0)
+ return -EINVAL;
+
+ ((struct StpByFPSetting *)cdata) ->pstate = state;
+ ip1811drv_dbg("cdata ->pstate=%d\n", ((struct StpByFPSetting *)cdata) ->pstate);
+ ip1811drv_dbg("ip1811: -getStpPortState...\n");
+ return 0;
+}
+
+//ip1811_lacp
+int switchdSetTrunkHashMthdSeq(int en)
+{
+ if (en!=OP_FUNC_DISABLE && en!=OP_FUNC_ENABLE)
+ return -EINVAL;
+ ip1811drv_dbg("en=%d\n", en);
+
+ _WriteRegBits(1, P1REG_TRUNKCFG, 3, 1, en);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetTrunkHashMthdSeq);
+int setTrunkHashMthdSeq(void *cdata, int len)
+{
+ int en;
+
+ ip1811drv_dbg("ip1811: +setTrunkHashMthdSeq...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ en = ((struct GeneralSetting *)cdata) ->gdata;
+
+ if(switchdSetTrunkHashMthdSeq(en) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setTrunkHashMthdSeq...\n");
+ return 0;
+}
+
+int switchdGetTrunkHashMthdSeq(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(1, P1REG_TRUNKCFG, 3, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetTrunkHashMthdSeq);
+int getTrunkHashMthdSeq(void *cdata, int len)
+{
+ int en;
+
+ ip1811drv_dbg("ip1811: +getTrunkHashMthdSeq...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ if(switchdGetTrunkHashMthdSeq(&en) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata) ->gdata = en;
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getTrunkHashMthdSeq...\n");
+ return 0;
+}
+
+int switchdSetTrunkGrpCombine(int grps, int en)
+{
+ if (grps < OP_TRUNK_COMBINE_G1_G2 || grps > OP_TRUNK_COMBINE_G3_G4)
+ return -EINVAL;
+ if (en!=OP_FUNC_DISABLE && en!=OP_FUNC_ENABLE)
+ return -EINVAL;
+ ip1811drv_dbg("grps=%d\n", grps);
+ ip1811drv_dbg("en=%d\n", en);
+
+ _WriteRegBits(1, P1REG_TRUNKCFG, grps, 1, en);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetTrunkGrpCombine);
+int setTrunkGrpCombine(void *cdata, int len)
+{
+ int grps, en;
+
+ ip1811drv_dbg("ip1811: +setTrunkGrpCombine...\n");
+ if (sizeof(struct TrunkCombineSetting) != len)
+ return -EINVAL;
+
+ grps=((struct TrunkCombineSetting *)cdata) ->tgrps;
+ en = ((struct TrunkCombineSetting *)cdata) ->cen;
+
+ if(switchdSetTrunkGrpCombine(grps, en) != 0)
+ return -EINVAL;
+
+ ip1811drv_dbg("ip1811: -setTrunkGrpCombine...\n");
+ return 0;
+}
+
+int switchdGetTrunkGrpCombine(int grps, int *ptrInt)
+{
+ if (grps < OP_TRUNK_COMBINE_G1_G2 || grps > OP_TRUNK_COMBINE_G3_G4)
+ return -EINVAL;
+ ip1811drv_dbg("grps=%d\n", grps);
+
+ *ptrInt = (int)_ReadRegBits(1, P1REG_TRUNKCFG, grps, 1);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetTrunkGrpCombine);
+int getTrunkGrpCombine(void *cdata, int len)
+{
+ int grps, en;
+
+ ip1811drv_dbg("ip1811: +getTrunkGrpCombine...\n");
+ if (sizeof(struct TrunkCombineSetting) != len)
+ return -EINVAL;
+
+ grps=((struct TrunkCombineSetting *)cdata) ->tgrps;
+
+ if(switchdGetTrunkGrpCombine(grps, &en) != 0)
+ return -EINVAL;
+
+ ((struct TrunkCombineSetting *)cdata) ->cen = en;
+ ip1811drv_dbg("cdata ->cen=%d\n", ((struct TrunkCombineSetting *)cdata) ->cen);
+ ip1811drv_dbg("ip1811: -getTrunkGrpCombine...\n");
+ return 0;
+}
+
+//------------ MIB Counter functions:ip1811 ---------------------
+int switchdSetMibCounterEnable(int en)
+{
+ if( en!=OP_FUNC_ENABLE && en!=OP_FUNC_DISABLE ){
+ ip1811drv_err("Error: en=%X\n", en);
+ return -EINVAL;
+ }
+ _WriteRegBits(0, P0REG_MACBEHAVIOR, 9, 1, en);
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetMibCounterEnable);
+
+int setMibCounterEnable(void *cdata, int len)
+{
+ int ret, en;
+ FUNC_MSG_IN;
+
+ if (sizeof(struct GeneralSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ en = ((struct GeneralSetting *)cdata) ->gdata;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", en);
+ ret = switchdSetMibCounterEnable(en);
+
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int switchdGetMibCounterEnable(int *gdata_p)
+{
+ *gdata_p = _ReadRegBits(0, P0REG_MACBEHAVIOR, 9, 1);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetMibCounterEnable);
+
+int getMibCounterEnable(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *gs = (struct GeneralSetting *)cdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ ret = switchdGetMibCounterEnable(&(gs ->gdata));
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int switchdGetMibCounterAll(void *uptr)
+{
+ int i, j, ret=0;
+ struct MIBCounterEntry_all *dptr;
+
+ dptr = kmalloc(sizeof(struct MIBCounterEntry_all), GFP_KERNEL);
+ if (!dptr) {
+ ret = -ENOMEM;
+ goto out_mib_counter_all;
+ }
+
+ IP2Page(0);
+ for(j=0; j<MAX_PHY_NUM; j++) {
+ for(i=0; i<NUM_MIB_COUNTER_RX; i++) {
+ //statistic counter read , read clear rx counter
+ Write_Reg(POREG_MIBCOUN_CMD, 0xC000|(u16)i|((u16)j<<5));
+ /* need to check does trigger bit has been put down */
+ while((Read_Reg(POREG_MIBCOUN_CMD) >> 15)&0x1);
+
+ dptr ->entry[j].RX_counter[i] = (u32)Read_Reg(POREG_MIBCOUN_DATA_L);
+ dptr ->entry[j].RX_counter[i] |= ((u32)Read_Reg(POREG_MIBCOUN_DATA_H)<<16);
+ }
+ for(i=0; i<NUM_MIB_COUNTER_TX; i++) {
+ //statistic counter read , read clear tx counter
+ Write_Reg(POREG_MIBCOUN_CMD,0xC400|(u16)i|((u16)j<<5));
+ /* need to check does trigger bit has been put down */
+ while((Read_Reg(POREG_MIBCOUN_CMD) >> 15)&0x1);
+
+ dptr ->entry[j].TX_counter[i] = (u32)Read_Reg(POREG_MIBCOUN_DATA_L);
+ dptr ->entry[j].TX_counter[i] |= ((u32)Read_Reg(POREG_MIBCOUN_DATA_H)<<16);
+ }
+ }
+ if (copy_to_user(uptr, dptr, sizeof(struct MIBCounterEntry_all))) {
+ ret = -EFAULT;
+ goto out_mib_counter_all;
+ }
+out_mib_counter_all:
+ if(dptr){
+ kfree(dptr);
+ }
+ return (ret < 0) ? ret : 0;
+}
+EXPORT_SYMBOL(switchdGetMibCounterAll);
+
+int getMibCounterAll(void *cdata, int len)
+{
+ int ret;
+ void *uptr;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ uptr = (void *)(((struct GeneralSetting *)cdata) ->gdata);
+ ret = switchdGetMibCounterAll(uptr);
+
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int switchdGetMibCounterByPort(void *uptr, int port)
+{
+ int i, ret;
+ struct MIBCounterEntry *dptr;
+
+ dptr = kmalloc(sizeof(struct MIBCounterEntry), GFP_KERNEL);
+ if (!dptr) {
+ ret = -ENOMEM;
+ goto out_mib_counter;
+ }
+ IP2Page(0);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ for(i=0; i<NUM_MIB_COUNTER_RX; i++) {
+ //statistic counter read , read clear rx counter
+ Write_Reg(POREG_MIBCOUN_CMD, 0xC000|(u16)i|((u16)port<<5));
+ /* need to check does trigger bit has been put down */
+ while((Read_Reg(POREG_MIBCOUN_CMD) >> 15)&0x1);
+ dptr ->RX_counter[i] = (u32)(((u32)Read_Reg(POREG_MIBCOUN_DATA_H)<<16)|Read_Reg(POREG_MIBCOUN_DATA_L));
+ }
+ for(i=0; i<NUM_MIB_COUNTER_TX; i++) {
+ //statistic counter read , read clear tx counter
+ Write_Reg(POREG_MIBCOUN_CMD, 0xC400|(u16)i|((u16)port<<5));
+ /* need to check does trigger bit has been put down */
+ while((Read_Reg(POREG_MIBCOUN_CMD) >> 15)&0x1);
+ dptr ->TX_counter[i] = (u32)(((u32)Read_Reg(POREG_MIBCOUN_DATA_H)<<16)|Read_Reg(POREG_MIBCOUN_DATA_L));
+ }
+ if (copy_to_user(uptr, dptr, sizeof(struct MIBCounterEntry))) {
+ ret = -EFAULT;
+ goto out_mib_counter;
+ }
+out_mib_counter:
+ if(dptr) {
+ kfree(dptr);
+ }
+
+ return (ret < 0) ? ret : 0;
+}
+EXPORT_SYMBOL(switchdGetMibCounterByPort);
+
+int getMibCounterByPort(void *cdata, int len)
+{
+ int port, ret;
+ void *uptr;
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ uptr = (void *)(((struct ByPortSetting *)cdata) ->pdata);
+ port = ((struct ByPortSetting *)cdata) ->port;
+
+ ret = switchdGetMibCounterByPort(uptr, port);
+
+ FUNC_MSG_OUT;
+ return ret;
+}
+
+int switchdGetMibCounterByItem(int port, int is_tx, int idx, unsigned long *cnt)
+{
+ IP2Page(0);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ //statistic counter read , read clear rx counter
+ Write_Reg(POREG_MIBCOUN_CMD, (is_tx?0xC400:0xC000)|(u16)idx|((u16)port<<5));
+ /* need to check does trigger bit has been put down */
+ while((Read_Reg(POREG_MIBCOUN_CMD) >> 15)&0x1);
+
+ *cnt = (u32)(((u32)Read_Reg(POREG_MIBCOUN_DATA_H)<<16)|Read_Reg(POREG_MIBCOUN_DATA_L));
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetMibCounterByItem);
+
+int getMibCounterByItem(void *cdata, int len)
+{
+ int port, dir, idx, ret;
+ unsigned long mibcnt;
+ struct MIBCounterData *mcd = (struct MIBCounterData *)cdata;
+
+ FUNC_MSG_IN;
+
+ if (sizeof(struct MIBCounterData) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ port = mcd ->port;
+ dir = mcd ->dir;
+ idx = mcd ->idx;
+
+ ret = switchdGetMibCounterByItem(port, dir, idx, &mibcnt);
+ mcd ->counter = mibcnt;
+
+ FUNC_MSG_OUT;
+ return ret;
+
+}
+
+//------------ MIB Counter functions:ip1811 end------------------
+//------------ QOS functions:ip1811 -----------------------------
+int setQOSAgingFunction(void *cdata, int len)
+{
+ int port,aging;
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ port=((struct ByPortSetting *)cdata) ->port;
+ aging =((struct ByPortSetting *)cdata) ->pdata;
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+
+ if (aging < 0 || aging > 0xff)
+ return -EINVAL;
+
+ _WriteRegBits(8, P8REG_QOSPORTAGINGEN0+(port/2), (port%2)*8, 8, aging);
+#ifdef COMBINED_PORT
+ if (port==9){
+ _WriteRegBits(8, P8REG_QOSPORTAGINGEN0+((port+1)/2), ((port+1)%2)*8, 8, aging);
+ }
+#endif
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+int getQOSAgingFunction(void *cdata, int len)
+{
+ int port;
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ port=((struct ByPortSetting *)cdata) ->port;
+ if (port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ ((struct ByPortSetting *)cdata) ->pdata=(u32)_ReadRegBits(8,P8REG_QOSPORTAGINGEN0+(port/2),(port%2)*8,8);
+
+ FUNC_MSG_OUT;
+ ip1811drv_dbg("cdata ->pdata=%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ return 0;
+}
+int setQOSAgingTime(void *cdata, int len)
+{
+ int aging;
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ aging = ((struct GeneralSetting *)cdata) ->gdata;
+ if (aging < 0 || aging > 0xff)
+ return -EINVAL;
+
+ _WriteRegBits(8, P8REG_QOSAGINGTIME, 0, 8, aging);
+ FUNC_MSG_OUT;
+ return 0;
+}
+int getQOSAgingTime(void *cdata, int len)
+{
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ ((struct GeneralSetting *)cdata) ->gdata = (u16)_ReadRegBits(8, P8REG_QOSAGINGTIME, 0, 8);
+
+ FUNC_MSG_OUT;
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ return 0;
+}
+int setQOSFastAging(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 8, P8REG_QOSAGINGTIME, 8);
+ FUNC_MSG_OUT;
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ return ret;
+}
+int getQOSFastAging(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 8, P8REG_QOSAGINGTIME, 8);
+ FUNC_MSG_OUT;
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ return ret;
+}
+int setCOSIGMP(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setPortmap(cdata, len, 0, P0REG_COSIGMPBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int getCOSIGMP(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getPortmap(cdata, len, 0, P0REG_COSIGMPBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int setCOSMACAddress(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setPortmap(cdata, len, 0, P0REG_COSMACBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int getCOSMACAddress(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getPortmap(cdata, len, 0, P0REG_COSMACBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int setCOSVID(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setPortmap(cdata, len, 0, P0REG_COSVIDBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int getCOSVID(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getPortmap(cdata, len, 0, P0REG_COSVIDBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int setCOSTCPUDPPort(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setPortmap(cdata, len, 0, P0REG_COSTCPUDPBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int getCOSTCPUDPPort(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getPortmap(cdata, len, 0, P0REG_COSTCPUDPBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int setCOSDSCP(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setPortmap(cdata, len, 0, P0REG_COSDSCPBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int getCOSDSCP(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getPortmap(cdata, len, 0, P0REG_COSDSCPBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int setCOS8021P(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setPortmap(cdata, len, 0, P0REG_COS8021PBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int getCOS8021P(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getPortmap(cdata, len, 0, P0REG_COS8021PBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int setCOSPhsicalPort(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setPortmap(cdata, len, 0, P0REG_COSPORTBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int getCOSPhsicalPort(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getPortmap(cdata, len, 0, P0REG_COSPORTBASEPRIEN);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int setCOSPortQueue(void *cdata, int len)
+{
+ int port;
+ u8 queue;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ port = ((struct ByPortSetting *)cdata) ->port;
+ queue = ((struct ByPortSetting *)cdata) ->pdata;
+
+ if ((port < 0) || (port >= MAX_PHY_NUM))
+ {
+ ip1811drv_err("Error: port=%d\n", port);
+ return -EINVAL;
+ }
+ if(queue>7)
+ {
+ ip1811drv_err("Error: queue=%d\n", queue);
+ return -EINVAL;
+ }
+
+ _WriteRegBits(0, P0REG_COSPORTBASEQUEUE0+(port/5), (port%5)*3, 3, queue);
+#ifdef COMBINED_PORT
+ if (port==9)
+ _WriteRegBits(0, P0REG_COSPORTBASEQUEUE0+((port+1)/5), ((port+1)%5)*3, 3, queue);
+#endif
+ FUNC_MSG_OUT;
+ return 0;
+}
+int getCOSPortQueue(void *cdata, int len)
+{
+ int port;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ port = ((struct ByPortSetting *)cdata) ->port;
+ if ((port < 0) || (port >= MAX_PHY_NUM))
+ {
+ ip1811drv_err("Error: port=%d\n", port);
+ return -EINVAL;
+ }
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ ((struct ByPortSetting *)cdata) ->pdata = (u16)_ReadRegBits(0, P0REG_COSPORTBASEQUEUE0+(port/5), (port%5)*3, 3);
+ ip1811drv_dbg("cdata ->pdata=0x%04X\n", ((struct ByPortSetting *)cdata) ->pdata);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+int setCOS8021PEdtion(void *cdata, int len)
+{
+ int gdata;
+ u16 regdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ gdata = ((struct GeneralSetting *)cdata) ->gdata;
+ if( gdata != OP_QOS_8021PEDTION_2005 && gdata != OP_QOS_8021PEDTION_2005_EX && gdata != OP_QOS_8021PEDTION_EARLY )
+ {
+ ip1811drv_err("Error: gdata=%X\n", gdata);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", gdata);
+ IP2Page(0);
+ regdata = Read_Reg(P0REG_COS8021PBASEPRIEN);
+ regdata &= (u16)~0x6000;
+ switch(gdata)
+ {
+ case OP_QOS_8021PEDTION_2005:
+ break;
+ case OP_QOS_8021PEDTION_2005_EX:
+ regdata |= 0x4000; break;
+ case OP_QOS_8021PEDTION_EARLY:
+ regdata |= 0x2000; break;
+ }
+ Write_Reg(P0REG_COS8021PBASEPRIEN,regdata);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+int getCOS8021PEdtion(void *cdata, int len)
+{
+ u16 u16dat;
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ u16dat =_ReadRegBits(0, P0REG_COS8021PBASEPRIEN, 13, 2);
+
+ if(u16dat&0x1)
+ { ((struct GeneralSetting *)cdata) ->gdata = OP_QOS_8021PEDTION_EARLY; }
+ else
+ {
+ if(u16dat&0x2)
+ { ((struct GeneralSetting *)cdata) ->gdata = OP_QOS_8021PEDTION_2005_EX; }
+ else
+ { ((struct GeneralSetting *)cdata) ->gdata = OP_QOS_8021PEDTION_2005; }
+ }
+ ip1811drv_dbg("cdata ->gdata=0x%08x\n", ((struct GeneralSetting *)cdata) ->gdata);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+int setCOSDSCPBaseDSCP(void *cdata, int len)
+{
+ u8 entryno,value,queue;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_dscp_setting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ entryno = ((struct qos_dscp_setting *)cdata) ->dscpentry;
+ value = ((struct qos_dscp_setting *)cdata) ->dscpvalue;
+ queue = ((struct qos_dscp_setting *)cdata) ->dscpqueue;
+
+ if(entryno<1 || entryno>8)
+ {
+ ip1811drv_err("Error: entryno=%d\n", entryno);
+ return -EINVAL;
+ }
+ if(value & ~0x3f)
+ {
+ ip1811drv_err("Error: value=%X\n", value);
+ return -EINVAL;
+ }
+ if(queue>7)
+ {
+ ip1811drv_err("Error: queue=%d\n", queue);
+ return -EINVAL;
+ }
+
+ entryno-=1;
+
+ _WriteRegBits(0, P0REG_COSDSCPVALUE0+(entryno/2), (entryno%2)*6, 6, value);
+ _WriteRegBits(0, P0REG_COSDSCPPRISETTING0+(entryno/5), (entryno%5)*3, 3, queue);
+ FUNC_MSG_OUT;
+ return 0;
+}
+int getCOSDSCPBaseDSCP(void *cdata, int len)
+{
+ u8 entryno;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_dscp_setting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ entryno = ((struct qos_dscp_setting *)cdata) ->dscpentry;
+ if(entryno>7)
+ {
+ ip1811drv_err("Error: entryno=%d\n", entryno);
+ return -EINVAL;
+ }
+ ((struct qos_dscp_setting *)cdata) ->dscpvalue = (u16)_ReadRegBits(0, P0REG_COSDSCPVALUE0+(entryno/2), (entryno%2)*5, 6);
+ ((struct qos_dscp_setting *)cdata) ->dscpqueue = (u16)_ReadRegBits(0, P0REG_COSDSCPPRISETTING0+(entryno/5), (entryno%5)*3, 3);
+ ip1811drv_dbg("cdata ->dscpvalue=0x%04X\n", ((struct qos_dscp_setting *)cdata) ->dscpvalue);
+ ip1811drv_dbg("cdata ->dscpqueue=0x%04X\n", ((struct qos_dscp_setting *)cdata) ->dscpqueue);
+ FUNC_MSG_OUT;
+
+ return 0;
+}
+int setCOSDSCPBaseNoMatchAction(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0, P0REG_COSDSCPPRISETTING1, 9);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int getCOSDSCPBaseNoMatchAction(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0, P0REG_COSDSCPPRISETTING1, 9);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int setQOSmodeGroupMember(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setPortmap(cdata, len, 8, P8REG_QOSGROUPSEL);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int getQOSmodeGroupMember(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getPortmap(cdata, len, 8, P8REG_QOSGROUPSEL);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int setQOSGroupBEn(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 8, P8REG_QOSMODESELGROUP2, 9);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int getQOSGroupBEn(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 8, P8REG_QOSMODESELGROUP2, 9);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int setQOSMode(void *cdata, int len)
+{
+ int gpnum,mode;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_modesettings) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ gpnum = ((struct qos_modesettings *)cdata) ->groupnum;
+ mode = ((struct qos_modesettings *)cdata) ->modesettings;
+ if(gpnum!=OP_QOS_GROUP1 && gpnum!=OP_QOS_GROUP2)
+ {
+ ip1811drv_err("Error: gpnum=%d\n", gpnum);
+ return -EINVAL;
+ }
+ if(mode<OP_QOS_MODE_FIFO || mode>OP_QOS_MODE_SP8)
+ {
+ ip1811drv_err("Error: mode=%d\n", mode);
+ return -EINVAL;
+ }
+ _WriteRegBits(8, (gpnum==OP_QOS_GROUP1)?P8REG_QOSMODESELGROUP1:P8REG_QOSMODESELGROUP2, 0, 3, mode);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+int getQOSMode(void *cdata, int len)
+{
+ int gpnum;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_modesettings) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ gpnum = ((struct qos_modesettings *)cdata) ->groupnum;
+ if(gpnum!=OP_QOS_GROUP1 && gpnum!=OP_QOS_GROUP2)
+ {
+ ip1811drv_err("Error: gpnum=%d\n", gpnum);
+ return -EINVAL;
+ }
+
+ ((struct qos_modesettings *)cdata) ->modesettings= (int)_ReadRegBits(8,(gpnum==OP_QOS_GROUP1)?P8REG_QOSMODESELGROUP1:P8REG_QOSMODESELGROUP2, 0, 3);
+
+ ip1811drv_dbg("cdata ->groupnum=0x%04X\n", ((struct qos_modesettings *)cdata) ->groupnum);
+ ip1811drv_dbg("cdata ->modesettings=0x%04X\n", ((struct qos_modesettings *)cdata) ->modesettings);
+ FUNC_MSG_OUT;
+
+ return 0;
+}
+int setQOSMethod(void *cdata, int len)
+{
+ int gpnum,mode;
+ u16 u16dat;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_modesettings) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ gpnum = ((struct qos_modesettings *)cdata) ->groupnum;
+ mode = ((struct qos_modesettings *)cdata) ->modesettings;
+ if(gpnum!=OP_QOS_GROUP1 && gpnum!=OP_QOS_GROUP2)
+ {
+ ip1811drv_err("Error: gpnum=%d\n", gpnum);
+ return -EINVAL;
+ }
+ if(mode<OP_QOS_METHOD_WRR || mode>OP_QOS_METHOD_TWRR)
+ {
+ ip1811drv_err("Error: mode=%d\n", mode);
+ return -EINVAL;
+ }
+ IP2Page(8);
+
+ u16dat = Read_Reg((gpnum==OP_QOS_GROUP1)?P8REG_QOSMODESELGROUP1:P8REG_QOSMODESELGROUP2);
+ u16dat &= 0xFF9F;
+ switch(mode)
+ {
+ case OP_QOS_METHOD_WRR:
+ break;
+ case OP_QOS_METHOD_BW:
+ u16dat |= ((u16)0x1<<5);
+ break;
+ case OP_QOS_METHOD_WFQ:
+ u16dat |= ((u16)0x2<<5);
+ break;
+ case OP_QOS_METHOD_TWRR:
+ u16dat |= ((u16)0x3<<5);
+ break;
+ }
+ Write_Reg((gpnum==OP_QOS_GROUP1)?P8REG_QOSMODESELGROUP1:P8REG_QOSMODESELGROUP2,u16dat);
+
+
+ if(mode==OP_QOS_METHOD_BW)
+ Write_Reg(P8REG_QOSMODESELGROUP1,Read_Reg(P8REG_QOSMODESELGROUP1)|0x8000);//stop & hold pkt
+ else
+ Write_Reg(P8REG_QOSMODESELGROUP1,Read_Reg(P8REG_QOSMODESELGROUP1)&0x7FFF);
+
+ ip1811drv_dbg("cdata ->groupnum=0x%04X\n", ((struct qos_modesettings *)cdata) ->groupnum);
+ ip1811drv_dbg("cdata ->modesettings=0x%04X\n", ((struct qos_modesettings *)cdata) ->modesettings);
+ FUNC_MSG_OUT;
+ return 0;
+}
+int getQOSMethod(void *cdata, int len)
+{
+ int gpnum;
+ u16 u16dat;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_modesettings) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ gpnum = ((struct qos_modesettings *)cdata) ->groupnum;
+ if(gpnum!=OP_QOS_GROUP1 && gpnum!=OP_QOS_GROUP2)
+ {
+ ip1811drv_err("Error: gpnum=%d\n", gpnum);
+ return -EINVAL;
+ }
+
+ u16dat = _ReadRegBits(8, (gpnum==OP_QOS_GROUP1)?P8REG_QOSMODESELGROUP1:P8REG_QOSMODESELGROUP2, 5, 3);
+
+ ((struct qos_modesettings *)cdata) ->modesettings = u16dat;
+
+ ip1811drv_dbg("cdata ->groupnum=0x%04X\n", ((struct qos_modesettings *)cdata) ->groupnum);
+ ip1811drv_dbg("cdata ->modesettings=0x%04X\n", ((struct qos_modesettings *)cdata) ->modesettings);
+ FUNC_MSG_OUT;
+ return 0;
+}
+int setQOSWeight(void *cdata, int len)
+{
+ int gpnum,mode,queue;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_modesettings) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ gpnum = ((struct qos_modesettings *)cdata) ->groupnum;
+ queue = ((struct qos_modesettings *)cdata) ->queuenum;
+ mode = ((struct qos_modesettings *)cdata) ->modesettings;
+ if(gpnum!=OP_QOS_GROUP1 && gpnum!=OP_QOS_GROUP2)
+ {
+ ip1811drv_err("Error: gpnum=%d\n", gpnum);
+ return -EINVAL;
+ }
+ if(queue<OP_QOS_NUM_Q0 || queue>OP_QOS_NUM_Q7)
+ {
+ ip1811drv_err("Error: queue=%d\n", queue);
+ return -EINVAL;
+ }
+ if(mode & ~(int)0xff)
+ {
+ ip1811drv_err("Error: mode=%d\n", mode);
+ return -EINVAL;
+ }
+
+ _WriteRegBits(8, (gpnum==OP_QOS_GROUP1)?(P8REG_QOSGP1_WEIGHT0+(queue/2)):(P8REG_QOSGP2_WEIGHT0+(queue/2)), (queue%2)*8, 8, mode);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+int getQOSWeight(void *cdata, int len)
+{
+ int gpnum,queue;
+ u16 u16dat;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_modesettings) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ gpnum = ((struct qos_modesettings *)cdata) ->groupnum;
+ queue = ((struct qos_modesettings *)cdata) ->queuenum;
+ if(gpnum!=OP_QOS_GROUP1 && gpnum!=OP_QOS_GROUP2)
+ {
+ ip1811drv_err("Error: gpnum=%d\n", gpnum);
+ return -EINVAL;
+ }
+ u16dat = _ReadRegBits(8,(gpnum==OP_QOS_GROUP1)?(P8REG_QOSGP1_WEIGHT0+(queue/2)):(P8REG_QOSGP2_WEIGHT0+(queue/2)), ((queue%2)*8), 8);
+
+ ((struct qos_modesettings *)cdata) ->modesettings=(int)u16dat;
+
+ ip1811drv_dbg("cdata ->groupnum=0x%04X\n", ((struct qos_modesettings *)cdata) ->groupnum);
+ ip1811drv_dbg("cdata ->queuenum=0x%04X\n", ((struct qos_modesettings *)cdata) ->queuenum);
+ ip1811drv_dbg("cdata ->modesettings=0x%04X\n", ((struct qos_modesettings *)cdata) ->modesettings);
+ FUNC_MSG_OUT;
+
+ return 0;
+}
+int setQOSMaxBandwidth(void *cdata, int len)
+{
+ int gpnum,mode,queue;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_modesettings) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ gpnum = ((struct qos_modesettings *)cdata) ->groupnum;
+ queue = ((struct qos_modesettings *)cdata) ->queuenum;
+ mode = ((struct qos_modesettings *)cdata) ->modesettings;
+ if(gpnum!=OP_QOS_GROUP1 && gpnum!=OP_QOS_GROUP2)
+ {
+ ip1811drv_err("Error: gpnum=%d\n", gpnum);
+ return -EINVAL;
+ }
+ if(queue<OP_QOS_NUM_Q0 || queue>OP_QOS_NUM_Q7)
+ {
+ ip1811drv_err("Error: queue=%d\n", queue);
+ return -EINVAL;
+ }
+ if(mode & ~(int)0xff)
+ {
+ ip1811drv_err("Error: mode=%d\n", mode);
+ return -EINVAL;
+ }
+
+ _WriteRegBits(8, (gpnum==OP_QOS_GROUP1)?(P8REG_QOSGP1_MAXBDWT0+(queue/2)):(P8REG_QOSGP2_MAXBDWT0+(queue/2)), (queue%2)*8, 8, mode);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int getQOSMaxBandwidth(void *cdata, int len)
+{
+ int gpnum,queue;
+ u16 u16dat;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_modesettings) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ gpnum = ((struct qos_modesettings *)cdata) ->groupnum;
+ queue = ((struct qos_modesettings *)cdata) ->queuenum;
+ if(gpnum!=OP_QOS_GROUP1 && gpnum!=OP_QOS_GROUP2)
+ {
+ ip1811drv_err("Error: gpnum=%d\n", gpnum);
+ return -EINVAL;
+ }
+ if(queue<OP_QOS_NUM_Q0 || queue>OP_QOS_NUM_Q7)
+ {
+ ip1811drv_err("Error: queue=%d\n", queue);
+ return -EINVAL;
+ }
+
+ u16dat = _ReadRegBits(8, (gpnum==OP_QOS_GROUP1)?(P8REG_QOSGP1_MAXBDWT0+(queue/2)):(P8REG_QOSGP2_MAXBDWT0+(queue/2)), ((queue%2)*8), 8);
+
+ ((struct qos_modesettings *)cdata) ->modesettings=(int)u16dat;
+
+ ip1811drv_dbg("cdata ->groupnum=0x%04X\n", ((struct qos_modesettings *)cdata) ->groupnum);
+ ip1811drv_dbg("cdata ->queuenum=0x%04X\n", ((struct qos_modesettings *)cdata) ->queuenum);
+ ip1811drv_dbg("cdata ->modesettings=0x%04X\n", ((struct qos_modesettings *)cdata) ->modesettings);
+ FUNC_MSG_OUT;
+
+ return 0;
+}
+int setQOSUnit(void *cdata, int len)
+{
+ int gpnum,mode;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_modesettings) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ gpnum = ((struct qos_modesettings *)cdata) ->groupnum;
+ mode = ((struct qos_modesettings *)cdata) ->modesettings;
+ if(gpnum!=OP_QOS_GROUP1 && gpnum!=OP_QOS_GROUP2)
+ {
+ ip1811drv_err("Error: gpnum=%d\n", gpnum);
+ return -EINVAL;
+ }
+ if(mode<OP_QOS_UNIT_64KBS || mode>OP_QOS_UNIT_4MBS)
+ {
+ ip1811drv_err("Error: mode=%d\n", mode);
+ return -EINVAL;
+ }
+ _WriteRegBits(8, (gpnum==OP_QOS_GROUP1)?(P8REG_QOSMODESELGROUP1):(P8REG_QOSMODESELGROUP2), 3, 2, mode);
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+int getQOSUnit(void *cdata, int len)
+{
+ int gpnum;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_modesettings) != len)
+ {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ gpnum = ((struct qos_modesettings *)cdata) ->groupnum;
+ if(gpnum!=OP_QOS_GROUP1 && gpnum!=OP_QOS_GROUP2)
+ {
+ ip1811drv_err("Error: gpnum=%d\n", gpnum);
+ return -EINVAL;
+ }
+
+ ((struct qos_modesettings *)cdata) ->modesettings= (int)_ReadRegBits(8,(gpnum==OP_QOS_GROUP1)?P8REG_QOSMODESELGROUP1:P8REG_QOSMODESELGROUP2, 3, 2);
+
+ ip1811drv_dbg("cdata ->groupnum=0x%04X\n", ((struct qos_modesettings *)cdata) ->groupnum);
+ ip1811drv_dbg("cdata ->modesettings=0x%04X\n", ((struct qos_modesettings *)cdata) ->modesettings);
+ FUNC_MSG_OUT;
+ return 0;
+}
+int setQOSRatioValue0Def(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 8, P8REG_QOSMODESELGROUP1, 15);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int getQOSRatioValue0Def(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 8, P8REG_QOSMODESELGROUP1, 15);
+ FUNC_MSG_OUT;
+ return ret;
+}
+int setQOSSBMDBM(void *cdata, int len)
+{
+ int port,mode;
+ u16 u16dat;
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ port = ((struct ByPortSetting *)cdata) ->port;
+ mode = ((struct ByPortSetting *)cdata) ->pdata;
+ if(port < 0 || port >= MAX_PHY_NUM)
+ return -EINVAL;
+ if(mode!=OP_QOS_QBASE_DBM && mode!=OP_QOS_QBASE_SBM)
+ {
+ ip1811drv_err("Error: mode=%d\n", mode);
+ return -EINVAL;
+ }
+ ip1811drv_dbg(" port=%d\n", port);
+ ip1811drv_dbg(" mode=%d\n", mode);
+
+ IP2Page(8);
+
+ // set all queue(per port) to same mode
+ u16dat=Read_Reg(P8REG_QOS_SBMDBMSEL0+(port/2));
+ u16dat&=((port%2)?0x00FF:0xFF00);
+ if(mode==OP_QOS_QBASE_SBM)
+ { u16dat|=((port%2)?0xFF00:0x00FF); }
+ Write_Reg(P8REG_QOS_SBMDBMSEL0+(port/2),u16dat);
+#ifdef COMBINED_PORT
+ if (port==9){
+ u16dat=Read_Reg(P8REG_QOS_SBMDBMSEL0+((port+1)/2));
+ u16dat&=(((port+1)%2)?0x00FF:0xFF00);
+ if(mode==OP_QOS_QBASE_SBM)
+ { u16dat|=(((port+1)%2)?0xFF00:0x00FF); }
+ Write_Reg(P8REG_QOS_SBMDBMSEL0+((port+1)/2),u16dat);
+ }
+#endif
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+int getQOSSBMDBM(void *cdata, int len)
+{
+ int port;
+ u16 u16dat;
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ port = ((struct ByPortSetting *)cdata) ->port;
+ if(port<0 || port>=MAX_PHY_NUM)
+ return -EINVAL;
+
+ IP2Page(8);
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ u16dat=Read_Reg(P8REG_QOS_SBMDBMSEL0+(port/2));
+ u16dat>>=((port%2)*8);
+ if(u16dat&0xff)
+ { ((struct ByPortSetting *)cdata) ->pdata=OP_QOS_QBASE_SBM; }
+ else
+ { ((struct ByPortSetting *)cdata) ->pdata=OP_QOS_QBASE_DBM; }
+
+ ip1811drv_dbg("cdata ->port=0x%d\n", ((struct ByPortSetting *)cdata) ->port);
+ ip1811drv_dbg("cdata ->pdata=0x%d\n", ((struct ByPortSetting *)cdata) ->pdata);
+ FUNC_MSG_OUT;
+
+ return 0;
+}
+int setQOSDBMEn(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _setPortmap(cdata, len, 8, P8REG_QOSQUEUEDBMEN);
+ FUNC_MSG_IN;
+ return ret;
+}
+int getQOSDBMEn(void *cdata, int len)
+{
+ int ret;
+ FUNC_MSG_IN;
+ ret = _getPortmap(cdata, len, 8, P8REG_QOSQUEUEDBMEN);
+ FUNC_MSG_IN;
+ return ret;
+}
+int setQOSRemap(void *cdata, int len)
+{
+ int port;
+ u8 queue,remap;
+ u16 u16dat;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_remap) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ port = ((struct qos_remap *)cdata) ->port;
+ queue = ((struct qos_remap *)cdata) ->queue;
+ remap = ((struct qos_remap *)cdata) ->remap;
+
+ if(port<0 || port>=MAX_PHY_NUM)
+ return -EINVAL;
+ if(queue>OP_QOS_REMAP_TX_Q7)
+ {
+ ip1811drv_err("Error: queue=%d\n", queue);
+ return -EINVAL;
+ }
+ if(remap>7)
+ {
+ ip1811drv_err("Error: remap=%d\n", remap);
+ return -EINVAL;
+ }
+ ip1811drv_dbg("cdata ->port=0x%d\n", ((struct qos_remap *)cdata) ->port);
+ ip1811drv_dbg("cdata ->queue=0x%d\n", ((struct qos_remap *)cdata) ->queue);
+ ip1811drv_dbg("cdata ->remap=0x%d\n", ((struct qos_remap *)cdata) ->remap);
+
+ if(queue<=OP_QOS_REMAP_RX_Q7)//RX
+ {
+ if ((queue/5) == 0)
+ {
+ IP2Page(6);
+ u16dat = Read_Reg(P6REG_QOS_REMAP_RX0+(port*2)+1);
+ }
+ _WriteRegBits(6, P6REG_QOS_REMAP_RX0+(port*2)+(queue/5), (queue%5)*3, 3, remap);
+ if ((queue/5) == 0)
+ {
+ IP2Page(6);
+ Write_Reg(P6REG_QOS_REMAP_RX0+(port*2)+1, u16dat);
+ }
+#ifdef COMBINED_PORT
+ if (port==9)
+ {
+ if ((queue/5) == 0)
+ {
+ IP2Page(6);
+ u16dat = Read_Reg(P6REG_QOS_REMAP_RX0+((port+1)*2)+1);
+ }
+ _WriteRegBits(6, P6REG_QOS_REMAP_RX0+((port+1)*2)+(queue/5), (queue%5)*3, 3, remap);
+ if ((queue/5) == 0)
+ {
+ IP2Page(6);
+ Write_Reg(P6REG_QOS_REMAP_RX0+((port+1)*2)+1, u16dat);
+ }
+ }
+#endif
+ }
+ else//TX
+ {
+ queue-=8;
+ if (port == 0)
+ {
+ _WriteRegBits(8, P8REG_QOS_REMAP_TX0+(port*2)+(queue/5), (queue%5)*3, 3, remap);
+ }
+ else if (port == 1)
+ {
+ if (queue / 5)
+ _WriteRegBits(8, P8REG_QOS_REMAP_TX0+(port*2)+(queue/5)+1, (queue%5)*3, 3, remap);
+ else
+ _WriteRegBits(8, P8REG_QOS_REMAP_TX0+(port*2)+(queue/5), (queue%5)*3, 3, remap);
+ }
+ else
+ {
+ _WriteRegBits(8, P8REG_QOS_REMAP_TX0+(port*2)+(queue/5)+1, (queue%5)*3, 3, remap);
+#ifdef COMBINED_PORT
+ if (port==9)
+ _WriteRegBits(8, P8REG_QOS_REMAP_TX0+((port+1)*2)+(queue/5)+1, (queue%5)*3, 3, remap);
+#endif
+ }
+ }
+ FUNC_MSG_OUT;
+ return 0;
+}
+int getQOSRemap(void *cdata, int len)
+{
+ int port;
+ u8 queue;
+ u16 u16dat;
+ FUNC_MSG_IN;
+ if (sizeof(struct qos_remap) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+ port = ((struct qos_remap *)cdata) ->port;
+ queue = ((struct qos_remap *)cdata) ->queue;
+ if(port<0 || port>=MAX_PHY_NUM)
+ return -EINVAL;
+ if(queue>OP_QOS_REMAP_TX_Q7)
+ {
+ ip1811drv_err("Error: queue=%d\n", queue);
+ return -EINVAL;
+ }
+ ip1811drv_dbg("cdata ->port=0x%d\n", ((struct qos_remap *)cdata) ->port);
+ ip1811drv_dbg("cdata ->queue=0x%d\n", ((struct qos_remap *)cdata) ->queue);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ if(queue<=OP_QOS_REMAP_RX_Q7)//RX
+ {
+ IP2Page(6);
+ u16dat = Read_Reg(P6REG_QOS_REMAP_RX0+(port*2)+(queue/5));
+ }
+ else//TX
+ {
+ queue-=8;
+ IP2Page(8);
+ if (port == 0)
+ {
+ u16dat = Read_Reg(P8REG_QOS_REMAP_TX0+(port*2)+(queue/5));
+ }
+ else if (port == 1)
+ {
+ if (queue / 5)
+ u16dat = Read_Reg(P8REG_QOS_REMAP_TX0+(port*2)+(queue/5)+1);
+ else
+ u16dat = Read_Reg(P8REG_QOS_REMAP_TX0+(port*2)+(queue/5));
+ }
+ else
+ {
+ u16dat = Read_Reg(P8REG_QOS_REMAP_TX0+(port*2)+(queue/5)+1);
+ }
+ }
+ ((struct qos_remap *)cdata) ->remap = (u8)((u16dat>>((queue%5)*3))&0x7);
+
+ ip1811drv_dbg("cdata ->remap=0x%d\n", ((struct qos_remap *)cdata) ->remap);
+ FUNC_MSG_OUT;
+ return 0;
+}
+//------------ QOS functions:ip1811 end--------------------------
+
+//------------ ACL functions:common ----------------------------
+struct acl_man *m_acl; // acl golbal manage variable
+int acl_write_table_0010(int block, int index, int link, struct acl_rule *r);
+int acl_write_table_0100(int block, int index, int link, struct acl_rule *r);
+int acl_write_table_0101(int block, int index, int link, struct acl_rule *r);
+int acl_write_table_0110(int block, int index, int link, struct acl_rule *r);
+int acl_write_table_0111(int block, int index, int link, struct acl_rule *r);
+int acl_write_table_1x00(int block, int index, int link, struct acl_rule *r);
+int acl_write_table_1x01(int block, int index, int link, struct acl_rule *r);
+int acl_write_table_1x10(int block, int index, int link, struct acl_rule *r);
+int acl_write_table_1x11(int block, int index, int link, struct acl_rule *r);
+int (*acl_write_table_rule[])(int block, int index, int link, struct acl_rule *r) = {
+ NULL,
+ acl_write_table_0010,
+ NULL,
+ acl_write_table_0100,
+ acl_write_table_0101,
+ acl_write_table_0110,
+ acl_write_table_0111,
+ acl_write_table_1x00,
+ acl_write_table_1x01,
+ acl_write_table_1x10,
+ acl_write_table_1x11
+};
+int acl_write_table_drop(int block, int index, int is_link, struct acl_rule *r);
+int acl_write_table_a1(int block, int index, int is_link, struct acl_rule *r);
+int acl_write_table_a2(int block, int index, int is_link, struct acl_rule *r);
+int acl_write_table_a3(int block, int index, int is_link, struct acl_rule *r);
+int (*acl_write_table_act[])(int block, int index, int is_link, struct acl_rule *r) = {
+ acl_write_table_drop,
+ acl_write_table_a1,
+ acl_write_table_a2,
+ acl_write_table_a3
+};
+
+int set_rule_index_remap(void);
+
+void acl_init(void)
+{
+ int i;
+ ip1811drv_dbg("<DBG_DR_ACL> acl_init()\n");
+
+ m_acl = kmalloc(sizeof(struct acl_man), GFP_KERNEL);
+ if(m_acl == NULL)
+ {
+ ip1811drv_err("Error: acl_init() acl_man malloc failed.\n");
+ return;
+ }
+
+ INIT_LIST_HEAD(&m_acl ->rule_list);
+ m_acl ->num_used_rules = 0;
+ m_acl ->num_used_entries = 0;
+ for(i=0; i<4; i++)
+ {
+ m_acl ->used_entry_mask[i] = 0;
+ }
+}
+
+int acl_find_index(int num, int *block, int *index, int find_idx_blockn, int find_idx_rvs)
+{
+ int i=0, j=0;
+ unsigned char m = 0;
+ unsigned long t = 0;
+
+ for(i=0; i<num; i++) {
+ m |= BIT(i);
+ }
+
+ for(i=0; i<4; i++) {
+ t = (unsigned long)m_acl ->used_entry_mask[(find_idx_blockn+i)%4];
+ if(find_idx_rvs) { // find index in reverse
+ for(j=15; j>=0; j--) {
+ if((16-j) < num) // empty entry is not enough, find next block
+ break;
+ if(!((t>>j) & m)) {
+ *block = (i+find_idx_blockn)%4;
+ *index = j;
+ return 0;
+ }
+ }
+ } else {
+ for(j=0; j<16; j++) {
+ if((16-j) < num) // empty entry is not enough, find next block
+ break;
+ if(!((t>>j) & m)) {
+ *block = (i+find_idx_blockn)%4;
+ *index = j;
+ return 0;
+ }
+ }
+ }
+ }
+
+ return -ENOMEM;
+}
+
+int acl_clean_table_rule(int block, int index)
+{
+ IP2Page(1);
+
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, 0);
+
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ return 0;
+}
+
+int acl_clean_table_act(int block, int index)
+{
+ IP2Page(1);
+
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, 0);
+
+ // act
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC100|index|(block<<5));
+ return 0;
+}
+
+int acl_clean_table(int block, int index)
+{
+ acl_clean_table_rule(block, index);
+ acl_clean_table_act(block, index);
+ return 0;
+}
+
+int acl_write_table_0010(int block, int index, int link, struct acl_rule *r)
+{
+ u16 tmp=0;
+
+ IP2Page(1);
+
+ /* Set user define location D3 and D4 */
+ if(r->location1)
+ Write_Reg(P1REG_ACL_PATTEM_LOCATION_D3, r->location1);
+ if(r->location2)
+ Write_Reg(P1REG_ACL_PATTEM_LOCATION_D4, r->location2);
+
+ /* E1 ~ E8 */
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, r->usr0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, r->mask0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, r->usr1);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, r->mask1);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, r->usr2);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, r->mask2);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, r->usr3);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, r->mask3);
+
+ //E9
+ if(r->rule_valid & ACL_RULE_VALID_INGRESS_PORT) {
+ tmp |= r->ingress_port+1;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, tmp);
+
+ //EA
+ tmp=ACL_SELECT_MODE_0010<<6;
+ if(r->rule_rvs & ACL_RULE_RVS_INGRESS_PORT) {
+ tmp |= 0x8;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ return 0;
+}
+
+
+int acl_write_table_0100(int block, int index, int link, struct acl_rule *r)
+{
+ u16 tmp = 0;
+
+ IP2Page(1);
+ //E1 & E2
+ if(r->rule_valid & ACL_RULE_VALID_SIP)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, r->sip4_addr&0xFFFF);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, (r->sip4_addr>>16)&0xFFFF);
+ tmp |= ((u16)(r->sip_mask&0xF)<<7);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, 0);
+ tmp |= (0xF<<7); // any sip
+ }
+ //E3 & E4
+ if(r->rule_valid & ACL_RULE_VALID_DP_R)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, r->dp_lo);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, r->dp_hi);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ tmp |= BIT(5);
+ }
+ //E5 & E6
+ if(r->rule_valid & ACL_RULE_VALID_SP_R)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, r->sp_lo);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, r->sp_hi);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ tmp |= BIT(6);
+ }
+ //E7
+ if(r->rule_valid & ACL_RULE_VALID_VLAN)
+ {
+ if(r->rule_valid & ACL_RULE_VALID_COS)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan | (r->cos<<12)));
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan|0x8000));
+ }
+ }
+ else
+ {
+ tmp |= (0x3<<11);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0x8000);
+ }
+ //E8
+ tmp |= (0x3<<13);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, 0x8000);
+ //E9
+ if(r->rule_valid & ACL_RULE_VALID_INGRESS_PORT)
+ {
+ tmp |= r->ingress_port+1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_SIP) {
+ tmp |= 0x8000;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, tmp);
+ //EA
+ tmp = ((ACL_SELECT_MODE_0100<<6) | (link<<4));
+ if(r->rule_rvs & ACL_RULE_RVS_DP_R) {
+ tmp |= 0x1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_SP_R) {
+ tmp |= 0x2;
+ }
+ if((r->rule_rvs&ACL_RULE_RVS_VLAN) && (r->rule_rvs&ACL_RULE_RVS_COS)) {
+ tmp |= 0x4;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_INGRESS_PORT) {
+ tmp |= 0x8;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ return 0;
+}
+
+int acl_write_table_0101(int block, int index, int link, struct acl_rule *r)
+{
+ u16 tmp = 0;
+
+ IP2Page(1);
+ //E1 & E2
+ if(r->rule_valid & ACL_RULE_VALID_DIP)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, r->dip4_addr&0xFFFF);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, (r->dip4_addr>>16)&0xFFFF);
+ tmp |= ((u16)(r->dip_mask&0xF)<<7);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, 0);
+ tmp |= (0xF<<7); // any dip
+ }
+ //E3 & E4
+ if(r->rule_valid & ACL_RULE_VALID_DP_R)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, r->dp_lo);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, r->dp_hi);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ tmp |= BIT(5);
+ }
+ //E5 & E6
+ if(r->rule_valid & ACL_RULE_VALID_SP_R)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, r->sp_lo);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, r->sp_hi);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ tmp |= BIT(6);
+ }
+ //E7
+ if(r->rule_valid & ACL_RULE_VALID_VLAN)
+ {
+ if(r->rule_valid & ACL_RULE_VALID_COS)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan | (r->cos<<12)));
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan|0x8000));
+ }
+ }
+ else
+ {
+ tmp |= (0x3<<11);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0x8000);
+ }
+ //E8
+ tmp |= (0x3<<13);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, 0x8000);
+ //E9
+ if(r->rule_valid & ACL_RULE_VALID_INGRESS_PORT)
+ {
+ tmp |= r->ingress_port+1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_DIP) {
+ tmp |= 0x8000;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, tmp);
+ //EA
+ tmp = ((ACL_SELECT_MODE_0101<<6) | (link<<4));
+ if(r->rule_rvs & ACL_RULE_RVS_DP_R) {
+ tmp |= 0x1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_SP_R) {
+ tmp |= 0x2;
+ }
+ if((r->rule_rvs&ACL_RULE_RVS_VLAN) && (r->rule_rvs&ACL_RULE_RVS_COS)) {
+ tmp |= 0x4;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_INGRESS_PORT) {
+ tmp |= 0x8;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ return 0;
+}
+
+int acl_write_table_0110(int block, int index, int link, struct acl_rule *r)
+{
+ u16 tmp = 0;
+
+ IP2Page(1);
+ //E1 ~ E8
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, r->sip6_addr16[7]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, r->sip6_addr16[6]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, r->sip6_addr16[5]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, r->sip6_addr16[4]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, r->sip6_addr16[3]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, r->sip6_addr16[2]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, r->sip6_addr16[1]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, r->sip6_addr16[0]);
+ //E9
+ tmp |= ((u16)(r->sip_mask&0x3FF)<<5);
+ if(r->rule_valid & ACL_RULE_VALID_INGRESS_PORT)
+ {
+ tmp |= r->ingress_port+1;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, tmp);
+ //EA
+ tmp = ((ACL_SELECT_MODE_0110<<6) | (link<<4));
+ if(r->rule_rvs & ACL_RULE_RVS_INGRESS_PORT) {
+ tmp |= 0x8;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ return 0;
+}
+
+int acl_write_table_0111(int block, int index, int link, struct acl_rule *r)
+{
+ u16 tmp = 0;
+
+ IP2Page(1);
+ //E1 ~ E8
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, r->dip6_addr16[7]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, r->dip6_addr16[6]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, r->dip6_addr16[5]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, r->dip6_addr16[4]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, r->dip6_addr16[3]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, r->dip6_addr16[2]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, r->dip6_addr16[1]);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, r->dip6_addr16[0]);
+ //E9
+ tmp |= ((u16)(r->dip_mask&0x3FF)<<5);
+ if(r->rule_valid & ACL_RULE_VALID_INGRESS_PORT)
+ {
+ tmp |= r->ingress_port+1;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, tmp);
+ //EA
+ tmp = ((ACL_SELECT_MODE_0111<<6) | (link<<4));
+ if(r->rule_rvs & ACL_RULE_RVS_INGRESS_PORT) {
+ tmp |= 0x8;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ return 0;
+}
+
+int acl_write_table_1x00(int block, int index, int link, struct acl_rule *r)
+{
+ u16 tmp=0, tmp2=0;
+
+ IP2Page(1);
+ //E1 & E2
+ if(r->rule_valid & ACL_RULE_VALID_SIP)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, r->sip4_addr&0xFFFF);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, (r->sip4_addr>>16)&0xFFFF);
+ tmp |= ((u16)(r->sip_mask&0xF)<<7);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, 0);
+ tmp |= (0xF<<7); // any sip
+ }
+ //E3
+ if(r->rule_valid & ACL_RULE_VALID_ETH_TYPE)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, r->eth_type);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, 0);
+ tmp |= BIT(5);
+ }
+ //E4 ~ E6
+ if(r->rule_valid & ACL_RULE_VALID_SMAC)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, ((u16)(r->smac[4]&0xFF)<<8) | ((u16)(r->smac[5]&0xFF)));
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, ((u16)(r->smac[2]&0xFF)<<8) | ((u16)(r->smac[3]&0xFF)));
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, ((u16)(r->smac[0]&0xFF)<<8) | ((u16)(r->smac[1]&0xFF)));
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ tmp |= (0x1<<6); // any smac
+ }
+ //E7
+ if(r->rule_valid & ACL_RULE_VALID_VLAN)
+ {
+ if(r->rule_valid & ACL_RULE_VALID_COS)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan | (r->cos<<12)));
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan|0x8000));
+ }
+ }
+ else
+ {
+ tmp |= (0x3<<11);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0x8000);
+ }
+ //E8
+ // ip_proto
+ if(r->rule_valid & ACL_RULE_VALID_IP_PROT)
+ {
+ tmp2 |= ((u16)r->ip_prot&0xFF);
+ }
+ else
+ {
+ tmp |= BIT(13); // any ip_prot
+ }
+ // dscp
+ if(r->rule_valid & ACL_RULE_VALID_DSCP)
+ {
+ tmp2 |= ((u16)(r->r_dscp&0x3F)<<10);
+ }
+ else
+ {
+ tmp |= BIT(14);
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, tmp2);
+ //E9
+ if(r->rule_valid & ACL_RULE_VALID_INGRESS_PORT)
+ {
+ tmp |= r->ingress_port+1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_SIP) {
+ tmp |= 0x8000;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, tmp);
+ //EA
+ tmp = ((ACL_SELECT_MODE_1x00<<6) | (link<<4));
+ if(r->rule_rvs & ACL_RULE_RVS_ETH_TYPE) {
+ tmp |= 0x1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_SMAC) {
+ tmp |= 0x2;
+ }
+ if((r->rule_rvs&ACL_RULE_RVS_VLAN) && (r->rule_rvs&ACL_RULE_RVS_COS)) {
+ tmp |= 0x4;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_INGRESS_PORT) {
+ tmp |= 0x8;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ return 0;
+}
+
+int acl_write_table_1x01(int block, int index, int link, struct acl_rule *r)
+{
+ u16 tmp=0, tmp2=0;
+
+ IP2Page(1);
+ //E1 & E2
+ if(r->rule_valid & ACL_RULE_VALID_DIP)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, r->dip4_addr&0xFFFF);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, (r->dip4_addr>>16)&0xFFFF);
+ tmp |= ((u16)(r->dip_mask&0xF)<<7);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, 0);
+ tmp |= (0xF<<7); // any dip
+ }
+ //E3
+ if(r->rule_valid & ACL_RULE_VALID_ETH_TYPE)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, r->eth_type);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, 0);
+ tmp |= BIT(5);
+ }
+ //E4 ~ E6
+ if(r->rule_valid & ACL_RULE_VALID_SMAC)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, ((u16)(r->smac[4]&0xFF)<<8) | ((u16)(r->smac[5]&0xFF)));
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, ((u16)(r->smac[2]&0xFF)<<8) | ((u16)(r->smac[3]&0xFF)));
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, ((u16)(r->smac[0]&0xFF)<<8) | ((u16)(r->smac[1]&0xFF)));
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ tmp |= (0x1<<6); // any smac
+ }
+ //E7
+ if(r->rule_valid & ACL_RULE_VALID_VLAN)
+ {
+ if(r->rule_valid & ACL_RULE_VALID_COS)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan | (r->cos<<12)));
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan|0x8000));
+ }
+ }
+ else
+ {
+ tmp |= (0x3<<11);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0x8000);
+ }
+ //E8
+ // ip_proto
+ if(r->rule_valid & ACL_RULE_VALID_IP_PROT)
+ {
+ tmp2 |= ((u16)r->ip_prot&0xFF);
+ }
+ else
+ {
+ tmp |= BIT(13); // any ip_prot
+ }
+ // dscp
+ if(r->rule_valid & ACL_RULE_VALID_DSCP)
+ {
+ tmp2 |= ((u16)(r->r_dscp&0x3F)<<10);
+ }
+ else
+ {
+ tmp |= BIT(14);
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, tmp2);
+ //E9
+ if(r->rule_valid & ACL_RULE_VALID_INGRESS_PORT)
+ {
+ tmp |= r->ingress_port+1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_DIP) {
+ tmp |= 0x8000;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, tmp);
+ //EA
+ tmp = ((ACL_SELECT_MODE_1x01<<6) | (link<<4));
+ if(r->rule_rvs & ACL_RULE_RVS_ETH_TYPE) {
+ tmp |= 0x1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_SMAC) {
+ tmp |= 0x2;
+ }
+ if((r->rule_rvs&ACL_RULE_RVS_VLAN) && (r->rule_rvs&ACL_RULE_RVS_COS)) {
+ tmp |= 0x4;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_INGRESS_PORT) {
+ tmp |= 0x8;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ return 0;
+}
+
+int acl_write_table_1x10(int block, int index, int link, struct acl_rule *r)
+{
+ u16 tmp=0, tmp2=0;
+
+ IP2Page(1);
+ //E1 & E2
+ if(r->rule_valid & ACL_RULE_VALID_SIP)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, r->sip4_addr&0xFFFF);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, (r->sip4_addr>>16)&0xFFFF);
+ tmp |= ((u16)(r->sip_mask&0xF)<<7);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, 0);
+ tmp |= (0xF<<7); // any sip
+ }
+ //E3
+ if(r->rule_valid & ACL_RULE_VALID_ETH_TYPE)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, r->eth_type);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, 0);
+ tmp |= BIT(5);
+ }
+ //E4 ~ E6
+ if(r->rule_valid & ACL_RULE_VALID_DMAC)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, ((u16)(r->dmac[4]&0xFF)<<8) | ((u16)(r->dmac[5]&0xFF)));
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, ((u16)(r->dmac[2]&0xFF)<<8) | ((u16)(r->dmac[3]&0xFF)));
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, ((u16)(r->dmac[0]&0xFF)<<8) | ((u16)(r->dmac[1]&0xFF)));
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ tmp |= (0x1<<6); // any dmac
+ }
+ //E7
+ if(r->rule_valid & ACL_RULE_VALID_VLAN)
+ {
+ if(r->rule_valid & ACL_RULE_VALID_COS)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan | (r->cos<<12)));
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan|0x8000));
+ }
+ }
+ else
+ {
+ tmp |= (0x3<<11);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0x8000);
+ }
+ //E8
+ // ip_proto
+ if(r->rule_valid & ACL_RULE_VALID_IP_PROT)
+ {
+ tmp2 |= ((u16)r->ip_prot&0xFF);
+ }
+ else
+ {
+ tmp |= BIT(13); // any ip_prot
+ }
+ // dscp
+ if(r->rule_valid & ACL_RULE_VALID_DSCP)
+ {
+ tmp2 |= ((u16)(r->r_dscp&0x3F)<<10);
+ }
+ else
+ {
+ tmp |= BIT(14);
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, tmp2);
+ //E9
+ if(r->rule_valid & ACL_RULE_VALID_INGRESS_PORT)
+ {
+ tmp |= r->ingress_port+1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_SIP) {
+ tmp |= 0x8000;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, tmp);
+ //EA
+ tmp = ((ACL_SELECT_MODE_1x10<<6) | (link<<4));
+ if(r->rule_rvs & ACL_RULE_RVS_ETH_TYPE) {
+ tmp |= 0x1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_DMAC) {
+ tmp |= 0x2;
+ }
+ if((r->rule_rvs&ACL_RULE_RVS_VLAN) && (r->rule_rvs&ACL_RULE_RVS_COS)) {
+ tmp |= 0x4;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_INGRESS_PORT) {
+ tmp |= 0x8;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ return 0;
+}
+
+int acl_write_table_1x11(int block, int index, int link, struct acl_rule *r)
+{
+ u16 tmp=0, tmp2=0;
+
+ IP2Page(1);
+ //E1 & E2
+ if(r->rule_valid & ACL_RULE_VALID_DIP)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, r->dip4_addr&0xFFFF);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, (r->dip4_addr>>16)&0xFFFF);
+ tmp |= ((u16)(r->dip_mask&0xF)<<7);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, 0);
+ tmp |= (0xF<<7); // any dip
+ }
+ //E3
+ if(r->rule_valid & ACL_RULE_VALID_ETH_TYPE)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, r->eth_type);
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, 0);
+ tmp |= BIT(5);
+ }
+ //E4 ~ E6
+ if(r->rule_valid & ACL_RULE_VALID_DMAC)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, ((u16)(r->dmac[4]&0xFF)<<8) | ((u16)(r->dmac[5]&0xFF)));
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, ((u16)(r->dmac[2]&0xFF)<<8) | ((u16)(r->dmac[3]&0xFF)));
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, ((u16)(r->dmac[0]&0xFF)<<8) | ((u16)(r->dmac[1]&0xFF)));
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ tmp |= (0x1<<6); // any dmac
+ }
+ //E7
+ if(r->rule_valid & ACL_RULE_VALID_VLAN)
+ {
+ if(r->rule_valid & ACL_RULE_VALID_COS)
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan | (r->cos<<12)));
+ }
+ else
+ {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, (r->vlan|0x8000));
+ }
+ }
+ else
+ {
+ tmp |= (0x3<<11);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0x8000);
+ }
+ //E8
+ // ip_proto
+ if(r->rule_valid & ACL_RULE_VALID_IP_PROT)
+ {
+ tmp2 |= ((u16)r->ip_prot&0xFF);
+ }
+ else
+ {
+ tmp |= BIT(13); // any ip_prot
+ }
+ // dscp
+ if(r->rule_valid & ACL_RULE_VALID_DSCP)
+ {
+ tmp2 |= ((u16)(r->r_dscp&0x3F)<<10);
+ }
+ else
+ {
+ tmp |= BIT(14);
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, tmp2);
+ //E9
+ if(r->rule_valid & ACL_RULE_VALID_INGRESS_PORT)
+ {
+ tmp |= r->ingress_port+1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_DIP) {
+ tmp |= 0x8000;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, tmp);
+ //EA
+ tmp = ((ACL_SELECT_MODE_1x11<<6) | (link<<4));
+ if(r->rule_rvs & ACL_RULE_RVS_ETH_TYPE) {
+ tmp |= 0x1;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_DMAC) {
+ tmp |= 0x2;
+ }
+ if((r->rule_rvs&ACL_RULE_RVS_VLAN) && (r->rule_rvs&ACL_RULE_RVS_COS)) {
+ tmp |= 0x4;
+ }
+ if(r->rule_rvs & ACL_RULE_RVS_INGRESS_PORT) {
+ tmp |= 0x8;
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ return 0;
+}
+
+int acl_write_table_drop(int block, int index, int is_link, struct acl_rule *r)
+{
+ u16 tmp = 0;
+
+ IP2Page(1);
+ //E1
+ tmp = 0x1F;
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, tmp);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, 0);
+ if(is_link) {
+ tmp = ((ACL_SELECT_MODE_0001<<6) | (ACL_LINK_TYPE_11<<4));
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ } else {
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, 0);
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC100|index|(block<<5));
+ }
+
+ return 0;
+}
+
+int acl_write_table_a1(int block, int index, int is_link, struct acl_rule *r)
+{
+ u16 tmp = 0;
+ u16 tmp2 = 0;
+
+ IP2Page(1);
+ //E1
+ if(r->act_valid & ACL_ACT_VALID_REDIR)
+ {
+ tmp |= ((r->redir)&0x1F);
+ }
+ if(r->act_valid & ACL_ACT_VALID_CTAG)
+ {
+ tmp |= ((r->ctag&0x7F)<<5);
+ }
+ if(r->act_valid & ACL_ACT_VALID_STAG)
+ {
+ tmp |= ((r->stag&0xF)<<12);
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, tmp);
+
+ //E2
+ tmp = 0;
+ if(r->act_valid & ACL_ACT_VALID_STAG)
+ {
+ tmp |= ((r->stag&0x70)>>4);
+ }
+ if(r->act_valid & ACL_ACT_VALID_PRI)
+ {
+ tmp |= ((BIT(3)|(r->pri&0x7))<<3);
+ }
+ if(r->act_valid & ACL_ACT_VALID_DSCP)
+ {
+ tmp |= ((BIT(3)|(r->a_dscp&0x7))<<7);
+ }
+ if(r->act_valid & ACL_ACT_VALID_BW)
+ {
+ if(is_link)
+ tmp2 |= ((BIT(2)|(r->bw&0x3))<<4);
+ else
+ tmp |= ((BIT(2)|(r->bw&0x3))<<11);
+ }
+ if(r->act_valid & ACL_ACT_VALID_SNIFFER)
+ {
+ if(is_link)
+ tmp |= BIT(15);
+ else
+ tmp |= BIT(14);
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, tmp);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, tmp2);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, 0);
+ if(is_link) {
+ tmp = ((ACL_SELECT_MODE_0001<<6) | (ACL_LINK_TYPE_11<<4));
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ } else {
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, 0);
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC100|index|(block<<5));
+ }
+
+ return 0;
+}
+
+int acl_write_table_a2(int block, int index, int is_link, struct acl_rule *r)
+{
+ u16 tmp = 0;
+ u16 tmp2 = 0;
+
+ IP2Page(1);
+ //E1
+ if(r->act_valid & ACL_ACT_VALID_REDIR)
+ {
+ tmp |= ((r->redir)&0x1F);
+ }
+ if(r->act_valid & ACL_ACT_VALID_CTAG)
+ {
+ tmp |= ((r->ctag&0x7F)<<5);
+ }
+ if(r->act_valid & ACL_ACT_VALID_STAG)
+ {
+ tmp |= ((r->stag&0xF)<<12);
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, tmp);
+
+ //E2
+ tmp = 0;
+ if(r->act_valid & ACL_ACT_VALID_STAG)
+ {
+ tmp |= ((r->stag&0x70)>>4);
+ }
+ if(r->act_valid & ACL_ACT_VALID_PRI)
+ {
+ tmp |= ((BIT(3)|(r->pri&0x7))<<3);
+ }
+ if(r->act_valid & ACL_ACT_VALID_STORM)
+ {
+ if(is_link)
+ tmp2 |= (BIT(r->storm-1)<<1);
+ else
+ tmp |= (BIT(r->storm-1)<<7);
+ }
+ if(r->act_valid & ACL_ACT_VALID_CPU)
+ {
+ if(is_link)
+ tmp2 |= BIT(0);
+ else
+ tmp |= BIT(10);
+ }
+ if(r->act_valid & ACL_ACT_VALID_MIB_COUNTER)
+ {
+ tmp |= ((BIT(1)|((r->mib_counter-1)&0x1))<<11);
+ }
+ if(r->act_valid & ACL_ACT_VALID_PTP)
+ {
+ tmp |= BIT(13);
+ }
+ if(r->act_valid & ACL_ACT_VALID_SFLOW)
+ {
+ tmp |= BIT(14);
+ }
+ tmp |= BIT(15);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, tmp);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, tmp2);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, 0);
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, 0);
+ if(is_link) {
+ tmp = ((ACL_SELECT_MODE_0001<<6) | (ACL_LINK_TYPE_11<<4));
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ } else {
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, 0);
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC100|index|(block<<5));
+ }
+
+ return 0;
+}
+
+int acl_write_table_a3(int block, int index, int is_link, struct acl_rule *r)
+{
+ u16 tmp = 0;
+
+ IP2Page(1);
+ //E1
+ if(r->act_valid & ACL_ACT_VALID_REDIR)
+ {
+ tmp |= ((r->redir)&0x1F);
+ }
+ if(r->act_valid & ACL_ACT_VALID_CTAG)
+ {
+ tmp |= ((r->ctag&0x7F)<<5);
+ }
+ if(r->act_valid & ACL_ACT_VALID_STAG)
+ {
+ tmp |= ((r->stag&0xF)<<12);
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1, tmp);
+
+ //E2
+ tmp = 0;
+ if(r->act_valid & ACL_ACT_VALID_STAG)
+ {
+ tmp |= ((r->stag&0x70)>>4);
+ }
+ if(r->act_valid & ACL_ACT_VALID_PRI)
+ {
+ tmp |= ((BIT(3)|(r->pri&0x7))<<3);
+ }
+ if(r->act_valid & ACL_ACT_VALID_DSCP)
+ {
+ tmp |= ((BIT(3)|(r->a_dscp&0x7))<<7);
+ }
+ if(r->act_valid & ACL_ACT_VALID_MIB_COUNTER)
+ {
+ tmp |= ((BIT(1)|(r->mib_counter&0x1))<<11);
+ }
+ if(r->act_valid & ACL_ACT_VALID_PTP)
+ {
+ tmp |= BIT(13);
+ }
+ if(r->act_valid & ACL_ACT_VALID_SFLOW)
+ {
+ tmp |= BIT(14);
+ }
+ if(r->act_valid & ACL_ACT_VALID_SNIFFER)
+ {
+ tmp |= BIT(15);
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E2, tmp);
+
+ //E3
+ tmp = 0;
+ if(r->act_valid & ACL_ACT_VALID_CPU)
+ {
+ tmp |= BIT(0);
+ }
+ if(r->act_valid & ACL_ACT_VALID_STORM)
+ {
+ tmp |= (BIT(r->storm-1)<<1);
+ }
+ if(r->act_valid & ACL_ACT_VALID_BW)
+ {
+ tmp |= ((BIT(2)|(r->bw&0x3))<<4);
+ }
+ Write_Reg(P1REG_ACL_TABLE_DATA_E3, tmp);
+
+ //E4
+ Write_Reg(P1REG_ACL_TABLE_DATA_E4, 0);
+ //E5
+ Write_Reg(P1REG_ACL_TABLE_DATA_E5, 0);
+ //E6
+ Write_Reg(P1REG_ACL_TABLE_DATA_E6, 0);
+ //E7
+ Write_Reg(P1REG_ACL_TABLE_DATA_E7, 0);
+ //E8
+ Write_Reg(P1REG_ACL_TABLE_DATA_E8, 0);
+ //E9
+ Write_Reg(P1REG_ACL_TABLE_DATA_E9, 0);
+ //EA
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, 0);
+
+ tmp = ((ACL_SELECT_MODE_0001<<6) | (ACL_LINK_TYPE_11<<4));
+ Write_Reg(P1REG_ACL_TABLE_DATA_EA, tmp);
+
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|index|(block<<5));
+ return 0;
+}
+
+int switchdSetAclRule(struct AclRuleSetting *ars)
+{
+ struct acl_rule *r = &ars ->rule;
+ unsigned long rule_v = r->rule_valid;
+ int s_mode = 0, s_num = 0, flag = 0, i = 0, block = 0, index = 0, link = 0;
+ struct acl_man_rule *mr;
+ int ret = 0;
+ int find_idx_blockn;
+ int find_idx_rvs;
+
+ ip1811drv_dbg("<DBG_DR_ACL> switchdSetAclRule(): ars ->rule_index = %i\n", ars ->rule_index);
+ // check index
+ list_for_each_entry(mr, &m_acl ->rule_list, rule_entry) {
+ if(mr->rule_index == ars ->rule_index) {
+ if((mr->func_used) & (ars->func_used)) {
+ for(i = mr->start_index; i<(mr->start_index+mr->num_entries); i++) {
+ block = mr->start_block;
+ index = i&0xF;
+ acl_clean_table(block, index);
+ m_acl ->used_entry_mask[block] &= ~BIT(i&0xF);
+ m_acl ->num_used_entries--;
+ }
+ m_acl ->num_used_rules--;
+ flag = 1;
+ break;
+ }
+ }
+ }
+
+ if(!flag) {
+ mr = NULL;
+ }
+
+ if(rule_v==0) {
+ ars->rule_index_res=0;
+ ars->reserved=0;
+ m_acl->num_used_rules++;
+ if(mr!=NULL) {
+ list_del(&mr->rule_entry);
+ kfree(mr);
+ }
+ return 0;
+ }
+
+ // selection logic
+ if((rule_v & ACL_RULE_VALID_SIP6) || (rule_v & ACL_RULE_VALID_DIP6)) {
+ if(rule_v & ACL_RULE_VALID_SIP6) {
+ // 0110
+ s_mode |= ACL_SELECT_MODE_BIT_0110;
+ s_num += 1;
+ }
+
+ if(rule_v & ACL_RULE_VALID_DIP6) {
+ // 0111
+ s_mode |= ACL_SELECT_MODE_BIT_0111;
+ s_num += 1;
+ }
+
+ if((rule_v & ACL_RULE_VALID_SP_R) || (rule_v & ACL_RULE_VALID_DP_R)) {
+ // 0101
+ s_mode |= ACL_SELECT_MODE_BIT_0101;
+ s_num += 1;
+ }
+ goto out_select_logic;
+ } else if(rule_v & ACL_RULE_VALID_USERDEF_OFFSET) {
+ //0010
+ s_mode=ACL_SELECT_MODE_BIT_0010;
+ s_num=1;
+ goto out_select_logic;
+ }
+
+ if((rule_v & ACL_RULE_VALID_SP_R) || (rule_v & ACL_RULE_VALID_DP_R)) {
+ if(rule_v & ACL_RULE_VALID_DIP) {
+ // 0101
+ s_mode |= ACL_SELECT_MODE_BIT_0101;
+ s_num += 1;
+
+ if( (rule_v & ACL_RULE_VALID_SIP)
+ || (rule_v & ACL_RULE_VALID_DMAC)
+ || (rule_v & ACL_RULE_VALID_SMAC)
+ || (rule_v & ACL_RULE_VALID_ETH_TYPE)
+ || (rule_v & ACL_RULE_VALID_DSCP)
+ || (rule_v & ACL_RULE_VALID_IP_PROT)
+ ) {
+ if(rule_v & ACL_RULE_VALID_DMAC) {
+ // 1x10
+ s_mode |= ACL_SELECT_MODE_BIT_1x10;
+ s_num += 1;
+
+ if(rule_v & ACL_RULE_VALID_SMAC) {
+ // 1x00
+ s_mode |= ACL_SELECT_MODE_BIT_1x00;
+ s_num += 1;
+ }
+ } else {
+ // 1x00
+ s_mode |= ACL_SELECT_MODE_BIT_1x00;
+ s_num += 1;
+ }
+ }
+ } else {
+ // 0100
+ s_mode |= ACL_SELECT_MODE_BIT_0100;
+ s_num += 1;
+ if( (rule_v & ACL_RULE_VALID_DMAC)
+ || (rule_v & ACL_RULE_VALID_SMAC)
+ || (rule_v & ACL_RULE_VALID_ETH_TYPE)
+ || (rule_v & ACL_RULE_VALID_DSCP)
+ || (rule_v & ACL_RULE_VALID_IP_PROT)
+ ) {
+ if(rule_v & ACL_RULE_VALID_DMAC) {
+ // 1x10
+ s_mode |= ACL_SELECT_MODE_BIT_1x10;
+ s_num += 1;
+
+ if(rule_v & ACL_RULE_VALID_SMAC) {
+ // 1x00
+ s_mode |= ACL_SELECT_MODE_BIT_1x00;
+ s_num += 1;
+ }
+ } else {
+ // 1x00
+ s_mode |= ACL_SELECT_MODE_BIT_1x00;
+ s_num += 1;
+ }
+ }
+ }
+ } else {
+ if(rule_v & ACL_RULE_VALID_DIP) {
+ if(rule_v & ACL_RULE_VALID_DMAC) {
+ // 1x11
+ s_mode |= ACL_SELECT_MODE_BIT_1x11;
+ s_num += 1;
+
+ if((rule_v & ACL_RULE_VALID_SMAC) || (rule_v & ACL_RULE_VALID_SIP)) {
+ // 1x00
+ s_mode |= ACL_SELECT_MODE_BIT_1x00;
+ s_num += 1;
+ }
+ } else {
+ // 1x01
+ s_mode |= ACL_SELECT_MODE_BIT_1x01;
+ s_num += 1;
+ if(rule_v & ACL_RULE_VALID_SIP) {
+ // 1x00
+ s_mode |= ACL_SELECT_MODE_BIT_1x00;
+ s_num += 1;
+ }
+ }
+ } else {
+ if(rule_v & ACL_RULE_VALID_DMAC) {
+ // 1x10
+ s_mode |= ACL_SELECT_MODE_BIT_1x10;
+ s_num += 1;
+ if(rule_v & ACL_RULE_VALID_SMAC) {
+ // 1x00
+ s_mode |= ACL_SELECT_MODE_BIT_1x00;
+ s_num += 1;
+ }
+ } else {
+ // 1x00
+ s_mode |= ACL_SELECT_MODE_BIT_1x00;
+ s_num += 1;
+ }
+ }
+ }
+
+out_select_logic:
+ ip1811drv_dbg("<DBG_SWD_ACL> s_mode = %02x, s_num = %i\n", s_mode, s_num);
+
+ if((r->act_type==ACL_ACT_TYPE_3) || (s_num>=2)) {
+ s_num++;
+ }
+
+ find_idx_blockn = ars->find_index_blockn;
+ find_idx_rvs = ars->find_index_rvs;
+
+ ret = acl_find_index(s_num, &block, &index, find_idx_blockn, find_idx_rvs);
+
+ if(ret < 0) { // if acl_find_index return <0, remap acl rule index and find index again
+ set_rule_index_remap();
+ ret = acl_find_index(s_num, &block, &index, find_idx_blockn, find_idx_rvs);
+ }
+
+ if(ret < 0) {
+ if(mr != NULL) {
+ list_del(&mr->rule_entry);
+ kfree(mr);
+ }
+ ars ->rule_index_res = -2;
+ ars ->reserved = s_num;
+ return 0;
+ //return -ENOMEM;
+ }
+ ip1811drv_dbg("<DBG_SWD_ACL> block, index = %i, %i\n", block, index);
+
+ ars->find_index_blockn = block;
+ if(mr == NULL) {
+ mr = kmalloc(sizeof(struct acl_man_rule), GFP_KERNEL);
+ if(mr == NULL) {
+ ip1811drv_err("Error: switchdSetAclRule() acl_man_rule malloc failed.\n");
+ return -ENOMEM;
+ }
+ list_add_tail(&mr->rule_entry, &m_acl ->rule_list);
+ }
+
+ mr->start_block = block;
+ mr->start_index = index;
+ mr->num_entries = s_num;
+ mr->rule_index = ars ->rule_index;
+ mr->func_used = ars ->func_used;
+ if(s_num == 1) {
+ link = ACL_LINK_TYPE_00;
+ // write rule table
+ for(i=2; i<12; i++) {
+ if(s_mode & BIT(i)) {
+ acl_write_table_rule[i-1](block, index, link, r);
+ s_num--;
+ break;
+ }
+ }
+ // write action table
+ acl_write_table_act[r->act_type](block, index, s_num, r);
+ } else {
+ link = ACL_LINK_TYPE_01;
+ // write rule table
+ for(i=2; i<12; i++) {
+ if(s_mode & BIT(i)) {
+ acl_write_table_rule[i-1](block, index, link, r);
+ index++;
+ s_num--;
+ if(s_num == 1) {
+ break;
+ } else {
+ link = ACL_LINK_TYPE_10;
+ }
+ }
+ }
+ // write action table
+ //acl_write_table_act[r->act_type](block, index, s_num, r);
+ acl_write_table_act[3](block, index, s_num, r);
+ }
+
+ for(i=0; i<mr->num_entries; i++) {
+ m_acl ->used_entry_mask[mr->start_block] |= BIT((i+mr->start_index)&0xF);
+ m_acl ->num_used_entries++;
+ }
+ m_acl ->num_used_rules++;
+ ars ->rule_index_res = 0;
+ ars ->reserved = mr->num_entries;
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetAclRule);
+
+int setAclRule(void *cdata, int len)
+{
+ int ret;
+ struct AclRuleSetting *ars = (struct AclRuleSetting *)cdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct AclRuleSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ ret = switchdSetAclRule(ars);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getAclRule(void *cdata, int len)
+{
+ return 0;
+}
+
+int switchdAclCleanTable(int rule_index, int func_used)
+{
+ int i = 0;
+ struct acl_man_rule *mr, *nmr;
+ int block, index;
+
+ if ((rule_index<1 || rule_index>64) && (rule_index!=128)) {
+ ip1811drv_err("Error: rule index=%d\n", rule_index);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("<DBG_DR_ACL> aclCleanTable()\n");
+
+ if(rule_index == 128) {
+ ip1811drv_dbg("<DBG_DR_ACL> aclCleanTable() 111111\n");
+ if(list_empty(&m_acl ->rule_list)) {
+ ip1811drv_dbg("<DBG_DR_ACL> aclCleanTable() 222222\n");
+ return 0;
+ }
+
+ list_for_each_entry_safe(mr, nmr, &m_acl ->rule_list, rule_entry)
+ {
+ for(i=0; i<mr->num_entries; i++) {
+ block = mr->start_block;
+ index = mr->start_index;
+ acl_clean_table(block, index+i);
+ m_acl ->used_entry_mask[block] &= ~BIT((index+i)&0xF);
+ m_acl ->num_used_entries--;
+ }
+ m_acl ->num_used_rules--;
+ list_del(&mr->rule_entry);
+ kfree(mr);
+ }
+
+ INIT_LIST_HEAD(&m_acl ->rule_list);
+
+ if((m_acl ->num_used_rules!=0) || (m_acl ->num_used_entries!=0))
+ ip1811drv_err("<DBG_SWD_ACL> aclCleanTable something error!\n");
+ } else {
+ list_for_each_entry(mr, &m_acl ->rule_list, rule_entry)
+ {
+ if(mr->rule_index == rule_index) {
+ if((mr->func_used) & func_used) {
+ for(i=0; i<mr->num_entries; i++) {
+ block = mr->start_block;
+ index = mr->start_index;
+ acl_clean_table(block, index+i);
+ m_acl ->used_entry_mask[block] &= ~BIT((index+i)&0xF);
+ m_acl ->num_used_entries--;
+ }
+ m_acl ->num_used_rules--;
+ list_del(&mr->rule_entry);
+ kfree(mr);
+ break;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdAclCleanTable);
+
+int aclCleanTable(void *cdata, int len)
+{
+ int ret, rule_index, func_used;
+ struct AclTableCleanSetting *atcs = (struct AclTableCleanSetting *)cdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct AclTableCleanSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ rule_index = atcs ->rule_idx;
+ func_used = atcs ->func_used;
+ ret = switchdAclCleanTable(rule_index, func_used);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetAclFunctionEn(int enable)
+{
+ if ((enable!=OP_FUNC_ENABLE) && (enable!=OP_FUNC_DISABLE)) {
+ ip1811drv_err("Error: value=%d\n", enable);
+ return -EINVAL;
+ }
+ _WriteRegBits(1, P1REG_MISCCFG, 0, 1, enable);
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetAclFunctionEn);
+
+int setAclFunctionEn(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *gs = (struct GeneralSetting *)cdata;
+ int func_en;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ func_en = gs ->gdata;
+ ret = switchdSetAclFunctionEn(func_en);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetAclFunctionEn(int *gdata_p)
+{
+ *gdata_p = _ReadRegBits(1, P1REG_MISCCFG, 0, 1);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetAclFunctionEn);
+
+int getAclFunctionEn(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *gs = (struct GeneralSetting *)cdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ ret = switchdGetAclFunctionEn(&(gs ->gdata));
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetAclEtherAfterTag(int is_after_tag)
+{
+ if ((is_after_tag!=OP_FUNC_ENABLE) && (is_after_tag!=OP_FUNC_DISABLE)) {
+ ip1811drv_err("Error: value=%d\n", is_after_tag);
+ return -EINVAL;
+ }
+ _WriteRegBits(1, P1REG_MISCCFG, 1, 1, is_after_tag);
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetAclEtherAfterTag);
+
+int setAclEtherAfterTag(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *gs = (struct GeneralSetting *)cdata;
+ int loca_v;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ loca_v = gs ->gdata;
+ ret = switchdSetAclEtherAfterTag(loca_v);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetAclEtherAfterTag(int *gdata_p)
+{
+ *gdata_p = _ReadRegBits(1, P1REG_MISCCFG, 1, 1);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetAclEtherAfterTag);
+
+int getAclEtherAfterTag(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *gs = (struct GeneralSetting *)cdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ ret = switchdGetAclEtherAfterTag(&(gs ->gdata));
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetAclUsedRules(int *gdata_p)
+{
+ *gdata_p = m_acl ->num_used_rules;
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetAclUsedRules);
+
+int getAclUsedRules(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *gs = (struct GeneralSetting *)cdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ ret = switchdGetAclUsedRules(&(gs ->gdata));
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetAclUsedEntries(int *gdata_p)
+{
+ *gdata_p = m_acl ->num_used_entries;
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetAclUsedEntries);
+
+int getAclUsedEntries(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *gs = (struct GeneralSetting *)cdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ ret = switchdGetAclUsedEntries(&(gs ->gdata));
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetAclUsedEntryMask(unsigned short *gmask_p)
+{
+ memcpy(gmask_p, m_acl->used_entry_mask, 4*sizeof(unsigned short));
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetAclUsedEntryMask);
+
+int getAclUsedEntryMask(void *cdata, int len)
+{
+ int ret;
+ struct AclEntryMaskGetting *aemg = (struct AclEntryMaskGetting *)cdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct AclEntryMaskGetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ ret = switchdGetAclUsedEntryMask(aemg ->mask);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetAclBW(int index, int in_rate)
+{
+ u16 rate = 0;
+
+ if (index<0 || index>3) {
+ ip1811drv_err("Error: index=%d\n", index);
+ return -EINVAL;
+ }
+
+ if (in_rate<0 || in_rate>2540) {
+ ip1811drv_err("Error: rate=%d\n", in_rate);
+ return -EINVAL;
+ }
+
+ if(in_rate > 163) {
+ rate |= BIT(7);
+ rate |= (in_rate*100/2000);
+ if(in_rate*100%2000)
+ rate++;
+ } else {
+ rate = (in_rate*100/128);
+ if(in_rate*100%128)
+ rate++;
+ }
+
+ ip1811drv_dbg("index=%d\n", index);
+ ip1811drv_dbg("value=0x%x\n", rate);
+ // set 4 block
+ _WriteRegBits(1, P1REG_ACL_BW_01+(index/2)+0, 8*(index%2), 8, rate);
+ _WriteRegBits(1, P1REG_ACL_BW_01+(index/2)+2, 8*(index%2), 8, rate);
+ _WriteRegBits(1, P1REG_ACL_BW_01+(index/2)+4, 8*(index%2), 8, rate);
+ _WriteRegBits(1, P1REG_ACL_BW_01+(index/2)+6, 8*(index%2), 8, rate);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetAclBW);
+
+int setAclBW(void *cdata, int len)
+{
+ int ret;
+ struct AclGeneralSetting *ags = (struct AclGeneralSetting *)cdata;
+ int bw_index;
+ int bw_v;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct AclGeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ bw_index = ags ->index;
+ bw_v = ags ->data;
+ ret = switchdSetAclBW(bw_index, bw_v);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetAclBW(int index, int *gdata_p)
+{
+ u16 tmp = 0;
+ u32 c_rate;
+
+ if (index<0 || index>3) {
+ ip1811drv_err("Error: index=%d\n", index);
+ return -EINVAL;
+ }
+
+ tmp = _ReadRegBits(1, P1REG_ACL_BW_01+(index/2), (8*(index%2)), 8);
+
+ if(tmp&BIT(7)) {
+ c_rate = (tmp&(0x7F))*2000;
+ } else {
+ c_rate = (tmp&(0x7F))*128;
+ }
+
+ *gdata_p = c_rate/100;
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetAclBW);
+
+int getAclBW(void *cdata, int len)
+{
+ int ret;
+ struct AclGeneralSetting *ags = (struct AclGeneralSetting *)cdata;
+ int bw_index;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct AclGeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ bw_index = ags ->index;
+ ret = switchdGetAclBW(bw_index, &(ags ->data));
+ ip1811drv_dbg("cdata ->data=%d\n", ags ->data);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetAclDscp(int index, int value)
+{
+ if (index<0 || index>7) {
+ ip1811drv_err("Error: index=%d\n", index);
+ return -EINVAL;
+ }
+
+ if (value & (~0x3F)) {
+ ip1811drv_err("Error: value=%x\n", value);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("index=%d\n", index);
+ ip1811drv_dbg("value=0x%x\n", value);
+
+ _WriteRegBits(7, P7REG_DSCP_REMARKING_01+(index/2), 8*(index%2), 8, value);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetAclDscp);
+
+int setAclDscp(void *cdata, int len)
+{
+ int ret;
+ struct AclGeneralSetting *ags = (struct AclGeneralSetting *)cdata;
+ int dscp_index;
+ int dscp_v;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct AclGeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ dscp_index = ags ->index;
+ dscp_v = ags ->data;
+ ret = switchdSetAclDscp(dscp_index, dscp_v);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetAclDscp(int index, int *gdata_p)
+{
+ if (index<0 || index>7) {
+ ip1811drv_err("Error: index=%d\n", index);
+ return -EINVAL;
+ }
+ *gdata_p = _ReadRegBits(7, P7REG_DSCP_REMARKING_01+(index/2), (8*(index%2)), 8);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetAclDscp);
+
+int getAclDscp(void *cdata, int len)
+{
+ int ret;
+ struct AclGeneralSetting *ags = (struct AclGeneralSetting *)cdata;
+ int dscp_index;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct AclGeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ dscp_index = ags ->index;
+ ret = switchdGetAclDscp(dscp_index, &(ags ->data));
+ ip1811drv_dbg("cdata ->data=%d\n", ags ->data);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetAclVidRemark(int index, int value)
+{
+
+ if (index<0 || index>15) {
+ ip1811drv_err("Error: index=%d\n", index);
+ return -EINVAL;
+ }
+
+ if (value & (~0x7FFF)) {
+ ip1811drv_err("Error: value=%x\n", value);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("index=%d\n", index);
+ ip1811drv_dbg("value=0x%x\n", value);
+
+ _WriteRegBits(2, P2REG_ACL_VID_REMARK_00+index, 0, 15, value);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetAclVidRemark);
+
+int setAclVidRemark(void *cdata, int len)
+{
+ int ret;
+ struct AclGeneralSetting *ags = (struct AclGeneralSetting *)cdata;
+ int vid_index;
+ int vid_v;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct AclGeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ vid_index = ags ->index;
+ vid_v = ags ->data;
+ ret = switchdSetAclVidRemark(vid_index, vid_v);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetAclVidRemark(int index, int *gdata_p)
+{
+
+ if (index<0 || index>15) {
+ ip1811drv_err("Error: index=%d\n", index);
+ return -EINVAL;
+ }
+
+ *gdata_p = _ReadRegBits(2, P2REG_ACL_VID_REMARK_00+index, 0, 15);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetAclVidRemark);
+
+int getAclVidRemark(void *cdata, int len)
+{
+ int ret;
+ struct AclGeneralSetting *ags = (struct AclGeneralSetting *)cdata;
+ int vid_index;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct AclGeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ vid_index = ags ->index;
+ ret = switchdGetAclVidRemark(vid_index, &(ags ->data));
+ ip1811drv_dbg("cdata ->data=%d\n", ags ->data);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int acl_write_table_move(int from_block, int from_index, int to_block, int to_index)
+{
+ int i;
+ u16 u16array[10];
+ u16 u16dat;
+
+ IP2Page(1);
+
+ // rule
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0x8000|from_index|((from_block&0x3)<<5));
+ for(i=0; i<10; i++) {
+ u16dat = Read_Reg(P1REG_ACL_TABLE_DATA_E1+i);
+ u16array[i] = u16dat;
+ }
+ acl_clean_table_rule(from_block, from_index);
+ for(i=0; i<10; i++) {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1+i, u16array[i]);
+ }
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC000|to_index|((to_block&0x3)<<5));
+
+ // act
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0x8100|from_index|((from_block&0x3)<<5));
+ for(i=0; i<10; i++) {
+ u16dat = Read_Reg(P1REG_ACL_TABLE_DATA_E1+i);
+ u16array[i] = u16dat;
+ }
+ acl_clean_table_act(from_block, from_index);
+ for(i=0; i<10; i++) {
+ Write_Reg(P1REG_ACL_TABLE_DATA_E1+i, u16array[i]);
+ }
+ Write_Reg(P1REG_ACL_TABLE_ACCESS, 0xC100|to_index|((to_block&0x3)<<5));
+
+ m_acl ->used_entry_mask[to_block] |= BIT(to_index);
+ m_acl ->used_entry_mask[from_block] &= ~BIT(from_index);
+
+ return 0;
+}
+
+int set_rule_index_remap(void)
+{
+ int i, j;
+ int index_move_to;
+ int block_move_to;
+ int index_move_from;
+ int block_move_from;
+ int index_move_range;
+ struct acl_man_rule *mr;
+
+ ip1811drv_dbg("<DBG_DR_ACL> set_rule_index_remap()\n");
+
+ for(i=0; i<64; i++) {
+ if(m_acl ->used_entry_mask[i>>4] & BIT(i%16)) { // entry i rule exist
+ } else { // entry i rule not exist
+ int no_entry = 1;
+ block_move_to = (i>>4)&0x3;
+ index_move_to = i&0xF;
+ block_move_from = 3;
+ index_move_from = 16;
+ index_move_range= 0;
+ // scan closest entry
+ list_for_each_entry(mr, &m_acl ->rule_list, rule_entry) {
+ if(mr->func_used != ACL_RULE_FUNC_USED_SNOOP) {
+ if((16*mr->start_block+mr->start_index)>i) {
+ if(((16*mr->start_block+mr->start_index)<(block_move_from*16+index_move_from)) && (mr->num_entries<=(16-index_move_to))) {
+ block_move_from = mr->start_block;
+ index_move_from = mr->start_index;
+ index_move_range = mr->num_entries;
+ no_entry = 0;
+ }
+ }
+ }
+ }
+
+ if(no_entry)
+ continue;
+
+ // move exist entry to empty rule index
+ for(j=0; j<index_move_range; j++) {
+ acl_write_table_move(block_move_from, index_move_from+j, block_move_to, index_move_to+j);
+ }
+
+ // modify entry info
+ list_for_each_entry(mr, &m_acl ->rule_list, rule_entry) {
+ if((mr->start_block==block_move_from) && (mr->start_index==index_move_from)) {
+ mr->start_block = block_move_to;
+ mr->start_index = index_move_to;
+ }
+ }
+ // assign i to be link entry end
+ i += (index_move_range-1);
+ }
+ ip1811drv_dbg("<DBG_DR_ACL> set_rule_index_remap(): entry from block(%d)/index(%d) to block(%d)/index(%d)\n", block_move_from, index_move_from, block_move_to, index_move_to);
+
+ }
+
+ return 0;
+}
+
+int switchdSetAclStormPeriod(int period)
+{
+ if (period& (~0x3)) {
+ ip1811drv_err("Error: period=0x%x\n", period);
+ return -EINVAL;
+ }
+ ip1811drv_dbg("clear period=0x%x\n", period);
+ _WriteRegBits(1, P1REG_MISCCFG, 4, 2, period);
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetAclStormPeriod);
+
+int setAclStormPeriod(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *gs = (struct GeneralSetting *)cdata;
+ int period;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ period = gs ->gdata;
+ ret = switchdSetAclStormPeriod(period);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetAclStormPeriod(int *gdata_p)
+{
+ *gdata_p = _ReadRegBits(1, P1REG_MISCCFG, 4, 2);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetAclStormPeriod);
+
+int getAclStormPeriod(void *cdata, int len)
+{
+ int ret;
+ struct GeneralSetting *gs = (struct GeneralSetting *)cdata;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ ret = switchdGetAclStormPeriod(&(gs ->gdata));
+ ip1811drv_dbg("cdata ->gdata=%d\n", gs ->gdata);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetAclStorm(int index, int value)
+{
+ if (index<0 || index>2) {
+ ip1811drv_err("Error: index=%d\n", index);
+ return -EINVAL;
+ }
+
+ if (value & (~0xFFFF)) {
+ ip1811drv_err("Error: value=%x\n", value);
+ return -EINVAL;
+ }
+ _WriteRegBits(1, P1REG_MISCCFG, 13, 1, 1);
+ ip1811drv_dbg("index=%d\n", index);
+ ip1811drv_dbg("value=0x%x\n", value);
+ _WriteRegBits(1, P1REG_ACL_STORM_0+index, 0, 16, value);
+ _WriteRegBits(1, P1REG_MISCCFG, 13, 1, 0);
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetAclStorm);
+
+int setAclStorm(void *cdata, int len)
+{
+ int ret;
+ struct AclGeneralSetting *ags = (struct AclGeneralSetting *)cdata;
+ int storm_index;
+ int storm_v;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct AclGeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ storm_index = ags ->index;
+ storm_v = ags ->data;
+ ret = switchdSetAclStorm(storm_index, storm_v);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdGetAclStorm(int index, int *gdata_p)
+{
+ if (index<0 || index>2) {
+ ip1811drv_err("Error: index=%d\n", index);
+ return -EINVAL;
+ }
+ _WriteRegBits(1, P1REG_MISCCFG, 13, 1, 1);
+ *gdata_p = _ReadRegBits(1, P1REG_ACL_STORM_0+index, 0, 16);
+ _WriteRegBits(1, P1REG_MISCCFG, 13, 1, 0);
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetAclStorm);
+
+int getAclStorm(void *cdata, int len)
+{
+ int ret;
+ struct AclGeneralSetting *ags = (struct AclGeneralSetting *)cdata;
+ int storm_index;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct AclGeneralSetting) != len) {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ storm_index = ags ->index;
+ ret = switchdGetAclStorm(storm_index, &(ags ->data));
+ ip1811drv_dbg("cdata ->data=%d\n", ags ->data);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+//------------ ACL functions:common end -----------------------
+
+//------------------------------------------------
+//common_bandwidth
+int switchdSetBandwidthIngressRate(int port, unsigned long rate)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ {
+ ip1811drv_err("Error: port=%d\n", port);
+ return -EINVAL;
+ }
+ if (rate > MAX_GIGA_SPEED)
+ {
+ ip1811drv_err("Error: pdata=0x%08X\n", (u16)rate);
+ return -EINVAL;
+ }
+
+ IP2Page(0);
+ if (rate == 0 || rate == MAX_GIGA_SPEED || (port < MAX_PHY_TP_NUM && rate >= MAX_TP_SPEED))
+ { Write_Reg(P0REG_INGRESS_RATE_CTRL0+port,0); }
+ else if(rate > 0 && rate < MAX_GIGA_SPEED)
+ {
+ if(port < MAX_PHY_TP_NUM && rate >= (MAX_TP_SPEED/RATE_SCALE_UNIT)*RATE_SCALE_UNIT)
+ { Write_Reg(P0REG_INGRESS_RATE_CTRL0+port,0); }
+ else if(rate >= (MAX_GIGA_SPEED/RATE_SCALE_UNIT)*RATE_SCALE_UNIT)
+ {
+ Write_Reg(P0REG_INGRESS_RATE_CTRL0+port,0);
+#ifdef COMBINED_PORT
+ if (port==9)
+ Write_Reg(P0REG_INGRESS_RATE_CTRL0+port+1,0);
+#endif
+ }
+ else
+ {
+ if(rate%RATE_SCALE_UNIT)
+ {
+ Write_Reg(P0REG_INGRESS_RATE_CTRL0+port,rate/RATE_SCALE_UNIT+1);
+#ifdef COMBINED_PORT
+ if (port==9)
+ Write_Reg(P0REG_INGRESS_RATE_CTRL0+port+1,rate/RATE_SCALE_UNIT+1);
+#endif
+ }
+ else
+ {
+ Write_Reg(P0REG_INGRESS_RATE_CTRL0+port,rate/RATE_SCALE_UNIT);
+#ifdef COMBINED_PORT
+ if (port==9)
+ Write_Reg(P0REG_INGRESS_RATE_CTRL0+port+1,rate/RATE_SCALE_UNIT);
+#endif
+ }
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetBandwidthIngressRate);
+int setBandwidthIngressRate(void *cdata, int len)
+{
+ int port; //1-28
+ unsigned long rate;
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting32) != len)
+ {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ port = ((struct ByPortSetting32 *)cdata)->port;
+ rate = ((struct ByPortSetting32 *)cdata)->pdata;
+
+ if(switchdSetBandwidthIngressRate(port, rate) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdGetBandwidthIngressRate(int port, unsigned long *ptrInt)
+{
+ if (port < 0 || port >= MAX_PHY_NUM){
+ ip1811drv_err("Error: port=%d\n", port);
+ return -EINVAL;
+ }
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *ptrInt = (unsigned long)(_ReadRegBits(0, P0REG_INGRESS_RATE_CTRL0+port, 0, 14)*64000);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetBandwidthIngressRate);
+int getBandwidthIngressRate(void *cdata, int len)
+{
+ int port;
+ unsigned long rate;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting32) != len)
+ {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ port = ((struct ByPortSetting32 *)cdata)->port;
+
+ if(switchdGetBandwidthIngressRate(port, &rate) != 0)
+ return -EINVAL;
+
+ ((struct ByPortSetting32 *)cdata)->pdata = rate;
+ ip1811drv_dbg("cdata->port=%d\n", ((struct ByPortSetting32 *)cdata)->port);
+ ip1811drv_dbg("cdata->pdata=0x%08X\n", (u16)((struct ByPortSetting32 *)cdata)->pdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetBandwidthEgressRate(int port, unsigned long rate)
+{
+ if (port < 0 || port >= MAX_PHY_NUM)
+ {
+ ip1811drv_err("Error: port=%d\n", port);
+ return -EINVAL;
+ }
+ if (rate > MAX_GIGA_SPEED)
+ {
+ ip1811drv_err("Error: pdata=0x%08X\n", (u16)rate);
+ return -EINVAL;
+ }
+ IP2Page(8);
+ if (rate == 0 || rate == MAX_GIGA_SPEED || (port < MAX_PHY_TP_NUM && rate >= MAX_TP_SPEED))
+ { Write_Reg(P8REG_EGRESS_RATE_CTRL0+port,0); }
+ else if(rate > 0 && rate < MAX_GIGA_SPEED)
+ {
+ if(port < MAX_PHY_TP_NUM && rate >= (MAX_TP_SPEED/RATE_SCALE_UNIT)*RATE_SCALE_UNIT)
+ { Write_Reg(P8REG_EGRESS_RATE_CTRL0+port,0); }
+ else if(rate >= (MAX_GIGA_SPEED/RATE_SCALE_UNIT)*RATE_SCALE_UNIT)
+ {
+ Write_Reg(P8REG_EGRESS_RATE_CTRL0+port,0);
+#ifdef COMBINED_PORT
+ if (port==9)
+ Write_Reg(P8REG_EGRESS_RATE_CTRL0+port+1,0);
+#endif
+ }
+ else
+ {
+ if(rate%RATE_SCALE_UNIT)
+ {
+ Write_Reg(P8REG_EGRESS_RATE_CTRL0+port,rate/RATE_SCALE_UNIT+1);
+#ifdef COMBINED_PORT
+ if (port==9)
+ Write_Reg(P8REG_EGRESS_RATE_CTRL0+port+1,rate/RATE_SCALE_UNIT+1);
+#endif
+ }
+ else
+ {
+ Write_Reg(P8REG_EGRESS_RATE_CTRL0+port,rate/RATE_SCALE_UNIT);
+#ifdef COMBINED_PORT
+ if (port==9)
+ Write_Reg(P8REG_EGRESS_RATE_CTRL0+port+1,rate/RATE_SCALE_UNIT+1);
+#endif
+ }
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetBandwidthEgressRate);
+int setBandwidthEgressRate(void *cdata, int len)
+{
+ int port;
+ unsigned long rate;
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting32) != len)
+ {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ port = ((struct ByPortSetting32 *)cdata)->port;
+ rate = ((struct ByPortSetting32 *)cdata)->pdata;
+
+ if(switchdSetBandwidthEgressRate(port, rate) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdGetBandwidthEgressRate(int port, unsigned long *ptrInt)
+{
+ if (port < 0 || port >= MAX_PHY_NUM){
+ ip1811drv_err("Error: port=%d\n", port);
+ return -EINVAL;
+ }
+ ip1811drv_dbg("port=%d\n", port);
+
+#ifdef COMBINED_PORT
+ if (port==9 && _ReadRegBits(3, 0x15, 0, 1)) //port==9 && port10 link
+ port++;
+#endif
+ *ptrInt = (unsigned long)(_ReadRegBits(8, P8REG_EGRESS_RATE_CTRL0+port, 0, 14)*64000);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetBandwidthEgressRate);
+int getBandwidthEgressRate(void *cdata, int len)
+{
+ int port;
+ unsigned long rate;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct ByPortSetting32) != len)
+ {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ port = ((struct ByPortSetting32 *)cdata)->port;
+
+ if(switchdGetBandwidthEgressRate(port, &rate) != 0)
+ return -EINVAL;
+
+ ((struct ByPortSetting32 *)cdata)->pdata = rate;
+ ip1811drv_dbg("cdata->port=%d\n", ((struct ByPortSetting32 *)cdata)->port);
+ ip1811drv_dbg("cdata->pdata=0x%08X\n", (u16)((struct ByPortSetting32 *)cdata)->pdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdSetBandwidthEgressPeriod(int period)
+{
+ if (period < 0 || period > 7){
+ ip1811drv_err("Error: gdata=%d\n", period);
+ return -EINVAL;
+ }
+ _WriteRegBits(8, P8REG_OUT_QUEUE_PARAM, 4, 3, period);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetBandwidthEgressPeriod);
+int setBandwidthEgressPeriod(void *cdata, int len)
+{
+ int period;
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len)
+ {
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ period = ((struct GeneralSetting *)cdata)->gdata;
+
+ if(switchdSetBandwidthEgressPeriod(period) != 0)
+ return -EINVAL;
+
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int switchdGetBandwidthEgressPeriod(int *ptrInt)
+{
+ *ptrInt = (int)_ReadRegBits(8,P8REG_OUT_QUEUE_PARAM,4,3);
+
+ ip1811drv_dbg("cdata ->pdata=%d\n", *ptrInt);
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdGetBandwidthEgressPeriod);
+int getBandwidthEgressPeriod(void *cdata, int len)
+{
+ int period=0;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct GeneralSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+
+ if(switchdGetBandwidthEgressPeriod(&period) != 0)
+ return -EINVAL;
+
+ ((struct GeneralSetting *)cdata)->gdata = period;
+
+ ip1811drv_dbg("cdata->gdata=0x%08X\n", ((struct GeneralSetting *)cdata)->gdata);
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+//------------ EEPROM functions:common start -----------------
+#define CMD_EEPROM_READ 0x8000
+#define CMD_EEPROM_WRITE 0xC000
+#define EEPROM_BIT_COMPLETE 0x8000
+#define REG_RETRY_COUNT 200
+
+u8 EE_Type = OP_EE_TYPE_Unknow;
+u8 EE_Data [OP_EEPROM_LEN_24C32] = {0x0};
+u8 EE_Flag [OP_EEPROM_LEN_24C32] = {0x0};
+
+u8 getEepromType(void)
+{
+ unsigned short val, i;
+
+ IP2Page(0xE);
+ Write_Reg(PEREG_EEPROM_CMD+1, (unsigned short)(Read_Reg(PEREG_EEPROM_CMD+1)&0xFF00));
+ IP2Page(0xE);
+ Write_Reg(PEREG_EEPROM_CMD, (CMD_EEPROM_READ + 0x1));
+
+ IP2Page(0xE);
+ val = Read_Reg(PEREG_EEPROM_CMD);
+ for(i = 0 ; 0 == (val&EEPROM_BIT_COMPLETE) && i < REG_RETRY_COUNT ; i++)
+ {
+ IP2Page(0xE);
+ val = Read_Reg(PEREG_EEPROM_CMD);
+ }
+
+ if(i == REG_RETRY_COUNT)
+ {
+ ip1811drv_err("Error: get EEPROM type REG_RETRY_COUNT reached\n");
+ return -EINVAL;
+ }
+
+ IP2Page(0xE);
+ val = Read_Reg(PEREG_EEPROM_DATA) & 0xFF;
+
+ udelay(5000);
+
+ if(val == 0x0B)
+ return OP_EE_TYPE_C16;
+ else if(val == 0x0D)
+ return OP_EE_TYPE_C32;
+ else
+ return OP_EE_TYPE_Unknow;
+}
+
+// EEPROM READ/WRITE
+int setEepromByte(void *cdata, int len)
+{
+ unsigned short addr2write, i, val;
+ unsigned char val2write;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct EepromSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ if(EE_Type==OP_EE_TYPE_Unknow)
+ {
+ EE_Type = getEepromType();
+ if(EE_Type==OP_EE_TYPE_Unknow)
+ {
+ ip1811drv_err("Error: setEEPROM get type failed\n");
+ return -EINVAL;
+ }
+ ip1811drv_dbg("set EEPROM type->%X\n", EE_Type);
+ }
+
+ addr2write = ((struct EepromSetting *)cdata)->addr;
+ val2write = ((struct EepromSetting *)cdata)->value;
+ if (addr2write > (EE_Type?OP_EEPROM_LEN_24C32:OP_EEPROM_LEN_24C16))
+ {
+ ip1811drv_err("Error: addr=0x%04X\n", addr2write);
+ return -EINVAL;
+ }
+ ip1811drv_dbg("type %X set addr:%04X , value:%02X\n", EE_Type, addr2write, val2write);
+
+ // update eeprom hardware
+ IP2Page(0xE);
+ Write_Reg(PEREG_EEPROM_DATA, val2write);
+ IP2Page(0xE);
+ if(EE_Type==OP_EE_TYPE_C16)
+ {
+ Write_Reg(PEREG_EEPROM_CMD, (CMD_EEPROM_WRITE + addr2write));
+ }
+ else
+ {
+ Write_Reg(PEREG_EEPROM_CMD+1, (unsigned short)((Read_Reg(PEREG_EEPROM_CMD+1)&0xFF00)|((addr2write>>8)&0xFF)));
+ IP2Page(0xE);
+ Write_Reg(PEREG_EEPROM_CMD, (CMD_EEPROM_WRITE + (addr2write&0xFF)));
+ }
+
+ IP2Page(0xE);
+ val = Read_Reg(PEREG_EEPROM_CMD);
+ for(i = 0 ; 0 == (val&EEPROM_BIT_COMPLETE) && i < REG_RETRY_COUNT ; i++)
+ {
+ IP2Page(0xE);
+ val = Read_Reg(PEREG_EEPROM_CMD);
+ }
+
+ if(i == REG_RETRY_COUNT)
+ {
+ ip1811drv_err("Error: set EEPROM REG_RETRY_COUNT reached %04X\n", addr2write);
+ return -EINVAL;
+ }
+
+// udelay(5000);
+
+ // update eeprom driver mem
+ EE_Flag[addr2write] = 0x1;
+ EE_Data[addr2write] = val2write;
+
+ ip1811drv_dbg("EE set done\n");
+ FUNC_MSG_OUT;
+ return 0;
+}
+
+int getEepromByte(void *cdata, int len)
+{
+ unsigned short addr2read, i, val;
+ unsigned char val2return;
+
+ FUNC_MSG_IN;
+ if (sizeof(struct EepromSetting) != len)
+ {
+ ip1811drv_err("Error: length=%d\n", len);
+ return -EINVAL;
+ }
+
+ if(EE_Type==OP_EE_TYPE_Unknow)
+ {
+ EE_Type = getEepromType();
+ if(EE_Type==OP_EE_TYPE_Unknow)
+ {
+ ip1811drv_err("Error: getEEPROM get type failed\n");
+ return -EINVAL;
+ }
+ ip1811drv_dbg("set EEPROM type->%X\n", EE_Type);
+ }
+
+ addr2read = ((struct EepromSetting *)cdata)->addr;
+ if (addr2read > (EE_Type?OP_EEPROM_LEN_24C32:OP_EEPROM_LEN_24C16))
+ {
+ ip1811drv_err("Error: addr=0x%04X\n", addr2read);
+ return -EINVAL;
+ }
+ ip1811drv_dbg("type %X get addr:%04X\n", EE_Type, addr2read);
+
+ if(EE_Flag[addr2read]==0x1) // return driver value
+ {
+ val2return = EE_Data[addr2read];
+ }
+ else // update driver memory
+ {
+ IP2Page(0xE);
+ if(EE_Type==OP_EE_TYPE_C16)
+ {
+ Write_Reg(PEREG_EEPROM_CMD, (CMD_EEPROM_READ + addr2read));
+ }
+ else
+ {
+ Write_Reg(PEREG_EEPROM_CMD+1, (unsigned short)((Read_Reg(PEREG_EEPROM_CMD+1)&0xFF00)|((addr2read>>8)&0xFF)));
+ IP2Page(0xE);
+ Write_Reg(PEREG_EEPROM_CMD, (CMD_EEPROM_READ + (addr2read & 0xFF)));
+ }
+
+ IP2Page(0xE);
+ val = Read_Reg(PEREG_EEPROM_CMD);
+ for(i = 0 ; 0 == (val&EEPROM_BIT_COMPLETE) && i < REG_RETRY_COUNT ; i++)
+ {
+ IP2Page(0xE);
+ val = Read_Reg(PEREG_EEPROM_CMD);
+ }
+
+ if(i == REG_RETRY_COUNT)
+ {
+ ip1811drv_err("Error: get EEPROM REG_RETRY_COUNT reached %04X\n", addr2read);
+ return -EINVAL;
+ }
+
+ IP2Page(0xE);
+ val2return = Read_Reg(PEREG_EEPROM_DATA) & 0xFF;
+
+ EE_Flag[addr2read] = 0x1;
+ EE_Data[addr2read] = val2return;
+
+// udelay(5000);
+ }
+
+ ((struct EepromSetting *)cdata)->value = val2return;
+ ip1811drv_dbg("EE get done and value:%04X\n", val2return);
+ FUNC_MSG_OUT;
+ return 0;
+}
+//------------ EEPROM functions:common end -----------------
+
+//------------ HSR functions:common Start -----------------------
+int setHSREnable(void *cdata, int len)
+{
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _setGeneralEnable(cdata, len, 0x02, P2REG_HSR_REG_SETTING_1, 0);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int getHSREnable(void *cdata, int len)
+{
+ int ret;
+
+ FUNC_MSG_IN;
+ ret = _getGeneralEnable(cdata, len, 0x02, P2REG_HSR_REG_SETTING_1, 0);
+ FUNC_MSG_OUT;
+
+ return ret;
+}
+
+int switchdSetHSRMode(int mode)
+{
+ if( mode != OP_HSR_MANDATORY && mode != OP_HSR_UNICAST ){
+ ip1811drv_err("Error: mode=%X\n", mode);
+ return -EINVAL;
+ }
+
+ ip1811drv_dbg("cdata ->mode=%d\n", mode);
+
+ if(mode==OP_HSR_MANDATORY){
+ _WriteRegBits(2, P2REG_HSR_REG_SETTING_1, 10, 2, 0x3);
+ _WriteRegBits(2, P2REG_HSR_REG_SETTING_2, 8, 1, 0x1);
+ _WriteRegBits(2, P2REG_HSR_REG_SETTING_2, 11, 1, 0x1);
+ _WriteRegBits(2, P2REG_HSR_REG_SETTING_2, 0, 2, 0x0);
+ _WriteRegBits(1, P1REG_MISCCFG, 13, 1, 0x1);
+ IP2Page(0x1);
+ Write_Reg(P1REG_LUTAGINGTIME, 0x0003);
+ _WriteRegBits(1, P1REG_MISCCFG, 13, 1, 0x0);
+ }
+ else if(mode==OP_HSR_UNICAST){
+ _WriteRegBits(2, P2REG_HSR_REG_SETTING_1, 10, 2, 0x3);
+ _WriteRegBits(2, P2REG_HSR_REG_SETTING_2, 8, 1, 0x1);
+ _WriteRegBits(2, P2REG_HSR_REG_SETTING_2, 11, 1, 0x1);
+ _WriteRegBits(2, P2REG_HSR_REG_SETTING_2, 0, 2, 0x3);
+ _WriteRegBits(1, P1REG_MISCCFG, 13, 1, 0x1);
+ IP2Page(0x1);
+ Write_Reg(P1REG_LUTAGINGTIME, 0x00A3);
+ _WriteRegBits(1, P1REG_MISCCFG, 13, 1, 0x0);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(switchdSetHSRMode);
+int setHSRMode(void *cdata, int len)
+{
+ int gdata;
+
+ if (sizeof(struct GeneralSetting) != len){
+ ip1811drv_err("Error: lengtn=%d\n", len);
+ return -EINVAL;
+ }
+ gdata = ((struct GeneralSetting *)cdata) ->gdata;
+
+ FUNC_MSG_IN;
+ if(switchdSetHSRMode(gdata) != 0)
+ return -EINVAL;
+ FUNC_MSG_OUT;
+
+ return 0;
+}
+
+void switchdGetHSRMode(int *ptrInt)
+{
+ int val;
+
+ val=(int)_ReadRegBits(2, P2REG_HSR_REG_SETTING_2, 0, 2);
+ if(val==0x3)
+ *ptrInt = OP_HSR_MANDATORY;
+ else if(val==0x0)
+ *ptrInt = OP_HSR_UNICAST;
+}
+EXPORT_SYMBOL(switchdGetHSRMode);
+int getHSRMode(void *cdata, int len)
+{
+ int ret;
+
+ ip1811drv_dbg("ip1811: +getHSRMode...\n");
+ if (sizeof(struct GeneralSetting) != len)
+ return -EINVAL;
+
+ FUNC_MSG_IN;
+ switchdGetHSRMode(&ret);
+ FUNC_MSG_OUT;
+
+ ((struct GeneralSetting *)cdata) ->gdata = ret;
+
+ ip1811drv_dbg("cdata ->gdata=%d\n", ((struct GeneralSetting *)cdata) ->gdata);
+ ip1811drv_dbg("ip1811: -getHSRMode...\n");
+ return 0;
+}
+//------------ HSR functions:common end -----------------------
+
+void noFunc(void)
+{}
diff --git a/kernel/drivers/net/ethernet/ip1811/ip1811op.h b/kernel/drivers/net/ethernet/ip1811/ip1811op.h
new file mode 100644
index 0000000..80591c3
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/ip1811op.h
@@ -0,0 +1,427 @@
+#ifndef IP1811OP_H
+#define IP1811OP_H
+
+#define OP_FUNC_DISABLE 0
+#define OP_FUNC_ENABLE 1
+
+#define OP_SMI_DUPLEX_HALF 0
+#define OP_SMI_DUPLEX_FULL 1
+
+#define OP_SMI_SPEED_1000 1000
+#define OP_SMI_SPEED_100 100
+#define OP_SMI_SPEED_10 10
+
+#define OP_CAP_PTCL_BPDU 0
+#define OP_CAP_PTCL_SLOW 1
+#define OP_CAP_PTCL_802_1X 2
+#define OP_CAP_PTCL_LLDP 3
+#define OP_CAP_PTCL_GRP0 4
+#define OP_CAP_PTCL_BRIDGE 5
+#define OP_CAP_PTCL_GRP1 6
+#define OP_CAP_PTCL_GARP 7
+#define OP_CAP_PTCL_GRP2 8
+#define OP_CAP_PTCL_GRP3 9
+
+#define OP_CAP_ACT_FORWARD 0
+#define OP_CAP_ACT_ALL_PORT 1
+#define OP_CAP_ACT_TO_CPU 2
+#define OP_CAP_ACT_DROP 3
+
+enum{
+ OP_CAT_INBAND_ARP, //0
+ OP_CAT_INBAND_IPV4,
+ OP_CAT_INBAND_IPV6,
+ OP_CAT_INBAND_PPPOE,
+ OP_CAT_INBAND_ICMP,
+ OP_CAT_INBAND_TCP,
+ OP_CAT_INBAND_UDP,
+ OP_CAT_INBAND_USER_ETH,
+ OP_CAT_INBAND_USER_IP1, //8
+ OP_CAT_INBAND_USER_IP2,
+ OP_CAT_INBAND_ICMPV6,
+ OP_CAT_INBAND_FTP,
+ OP_CAT_INBAND_SSH,
+ OP_CAT_INBAND_TELNET,
+ OP_CAT_INBAND_SMTP,
+ OP_CAT_INBAND_DNS,
+ OP_CAT_INBAND_BOOTP, //16
+ OP_CAT_INBAND_TFTP,
+ OP_CAT_INBAND_HTTP,
+ OP_CAT_INBAND_POP3,
+ OP_CAT_INBAND_NEWS,
+ OP_CAT_INBAND_SNTP,
+ OP_CAT_INBAND_NETBIOS,
+ OP_CAT_INBAND_IMAP,
+ OP_CAT_INBAND_SNMP, //24
+ OP_CAT_INBAND_HTTPS,
+ OP_CAT_INBAND_USER_TCPUDP_A,
+ OP_CAT_INBAND_USER_TCPUDP_B,
+ OP_CAT_INBAND_USER_TCPUDP_C,
+ OP_CAT_INBAND_USER_TCPUDP_D,
+ OP_CAT_INBAND_USER_TCPUDP_E,
+ OP_CAT_INBAND_TOTALNUM //31
+};
+
+enum{
+ OP_CAT_L3_ICMP, //0
+ OP_CAT_L3_TCP,
+ OP_CAT_L3_UDP,
+ OP_CAT_L3_OSPF,
+ OP_CAT_L3_USR1,
+ OP_CAT_L3_USR2,
+ OP_CAT_L3_IPV4_OTHER,
+ OP_CAT_L3_TOTALNUM //7
+};
+
+enum{
+ OP_TCPUDP_PTCL_FTP, //0
+ OP_TCPUDP_PTCL_SSH,
+ OP_TCPUDP_PTCL_TELNET,
+ OP_TCPUDP_PTCL_SMTP,
+ OP_TCPUDP_PTCL_DNS,
+ OP_TCPUDP_PTCL_DHCP,
+ OP_TCPUDP_PTCL_TFTP,
+ OP_TCPUDP_PTCL_HTTP,
+ OP_TCPUDP_PTCL_POP3,
+ OP_TCPUDP_PTCL_NEWS,
+ OP_TCPUDP_PTCL_SNTP, //10
+ OP_TCPUDP_PTCL_NETBIOS,
+ OP_TCPUDP_PTCL_IMAP,
+ OP_TCPUDP_PTCL_SNMP,
+ OP_TCPUDP_PTCL_HTTPS,
+ OP_TCPUDP_PTCL_USR_A,
+ OP_TCPUDP_PTCL_USR_B,
+ OP_TCPUDP_PTCL_USR_C,
+ OP_TCPUDP_PTCL_USR_D,
+ OP_TCPUDP_PTCL_USR_E,
+ OP_TCPUDP_PTCL_TOTALNUM //10
+};
+
+enum{
+ OP_TCPUDP_USER_A,
+ OP_TCPUDP_USER_B,
+ OP_TCPUDP_USER_C_LOWER,
+ OP_TCPUDP_USER_C_UPPER,
+ OP_TCPUDP_USER_D_LOWER,
+ OP_TCPUDP_USER_D_UPPER,
+ OP_TCPUDP_USER_E_LOWER,
+ OP_TCPUDP_USER_E_UPPER,
+ OP_TCPUDP_USER_TOTALNUM
+};
+
+enum{
+ OP_TCPUDP_ACT_Q0, //0
+ OP_TCPUDP_ACT_Q1,
+ OP_TCPUDP_ACT_Q2,
+ OP_TCPUDP_ACT_Q3,
+ OP_TCPUDP_ACT_Q4,
+ OP_TCPUDP_ACT_Q5,
+ OP_TCPUDP_ACT_Q6,
+ OP_TCPUDP_ACT_Q7,
+
+ OP_TCPUDP_ACT_TO_CPU = 9, //9
+ OP_TCPUDP_ACT_DROP,
+ OP_TCPUDP_ACT_ALL_PORT
+};
+
+enum{
+ OP_TCPFLAG_FLAG0,
+ OP_TCPFLAG_FLAG1,
+ OP_TCPFLAG_FLAG2,
+ OP_TCPFLAG_FLAG3
+};
+
+enum{
+ OP_TCPFLAG_ACT_NONE,
+ OP_TCPFLAG_ACT_STORMCTRL,
+ OP_TCPFLAG_ACT_TO_CPU,
+ OP_TCPFLAG_ACT_DROP
+};
+
+enum{
+ OP_IPV6_HEADER_FRAG,
+ OP_IPV6_HEADER_ENACP,
+ OP_IPV6_HEADER_AUTH,
+ OP_IPV6_HEADER_ICMPV6,
+ OP_IPV6_HEADER_ICMPV6_MLD,
+ OP_IPV6_HEADER_ICMPV6_NDP,
+ OP_IPV6_HEADER_USER1,
+ OP_IPV6_HEADER_USER2,
+ OP_IPV6_HEADER_ICMPV6_USER1,
+ OP_IPV6_HEADER_ICMPV6_USER2,
+ OP_IPV6_HEADER_TOTALNUM
+};
+
+enum{
+ OP_IPV6_HEADER_ICMPV6_USER1_HIGH,
+ OP_IPV6_HEADER_ICMPV6_USER1_LOW,
+ OP_IPV6_HEADER_ICMPV6_USER2_HIGH,
+ OP_IPV6_HEADER_ICMPV6_USER2_LOW
+};
+
+#define OP_SNIFFER1_METHOD_DISABLE 0
+#define OP_SNIFFER1_METHOD_EGRESS 1
+#define OP_SNIFFER1_METHOD_INGRESS 2
+#define OP_SNIFFER1_METHOD_BOTHDIR 3
+
+#define OP_SNIFFER1_PKT_MODIFY 0
+#define OP_SNIFFER1_PKT_KEEP 1
+
+#define OP_SNIFFER1_TAG_KEEP 0
+#define OP_SNIFFER1_TAG_MODIFY 1
+
+#define OP_SNIFFER2_LUT_TRIGGER_TARGET_DA 0
+#define OP_SNIFFER2_LUT_TRIGGER_TARGET_SA 1
+
+#define OP_STORM_BCST 0x01
+#define OP_STORM_MCST 0x02
+#define OP_STORM_DLF 0x04
+#define OP_STORM_ARP 0x08
+#define OP_STORM_ICMP 0x10
+
+#define OP_EOC_STATUS_NORMAL 0
+#define OP_EOC_STATUS_LOOP_DETECTED 1
+
+#define OP_EOC_RELEASE_TIME_1MIN 1
+#define OP_EOC_RELEASE_TIME_10MIN 10
+
+#define OP_LD_TIME_UNIT_500MS 0
+#define OP_LD_TIME_UNIT_10S 1
+
+#define OP_LD_STATUS_NORMAL 0
+#define OP_LD_STATUS_LOOP_DETECTED 1
+
+#define OP_WOL_MODE_SLAVE 0
+#define OP_WOL_MODE_MASTER 1
+
+#define OP_WOL_IDLE_UNIT_DISABLE 0
+#define OP_WOL_IDLE_UNIT_10s 1
+#define OP_WOL_IDLE_UNIT_1min 2
+#define OP_WOL_IDLE_UNIT_10min 3
+
+#define OP_WOL_STATUS_NORMAL 0
+#define OP_WOL_STATUS_SLEEPING 1
+#define OP_WOL_STATUS_RDY4SLEEP 2
+#define OP_WOL_STATUS_SLEEP 3
+
+#define OP_CPU_PORT_NORMAL 0
+#define OP_CPU_PORT_CPU 1
+
+#define OP_MAC_SELF_TEST_PKT_NO_32768 32768
+#define OP_MAC_SELF_TEST_PKT_NO_4096 4096
+#define OP_MAC_SELF_TEST_PKT_NO_256 256
+#define OP_MAC_SELF_TEST_PKT_NO_16 16
+
+#define OP_MAC_SELF_TEST_RESULT_FAIL 0
+#define OP_MAC_SELF_TEST_RESULT_PASS 1
+
+#define OP_BPDU_CMODE_GLOBAL 0
+#define OP_BPDU_CMODE_BY_PORT 1
+
+#define OP_STP_STATE_DISCARD 0
+#define OP_STP_STATE_BLOCK 1
+#define OP_STP_STATE_LEARN 2
+#define OP_STP_STATE_FORWARD 3
+
+#define OP_TRUNK_HASH_METHOD_PORT_ID 0
+#define OP_TRUNK_HASH_METHOD_SA 1
+#define OP_TRUNK_HASH_METHOD_DA 2
+#define OP_TRUNK_HASH_METHOD_DA_SA 3
+#define OP_TRUNK_HASH_METHOD_DIP 4
+#define OP_TRUNK_HASH_METHOD_SIP 5
+#define OP_TRUNK_HASH_METHOD_DP 6
+#define OP_TRUNK_HASH_METHOD_SP 7
+
+#define OP_TRUNK_COMBINE_G1_G2 5
+#define OP_TRUNK_COMBINE_G3_G4 6
+#define OP_TRUNK_COMBINE_G5_G6 7
+
+#define OP_LUT_LEARN_MODE_ALL_BY_AGING_TIME 0x0
+#define OP_LUT_LEARN_MODE_NEVER_OVERWRITE 0x1
+#define OP_LUT_LEARN_MODE_L2_BY_AGING_TIME 0x3
+
+#define OP_HASH_DIRECT 0
+#define OP_HASH_CRC 1
+
+#define OP_LUT_UNKNOWN_SA_FWD_2_CPU 0x0
+#define OP_LUT_UNKNOWN_SA_DROP 0x1
+#define OP_LUT_UNKNOWN_SA_FWD 0x2
+
+/* LUT flushing */
+#define OP_LUT_FLUSH_DYNAMIC_ONLY 0x0
+#define OP_LUT_FLUSH_STATIC_ONLY 0x1//not implemented
+#define OP_LUT_FLUSH_ALL 0x2
+
+/* LUT cfg */
+#define OP_LUT_CFG_FID 0
+#define OP_LUT_CFG_MD 1 //multi-destination, not implemented
+#define OP_LUT_CFG_TRAN 2 //vlan translation
+#define OP_LUT_CFG_MVT 3 //mac-based vlan
+
+/* LUT action */
+#define OP_ENTRY_CREATE 0
+#define OP_ENTRY_CONFIG 1
+#define OP_ENTRY_DELETE 2
+#define OP_ENTRY_CREATE_REG 3
+
+#define OP_ENTRY_GET_BY_INDEX 4
+#define OP_ENTRY_GET_BY_INFO 5
+
+/* the state for getLutValidEntry */
+#ifndef BIT
+#define BIT(x) (1UL << (x))
+#endif
+#define OP_LUT_STATE_DYNAMIC BIT(0)
+#define OP_LUT_STATE_STATIC BIT(1)
+#define OP_LUT_STATE_ALL (OP_LUT_STATE_DYNAMIC|OP_LUT_STATE_STATIC)
+//#define OP_LUT_STATE_ALL (OP_LUT_STATE_DYNAMIC|OP_LUT_STATE_ALL_STATIC)
+
+
+enum{
+ /* target entry is valid and index values are matched */
+ OP_ENTRY_EXISTS=0xE0,
+ /* target entry is valid but index values are not matched */
+ OP_ENTRY_NOT_MATCH,
+ /* target entry is invalid */
+ OP_ENTRY_NOT_FOUND,
+ /* target dynamice entry is valid and index values are matched */
+ OP_ENTRY_EXISTS_DYNAMIC,
+};
+
+#define OP_IGMP_PACKET_QUERY 0
+#define OP_IGMP_PACKET_LEAVE 4
+#define OP_IGMP_PACKET_UN_REG_DATA 8
+#define OP_IGMP_PACKET_UN_DEFINED 12
+#define OP_IGMP_PACKET_REPORT 1
+#define OP_IGMP_PACKET_GROUP_SPECIFIC_QUERY 6
+#define OP_IGMP_PACKET_REG_DATA 11
+
+#define OP_IGMP_RULE_BCST 0x01
+#define OP_IGMP_RULE_CPU 0x02
+#define OP_IGMP_RULE_ROUTER 0x04
+#define OP_IGMP_RULE_DROP 0x08
+#define OP_IGMP_RULE_GROUP_MEM 0x10
+
+#define OP_IGMP_SLT_IPV4 4
+#define OP_IGMP_SLT_IPV6 6
+
+#define OP_MLD_SEND_TO_PORTS 0
+#define OP_MLD_SEND_TO_PORTS_AND_CPU 1
+#define OP_MLD_SEND_TO_CPU 2
+#define OP_MLD_DROP 3
+
+#define OP_IMP_DROP_IP_MISMATCH 0
+#define OP_IMP_DROP_IP_MATCH 1
+
+#define OP_IMP_IPTYPE_4 0
+#define OP_IMP_IPTYPE_6 1
+
+#define OP_VLAN_EGRESS_UNI_FRAME 0x1
+#define OP_VLAN_EGRESS_ARP_FRAME 0x2
+#define OP_VLAN_EGRESS_MULTI_FRAME 0x4
+
+#define OP_VLAN_TAGGING_BY_PORT 0x0
+#define OP_VLAN_TAGGING_BY_VID 0x1
+
+#define OP_VLAN_TYPE_GROUP 0x0
+#define OP_VLAN_TYPE_TAG 0x1
+
+#define OP_VLAN_PROTOCOL_INVALID 0x0
+#define OP_VLAN_PROTOCOL_ETHER 0x1
+#define OP_VLAN_PROTOCOL_LLC 0x2
+#define OP_VLAN_PROTOCOL_1042 0x3
+
+enum{
+ OP_VLAN_QINQ_STAG_METHOD_ADDR,
+ OP_VLAN_QINQ_STAG_METHOD_ACL
+};
+
+#define OP_QOS_8021PEDTION_2005 0 //2005 edition
+#define OP_QOS_8021PEDTION_2005_EX 1 //2005 + exchange
+#define OP_QOS_8021PEDTION_EARLY 2 //early
+
+#define OP_QOS_GROUP1 0
+#define OP_QOS_GROUP2 1
+
+#define OP_CPU_IF_SPEED_HIGH 0
+#define OP_CPU_IF_SPEED_NORMAL 1
+
+enum{
+ OP_QOS_MODE_FIFO,
+ OP_QOS_MODE_WWBBT,
+ OP_QOS_MODE_SP1_WWBBT7,
+ OP_QOS_MODE_SP2_WWBBT6,
+ OP_QOS_MODE_SP4_WWBBT4,
+ OP_QOS_MODE_SP8
+};
+
+enum{
+ OP_QOS_NUM_Q0,
+ OP_QOS_NUM_Q1,
+ OP_QOS_NUM_Q2,
+ OP_QOS_NUM_Q3,
+ OP_QOS_NUM_Q4,
+ OP_QOS_NUM_Q5,
+ OP_QOS_NUM_Q6,
+ OP_QOS_NUM_Q7
+};
+enum{
+ OP_QOS_UNIT_64KBS,
+ OP_QOS_UNIT_1MBS,
+ OP_QOS_UNIT_2MBS,
+ OP_QOS_UNIT_4MBS
+};
+enum{
+ OP_QOS_REMAP_RX_Q0,
+ OP_QOS_REMAP_RX_Q1,
+ OP_QOS_REMAP_RX_Q2,
+ OP_QOS_REMAP_RX_Q3,
+ OP_QOS_REMAP_RX_Q4,
+ OP_QOS_REMAP_RX_Q5,
+ OP_QOS_REMAP_RX_Q6,
+ OP_QOS_REMAP_RX_Q7,
+ OP_QOS_REMAP_TX_Q0,
+ OP_QOS_REMAP_TX_Q1,
+ OP_QOS_REMAP_TX_Q2,
+ OP_QOS_REMAP_TX_Q3,
+ OP_QOS_REMAP_TX_Q4,
+ OP_QOS_REMAP_TX_Q5,
+ OP_QOS_REMAP_TX_Q6,
+ OP_QOS_REMAP_TX_Q7
+};
+#define OP_QOS_REMPA_RX 0
+#define OP_QOS_REMPA_TX 1
+enum{
+ OP_QOS_METHOD_WRR,
+ OP_QOS_METHOD_BW,
+ OP_QOS_METHOD_WFQ,
+ OP_QOS_METHOD_TWRR
+};
+
+#define OP_QOS_QBASE_DBM 0
+#define OP_QOS_QBASE_SBM 1
+
+enum{
+ OP_BW_PERIOD_4KB_500MS,
+ OP_BW_PERIOD_2KB_250MS,
+ OP_BW_PERIOD_1KB_125MS,
+ OP_BW_PERIOD_512B_63MS,
+ OP_BW_PERIOD_256B_31MS,
+ OP_BW_PERIOD_128B_16MS,
+ OP_BW_PERIOD_64B_8MS,
+ OP_BW_PERIOD_32B_4MS
+};
+
+#define OP_EEPROM_LEN_24C16 2048
+#define OP_EEPROM_LEN_24C32 4096
+
+enum Eeprom_Type {
+ OP_EE_TYPE_C16,
+ OP_EE_TYPE_C32,
+ OP_EE_TYPE_Unknow
+};
+
+#define OP_HSR_MANDATORY 0
+#define OP_HSR_UNICAST 1
+
+#endif /* IP1811OP_H */
diff --git a/kernel/drivers/net/ethernet/ip1811/ip1811reg.h b/kernel/drivers/net/ethernet/ip1811/ip1811reg.h
new file mode 100644
index 0000000..a42c842
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/ip1811reg.h
@@ -0,0 +1,231 @@
+
+#define REG_Page 0xFF
+
+// Page0
+#define P0REG_MACBEHAVIOR 0x01
+#define P0REG_L2FRAMEGETCTRL 0x04
+#define P0REG_L2FRAMEGETCTRL1 0x05
+#define P0REG_BPDUPORTCAPCFG 0x0A
+#define P0REG_QOS8021PBASEPRIEN 0x26
+#define P0REG_QOSDSCPBASEPRIEN 0x27
+#define P0REG_QOSDSCPPRISETTING0 0x28
+#define P0REG_QOSDSCPPRISETTING1 0x29
+#define P0REG_QOSDSCPVALUE0 0x2A
+#define P0REG_QOSIPBASEPRIEN 0x31
+#define P0REG_INGRESS_RATE_CTRL0 0x40
+#define P0REG_TEST_PACKET_CTRL 0x4D
+#define P0REG_TEST_RESULT 0x4E
+#define P0REG_MACADDRESS 0x84
+#define P0REG_COSPORTBASEPRIEN 0x60
+#define P0REG_COS8021PBASEPRIEN 0x62
+#define P0REG_COSDSCPBASEPRIEN 0x64
+#define P0REG_COSTCPUDPBASEPRIEN 0x21
+#define P0REG_COSMACBASEPRIEN 0x66
+#define P0REG_COSVIDBASEPRIEN 0x68
+#define P0REG_COSIGMPBASEPRIEN 0x6A
+#define P0REG_COSPORTBASEQUEUE0 0x70
+#define P0REG_COSPORTBASEQUEUE1 0x71
+#define P0REG_COSPORTBASEQUEUE2 0x72
+#define P0REG_COSDSCPPRISETTING0 0x76
+#define P0REG_COSDSCPPRISETTING1 0x77
+#define P0REG_COSDSCPVALUE0 0x78
+#define P0REG_COSDSCPVALUE1 0x79
+#define P0REG_COSDSCPVALUE2 0x7A
+#define P0REG_COSDSCPVALUE3 0x7B
+#define P0REG_TCPUDPUSERDEF 0x10
+#define P0REG_TCPUDPPRICFG 0x18
+#define P0REG_TCPUDFUNCEN 0x1F
+#define P0REG_L3FRAMEGETCTRL 0x07
+#define P0REG_TCPCHECKEN 0x23
+#define P0REG_UDPCHECKEN 0x25
+#define P0REG_TCPFLGCFGGLB 0x30
+#define P0REG_TCPFLGCFG0 0x32
+#define P0REG_TCPFLGPORTEN 0x38
+#define P0REG_PORTLOCKEN 0x91
+#define P0REG_IPV6RLTCFG 0xA1
+#define P0REG_IPV6RLTFWD 0xA2
+#define POREG_MIBCOUN_CMD 0xA7
+#define POREG_MIBCOUN_DATA_L 0xA8
+#define POREG_MIBCOUN_DATA_H 0xA9
+#define P0REG_LDCONFIG 0xC0
+#define P0REG_LDEN 0xC1
+#define P0REG_LDTIMER 0xC3
+#define P0REG_LDSTATUS 0xCB
+#define P0REG_LDDA0 0xC4
+#define P0REG_LDSUBTYPE 0xC8
+#define P0REG_PTPCFG 0xA0
+
+// Page 1
+#define P1REG_CONFIG_CPUPORT 0x01
+#define P1REG_LUTAGINGTIME 0x02
+#define P1REG_SRCLEARNCFG 0x03
+#define P1REG_SRCLEARN_ENABLE 0x04
+#define P1REG_BSTORMTHRESH 0x09
+#define P1REG_ARPSTORMCFG 0x0A
+#define P1REG_ICMPSTORMCFG 0x0B
+#define P1REG_BSTORMEN 0x0C
+#define P1REG_MSTORMEN 0x0E
+#define P1REG_DLFSTORMEN 0x10
+#define P1REG_ARPSTORMEN 0x12
+#define P1REG_ICMPSTORMEN 0x14
+#define P1REG_OAM_8023_LB_CFG 0x14
+#define P1REG_TRUNKCFG 0x16
+#define P1REG_TRUNKGRP 0x17
+#define P1REG_SNIFCFG 0x1A
+#define P1REG_SNIFDEST 0x1B
+#define P1REG_SNIFSRC 0x1D
+#define P1REG_MEM_COMMAND 0x1D
+#define P1REG_MEM_TABLE_0 0x1E
+#define P1REG_PORTFLUSH 0x25
+#define P1REG_LUTFLUSH_CFG 0x27
+#define P1REG_LUTCFG 0x28
+#define P1REG_LUTDATA_0 0x29
+#define P1REG_LUTDATA_1 0x2A
+#define P1REG_LUTDATA_2 0x2B
+#define P1REG_LUTDATA_3 0x2C
+#define P1REG_LUTDATA_4 0x2D
+#define P1REG_LUTDATA_5 0x2E
+#define P1REG_MISCCFG 0x2F
+#define P1REG_MEM_MCT_COMMAND 0xA0
+#define P1REG_MEM_MCT_TABLE_0 0xA1
+#define P1REG_IGMPSNOP 0xA8
+#define P1REG_IGMPPKTFWD_0 0xA9
+#define P1REG_IGMPPKTFWD_1 0xAA
+#define P1REG_ROUTLIST 0xAE
+#define P1REG_MEM_SLT_COMMAND 0xB0
+#define P1REG_MEM_SLT_TABLE_0 0xB1
+#define P1REG_ACL_PATTEM_LOCATION_D3 0xD3
+#define P1REG_ACL_PATTEM_LOCATION_D4 0xD4
+#define P1REG_ACL_STORM_0 0xD7
+#define P1REG_ACL_BW_01 0xD7
+#define P1REG_ACL_TABLE_ACCESS 0xE0
+#define P1REG_ACL_TABLE_DATA_E1 0xE1
+#define P1REG_ACL_TABLE_DATA_E2 0xE2
+#define P1REG_ACL_TABLE_DATA_E3 0xE3
+#define P1REG_ACL_TABLE_DATA_E4 0xE4
+#define P1REG_ACL_TABLE_DATA_E5 0xE5
+#define P1REG_ACL_TABLE_DATA_E6 0xE6
+#define P1REG_ACL_TABLE_DATA_E7 0xE7
+#define P1REG_ACL_TABLE_DATA_E8 0xE8
+#define P1REG_ACL_TABLE_DATA_E9 0xE9
+#define P1REG_ACL_TABLE_DATA_EA 0xEA
+
+// Page2
+#define P2REG_VLANCFG 0x01
+#define P2REG_VLAN_INACTIVE_VID 0x02
+#define P2REG_VLAN_INGRESS_FRAME_0 0x04 //bit 0 for per port
+#define P2REG_VLAN_INGRESS_FRAME_1 0x06 //bit 1 for per port
+#define P2REG_VLAN_INGRESS_CHK 0x0A
+#define P2REG_VLANLOCAL 0x0C
+#define P2REG_VLAN_EGRESS_CFG 0x0E
+#define P2REG_VLAN_EGRESS_CFG1 0x10
+#define P2REG_VLAN_EXCLUSIVE 0x11
+#define P2REG_VLAN_ADDTAG 0x13
+#define P2REG_VLAN_RMVTAG 0x15
+#define P2REG_VLAN_UPLINK 0x17
+#define P2REG_VLAN_PVIDCFG 0x20
+#define P2REG_VLANGROUP 0x40
+#define P2REG_VLAN_MACBASED_ENTRY_0 0x80
+#define P2REG_VLAN_MACBASED_UNKNOWN 0x9B
+#define P2REG_VLAN_PROCOTOL_CFG 0xA0
+#define P2REG_SPANTREE_PORTCMD 0xB2
+#define P2REG_SPANTREE_PORTDTA 0xB3
+#define P2REG_VLANCMD 0xB5
+#define P2REG_VLANDAT0 0xB6
+#define P2REG_ACL_VID_REMARK_00 0xD0
+#define P2REG_HSR_REG_SETTING_1 0xFC
+#define P2REG_HSR_REG_SETTING_2 0xFD
+
+// Page 3
+#define P3REG_AN 0x01
+#define P3REG_SPG 0x02
+#define P3REG_SP 0x03
+#define P3REG_DUPLEX 0x04
+#define P3REG_PAUSE 0x05
+#define P3REG_ASPAUSE 0x06
+#define P3REG_BPRESS 0x07
+#define P3REG_POWERDOWN 0x08
+#define P3REG_UNIDIRECT 0x09
+#define P3REG_PORTSTS0 0x10
+#define P3REG_FORCELINK 0x24
+
+// Page4
+#define P4REG_OAM_8023AH_DYING_GASP 0x01
+#define P4REG_OAM_8023AH_CFG0 0x02
+#define P4REG_OAM_8023AH_REMOTE_CMD0 0x08
+#define P4REG_OAM_8023AH_REMOTE_DAT0 0x09
+#define P4REG_OAM_8023AH_STAT0 0x10
+#define P4REG_OAM_8023AH_REMOTE_INFO_OUI 0x1B
+#define P4REG_OAM_8023AH_RECV_DAT0 0x1D
+#define P4REG_OAM_8023AH_RECV_CMD0 0x1E
+#define P4REG_OAM_8023AH_FAULT_RECORD 0x1F
+
+// Page 6
+#define P6REG_QOS_REMAP_RX0 0x19
+
+// Page 7
+#define P7REG_QINQ_RMVTAG 0x01
+#define P7REG_QINQ_ADDTAG 0x02
+#define P7REG_QINQEGTYPELEN 0x03
+#define P7REG_QINQ_DET_RX 0x05
+#define P7REG_QINQ_DATA 0x06
+#define P7REG_QINQ_P_DATA 0x16
+#define P7REG_DSCP_REMARKING_01 0x22
+#define P7REG_TXDMA 0x33
+
+// Page8
+#define P8REG_QOSMODESELGROUP1 0x01
+#define P8REG_QOSGP1_WEIGHT0 0x02
+#define P8REG_QOSGP1_MAXBDWT0 0x0A
+#define P8REG_EGRESS_RATE_CTRL0 0x4C
+#define P8REG_OUT_QUEUE_PARAM 0x5E
+#define P8REG_QOSAGINGTIME 0x37
+#define P8REG_QOSPORTAGINGEN0 0x38
+#define P8REG_QOS_REMAP_TX0 0x11
+#define P8REG_QOSGROUPSEL 0x3F
+#define P8REG_QOSMODESELGROUP2 0x3E
+#define P8REG_QOSGP2_WEIGHT0 0x40
+#define P8REG_QOSGP2_MAXBDWT0 0x48
+#define P8REG_QOSQUEUEDBMEN 0x36
+#define P8REG_QOS_SBMDBMSEL0 0x30
+
+// Page9
+#define P9REG_PTP_CLOCK_RESET 0x00
+#define P9REG_PTP_TIMESTAMP_READ 0x01
+#define P9REG_PTP_CONFIGURATION 0x02
+#define P9REG_PTP_PORT_TIMESTAMP0 0x03
+#define P9REG_PTP_PORT_TIMESTAMP1 0x04
+#define P9REG_PTP_TIMESTAMP_CLEAR0 0x05
+#define P9REG_PTP_TIMESTAMP_CLEAR1 0x06
+#define P9REG_PTP_TIMEDATA_NANOSEC0 0x07
+#define P9REG_PTP_TIMEDATA_NANOSEC1 0x08
+#define P9REG_PTP_TIMEDATA_SEC0 0x09
+#define P9REG_PTP_TIMEDATA_SEC1 0x0A
+#define P9REG_PTP_TIMEDATA_SEC2 0x0B
+#define P9REG_PTP_CLOCK_CONTROL 0x0C
+#define P9REG_PTP_FREQUENCY_ADD0 0x0D
+#define P9REG_PTP_FREQUENCY_ADD1 0x0E
+#define P9REG_PTP_CLOCK_PERIOD 0x0F
+#define P9REG_PTP_FREQUENCY_COMPENSATION0 0x10
+#define P9REG_PTP_FREQUENCY_COMPENSATION1 0x11
+#define P9REG_PTP_FREQUENCY_COMPENSATION2 0x12
+#define P9REG_PTP_FREQUENCY_COMPENSATION3 0x13
+#define P9REG_PTP_FREQUENCY_COMPENSATION_CONTROL 0x14
+#define P9REG_PTP_PROGRAMMABLE_OUTPUT 0x15
+#define P9REG_PTP_INGRESS_LATENCY_10TP 0x1A
+#define P9REG_PTP_EGRESS_LATENCY_10TP 0x1B
+#define P9REG_PTP_INGRESS_LATENCY_100TP 0x1C
+#define P9REG_PTP_EGRESS_LATENCY_100TP 0x1D
+#define P9REG_PTP_INGRESS_LATENCY_FIBER 0x20
+#define P9REG_PTP_EGRESS_LATENCY_FIBER 0x21
+
+// PageD
+
+// PageE
+#define PEREG_SW_RESET 0x00
+#define PEREG_CPUMODE 0x03
+#define PEREG_SPTAG 0x05
+#define PEREG_INT_STATUS 0x07
+#define PEREG_LAST_GASP_CONFIG 0x08
+#define PEREG_EEPROM_CMD 0x0A
+#define PEREG_EEPROM_DATA 0x0C
diff --git a/kernel/drivers/net/ethernet/ip1811/ip218.h b/kernel/drivers/net/ethernet/ip1811/ip218.h
new file mode 100644
index 0000000..4ea77f3
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/ip218.h
@@ -0,0 +1,29 @@
+#ifndef IP218_H
+#define IP218_H
+
+#if 1
+#define IP218_MAC_BASE 0xBC400000 //Virtual Address
+#else
+#define IP218_MAC_BASE 0x1C400000 //Physical Address
+#endif
+
+#define IP218_MAC_SMICTRL0 0x0004
+#define IP218_MAC_SMICTRL1 0x0008
+
+struct ip218_smictrl0{
+ unsigned long wr_data:16;
+ unsigned long en:1;
+ unsigned long rdwr:1;
+ unsigned long rev2:1;
+ unsigned long phy:5;
+ unsigned long rev1:3;
+ unsigned long reg:5;
+};
+
+struct ip218_smictrl1{
+ unsigned long mdc_clk_divisor:3;
+ unsigned long rev:13;
+ unsigned long rd_data:16;
+};
+
+#endif
diff --git a/kernel/drivers/net/ethernet/ip1811/libcommon.h b/kernel/drivers/net/ethernet/ip1811/libcommon.h
new file mode 100644
index 0000000..3aaa686
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/libcommon.h
@@ -0,0 +1,53 @@
+#ifndef __LIB_COMMON_H__
+#define __LIB_COMMON_H__
+#include <sys/types.h>//for u_int8_t
+
+#undef OK
+#define OK 0
+
+#undef ERROR
+#define ERROR -1
+
+#undef FALSE
+#define FALSE 0
+
+#undef TRUE
+#define TRUE 1
+
+#undef DISABLE
+#define DISABLE 0
+
+#undef ENABLE
+#define ENABLE 1
+
+#define FREE_SAFE(a) if(a!=NULL){free(a);a=NULL;}
+
+#define SV_WDT_WDT_TIME (100)//Unit depends on WORKQUEUE_DELAY_TIME defined in supervisor.c
+
+/************************************************************
+ * Name: getSysUptime
+ * Description: get system uptime from proc file
+ * Parameters: None
+ * Return value:failed: -1
+ * success: float type uptime
+ * **********************************************************/
+float getSysUptime(void);
+long getSysUptime_10ms(void);
+void daemonize(void);
+int lock_file(char *filename);
+int unlock_file(int fd, char *filename);
+
+void get_switch_mac(u_int8_t* macaddr);
+void get_switch_ip(u_int8_t *ip);
+void get_switch_netmask(u_int8_t *mask);
+void get_gateway_ip(u_int8_t *ip);
+void get_gateway_ipv6(u_int8_t *ipv6);
+void DER_OID_decoder(unsigned char *input_OID, unsigned int OIDLen, char *outputString);
+char popen_d(char *cmd, char *ret, unsigned int ret_len);
+void printfd(char *file, char *buf);
+char ipStr2Array(char *ip, char *buf);
+int do_fork_execvp(char *argv[]);
+int supervisor_wdt_add(char *command, const char *func_name, int wdt_life_time);
+int supervisor_wdt_del(char *command);
+int supervisor_wdt_reset(char *command);
+#endif//__LIB_COMMON_H__
diff --git a/kernel/drivers/net/ethernet/ip1811/list.h b/kernel/drivers/net/ethernet/ip1811/list.h
new file mode 100644
index 0000000..0bbafbf
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/list.h
@@ -0,0 +1,517 @@
+/**
+ *
+ * I grub it from linux kernel source code and fix it for user space
+ * program. Of course, this is a GPL licensed header file.
+ *
+ * Here is a recipe to cook list.h for user space program
+ *
+ * 1. copy list.h from linux/include/list.h
+ * 2. remove
+ * - #ifdef __KERNE__ and its #endif
+ * - all #include line
+ * - prefetch() and rcu related functions
+ * 3. add macro offsetof() and container_of
+ *
+ * - kazutomo@mcs.anl.gov
+ */
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+#include <stddef.h>
+/**
+ * @name from other kernel headers
+ */
+/*@{*/
+
+/**
+ * Get offset of a member
+ */
+//#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+/**
+ * Casts a member of a structure out to the containing structure
+ * @param ptr the pointer to the member.
+ * @param type the type of the container struct this is embedded in.
+ * @param member the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+/*@}*/
+
+
+/*
+ * These are non-NULL pointers that will result in page faults
+ * under normal circumstances, used to verify that nobody uses
+ * non-initialized list entries.
+ */
+#define LIST_POISON1 ((void *) 0x00100100)
+#define LIST_POISON2 ((void *) 0x00200200)
+
+/**
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+#define INIT_LIST_HEAD(ptr) do { \
+ (ptr)->next = (ptr); (ptr)->prev = (ptr); \
+} while (0)
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head->prev, head);
+}
+
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = LIST_POISON1;
+ entry->prev = LIST_POISON2;
+}
+
+
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+ return head->next == head;
+}
+
+static inline void __list_splice(struct list_head *list,
+ struct list_head *head)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+ struct list_head *at = head->next;
+
+ first->prev = head;
+ head->next = first;
+
+ last->next = at;
+ at->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+ if (!list_empty(list))
+ __list_splice(list, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ */
+
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); \
+ pos = pos->next)
+
+/**
+ * __list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev - iterate over a list backwards
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+ for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
+ pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop counter.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use as a start point in
+ * list_for_each_entry_continue
+ * @pos: the type * to use as a start point
+ * @head: the head of the list
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_prepare_entry(pos, head, member) \
+ ((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - iterate over list of given type
+ * continuing after existing point
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_continue(pos, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue - iterate over list of given type
+ * continuing after existing point safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member) \
+ for (pos = list_entry(pos->member.next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against
+ * removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member) \
+ for (pos = list_entry((head)->prev, typeof(*pos), member), \
+ n = list_entry(pos->member.prev, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+
+
+
+/*
+ * Double linked lists with a single pointer list head.
+ * Mostly useful for hash tables where the two pointer list head is
+ * too wasteful.
+ * You lose the ability to access the tail in O(1).
+ */
+
+struct hlist_head {
+ struct hlist_node *first;
+};
+
+struct hlist_node {
+ struct hlist_node *next, **pprev;
+};
+
+#define HLIST_HEAD_INIT { .first = NULL }
+#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
+#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
+#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
+
+static inline int hlist_unhashed(const struct hlist_node *h)
+{
+ return !h->pprev;
+}
+
+static inline int hlist_empty(const struct hlist_head *h)
+{
+ return !h->first;
+}
+
+static inline void __hlist_del(struct hlist_node *n)
+{
+ struct hlist_node *next = n->next;
+ struct hlist_node **pprev = n->pprev;
+ *pprev = next;
+ if (next)
+ next->pprev = pprev;
+}
+
+static inline void hlist_del(struct hlist_node *n)
+{
+ __hlist_del(n);
+ n->next = LIST_POISON1;
+ n->pprev = LIST_POISON2;
+}
+
+
+static inline void hlist_del_init(struct hlist_node *n)
+{
+ if (n->pprev) {
+ __hlist_del(n);
+ INIT_HLIST_NODE(n);
+ }
+}
+
+static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
+{
+ struct hlist_node *first = h->first;
+ n->next = first;
+ if (first)
+ first->pprev = &n->next;
+ h->first = n;
+ n->pprev = &h->first;
+}
+
+
+
+/* next must be != NULL */
+static inline void hlist_add_before(struct hlist_node *n,
+ struct hlist_node *next)
+{
+ n->pprev = next->pprev;
+ n->next = next;
+ next->pprev = &n->next;
+ *(n->pprev) = n;
+}
+
+static inline void hlist_add_after(struct hlist_node *n,
+ struct hlist_node *next)
+{
+ next->next = n->next;
+ n->next = next;
+ next->pprev = &n->next;
+
+ if(next->next)
+ next->next->pprev = &next->next;
+}
+
+
+
+#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
+
+#define hlist_for_each(pos, head) \
+ for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
+ pos = pos->next)
+
+#define hlist_for_each_safe(pos, n, head) \
+ for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
+ pos = n)
+
+/**
+ * hlist_for_each_entry - iterate over list of given type
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry(tpos, pos, head, member) \
+ for (pos = (head)->first; \
+ pos && ({ prefetch(pos->next); 1;}) && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = pos->next)
+
+/**
+ * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_continue(tpos, pos, member) \
+ for (pos = (pos)->next; \
+ pos && ({ prefetch(pos->next); 1;}) && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = pos->next)
+
+/**
+ * hlist_for_each_entry_from - iterate over a hlist continuing from existing point
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_from(tpos, pos, member) \
+ for (; pos && ({ prefetch(pos->next); 1;}) && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = pos->next)
+
+/**
+ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @tpos: the type * to use as a loop counter.
+ * @pos: the &struct hlist_node to use as a loop counter.
+ * @n: another &struct hlist_node to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
+ for (pos = (head)->first; \
+ pos && ({ n = pos->next; 1; }) && \
+ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+ pos = n)
+
+
+#endif
diff --git a/kernel/drivers/net/ethernet/ip1811/port_config.h b/kernel/drivers/net/ethernet/ip1811/port_config.h
new file mode 100644
index 0000000..96e556e
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/port_config.h
@@ -0,0 +1,16 @@
+#ifndef __PORT_CONFIG_H__
+#define __PORT_CONFIG_H__
+#include "portnumber.h"
+
+#define MAX_PORT_NUM get_MaxPort()
+#define GIGA_PORT_START get_GPStart()
+#define GIGA_PORT_END get_GPEnd()
+
+#define MAX_IPORT_CNT SWITCH_MAX_IPORT_CNT
+#define ALL_PORTS_LIST (~(-1 << MAX_PORT_NUM))
+#define GIGA_PORT_NUM (GIGA_PORT_END - GIGA_PORT_START)
+#define CPU_PORT_NUM MAX_IPORT_CNT
+#define MAX_TP_PORT_NUM (GIGA_PORT_START -1)
+
+#endif
+
diff --git a/kernel/drivers/net/ethernet/ip1811/system_config.h b/kernel/drivers/net/ethernet/ip1811/system_config.h
new file mode 100644
index 0000000..b80d6f5
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/system_config.h
@@ -0,0 +1,36 @@
+
+#ifndef __SYSTEM_CONFIG_H__
+#define __SYSTEM_CONFIG_H__
+///////////////////////////////////////////////
+//// board config
+///////////////////////////////////////////////
+
+//#define SYSTEM_CONFIG__FPGA
+//#define SYSTEM_CONFIG__ASIC//this is ASIC_135
+//#define SYSTEM_CONFIG__ASIC125
+//#define SYSTEM_CONFIG__ASIC_135
+#define SYSTEM_CONFIG__ASIC_150
+
+
+#define SYSTEM_CONFIG__SERVER_MODE
+//#define SYSTEM_CONFIG__PCI_MODE
+
+
+///////////////////////////////////////////////
+//// DRAM parameter - ref: sdram_support_list
+///////////////////////////////////////////////
+
+#define SYSTEM_CONFIG_DRAM__ARCH_4CH
+//#define SYSTEM_CONFIG_DRAM__USED_2CHIPS
+//#define SYSTEM_CONFIG_FLASH__USED_2CHIPS
+
+//#define SYSTEM_CONFIG_DRAM__NT5SV16M16CS_6K
+//#define SYSTEM_CONFIG_DRAM__PMS308416BTR_6
+//#define SYSTEM_CONFIG_DRAM__IS42S16320D
+#define SYSTEM_CONFIG_DRAM__W9825G6KH_6I
+//#define SYSTEM_CONFIG_DRAM__A3V56S30
+
+//#define SYS_CONFIG_WITH_IP102_PHY
+
+#endif
+
diff --git a/kernel/drivers/net/ethernet/ip1811/types.h b/kernel/drivers/net/ethernet/ip1811/types.h
new file mode 100644
index 0000000..bfcfab4
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/types.h
@@ -0,0 +1,17 @@
+#ifndef _TYPES_H_
+#define _TYPES_H_
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+typedef char s8;
+typedef short s16;
+typedef int s32;
+typedef long long s64;
+
+#define BIT(x) (1UL<<(x))
+
+#define err (-1)
+
+#endif
diff --git a/kernel/drivers/net/ethernet/ip1811/zconf.h b/kernel/drivers/net/ethernet/ip1811/zconf.h
new file mode 100644
index 0000000..8912fe6
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/zconf.h
@@ -0,0 +1,506 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2012 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateResetKeep z_inflateResetKeep
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+/* ./configure may #define Z_U4 here */
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# else
+# if (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# else
+# if (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+# endif
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#if 1 /* was set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#if 1 /* was set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#ifdef _WIN32
+# include <stddef.h> /* for wchar_t */
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/kernel/drivers/net/ethernet/ip1811/zlib.h b/kernel/drivers/net/ethernet/ip1811/zlib.h
new file mode 100644
index 0000000..3edf3ac
--- /dev/null
+++ b/kernel/drivers/net/ethernet/ip1811/zlib.h
@@ -0,0 +1,1744 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.7, May 2nd, 2012
+
+ Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.7"
+#define ZLIB_VERNUM 0x1270
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 7
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed data.
+ This version of the library supports only one compression method (deflation)
+ but other algorithms will be added later and will have the same stream
+ interface.
+
+ Compression can be done in a single step if the buffers are large enough,
+ or can be done by repeated calls of the compression function. In the latter
+ case, the application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never crash
+ even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ z_const Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total number of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total number of bytes output so far */
+
+ z_const char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has dropped
+ to zero. It must update next_out and avail_out when avail_out has dropped
+ to zero. The application must initialize zalloc, zfree and opaque before
+ calling the init function. All other fields are set by the compression
+ library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this if
+ the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
+ returned by zalloc for objects of exactly 65536 bytes *must* have their
+ offset normalized to zero. The default allocation function provided by this
+ library ensures this (see zutil.c). To reduce memory requirements and avoid
+ any allocation of 64K objects, at the expense of compression ratio, compile
+ the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or progress
+ reports. After compression, total_in holds the total size of the
+ uncompressed data and may be saved for use in the decompressor (particularly
+ if the decompressor wants to decompress everything in a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+#define Z_TREES 6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is not
+ compatible with the zlib.h header file used by the application. This check
+ is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller. If
+ zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+ allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at all
+ (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
+ requests a default compromise between speed and compression (currently
+ equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if level is not a valid compression level, or
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION). msg is set to null
+ if there is no error message. deflateInit does not perform any compression:
+ this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications). Some
+ output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating avail_in or avail_out accordingly; avail_out should
+ never be zero before the call. The application can consume the compressed
+ output when it wants, for example when the output buffer is full (avail_out
+ == 0), or after each call of deflate(). If deflate returns Z_OK and with
+ zero avail_out, it must be called again after making room in the output
+ buffer because there might be more output pending.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumulate before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In
+ particular avail_in is zero after the call if enough output space has been
+ provided before the call.) Flushing may degrade compression for some
+ compression algorithms and so it should be used only when necessary. This
+ completes the current deflate block and follows it with an empty stored block
+ that is three bits plus filler bits to the next byte, followed by four bytes
+ (00 00 ff ff).
+
+ If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+ output buffer, but the output is not aligned to a byte boundary. All of the
+ input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+ This completes the current deflate block and follows it with an empty fixed
+ codes block that is 10 bits long. This assures that enough bytes are output
+ in order for the decompressor to finish the block before the empty fixed code
+ block.
+
+ If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+ for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+ seven bits of the current block are held to be written as the next byte after
+ the next deflate block is completed. In this case, the decompressor may not
+ be provided enough bits at this point in order to complete decompression of
+ the data provided so far to the compressor. It may need to wait for the next
+ block to be emitted. This is for advanced applications that need to control
+ the emission of deflate blocks.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there was
+ enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the stream
+ are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least the
+ value returned by deflateBound (see below). Then deflate is guaranteed to
+ return Z_STREAM_END. If not enough output space is provided, deflate will
+ not return Z_STREAM_END, and it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect the
+ compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case, msg
+ may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the
+ exact value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit() does not process any header information -- that is deferred
+ until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing will
+ resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there is
+ no more input data or no more space in the output buffer (see below about
+ the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating the next_* and avail_* values accordingly. The
+ application can consume the uncompressed output when it wants, for example
+ when the output buffer is full (avail_out == 0), or after each call of
+ inflate(). If inflate returns Z_OK and with zero avail_out, it must be
+ called again after making room in the output buffer because there might be
+ more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+ Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate()
+ stop if and when it gets to the next deflate block boundary. When decoding
+ the zlib or gzip format, this will cause inflate() to return immediately
+ after the header and before the first block. When doing a raw inflate,
+ inflate() will go ahead and process the first block, and will return when it
+ gets to the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64 if
+ inflate() is currently decoding the last block in the deflate stream, plus
+ 128 if inflate() returned immediately after decoding an end-of-block code or
+ decoding the complete header up to just before the first byte of the deflate
+ stream. The end-of-block will not be indicated until all of the uncompressed
+ data from that block has been written to strm->next_out. The number of
+ unused bits may in general be greater than seven, except when bit 7 of
+ data_type is set, in which case the number of unused bits will be less than
+ eight. data_type is set as noted here every time inflate() returns for all
+ flush options, and so can be used to determine the amount of currently
+ consumed input in bits.
+
+ The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+ end of each deflate block header is reached, before any actual data in that
+ block is decoded. This allows the caller to determine the length of the
+ deflate block header for later use in random access within a deflate block.
+ 256 is added to the value of strm->data_type when inflate() returns
+ immediately after reaching the end of the deflate block header.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step (a
+ single call of inflate), the parameter flush should be set to Z_FINISH. In
+ this case all pending input is processed and all pending output is flushed;
+ avail_out must be large enough to hold all of the uncompressed data for the
+ operation to complete. (The size of the uncompressed data may have been
+ saved by the compressor for this purpose.) The use of Z_FINISH is not
+ required to perform an inflation in one step. However it may be used to
+ inform inflate that a faster approach can be used for the single inflate()
+ call. Z_FINISH also informs inflate to not maintain a sliding window if the
+ stream completes, which reduces inflate's memory footprint. If the stream
+ does not complete, either because not all of the stream is provided or not
+ enough output space is provided, then a sliding window will be allocated and
+ inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+ been used.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the effects of the flush parameter in this implementation are
+ on the return value of inflate() as noted below, when inflate() returns early
+ when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+ memory for a sliding window when Z_FINISH is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the Adler-32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically, if requested when
+ initializing with inflateInit2(). Any information contained in the gzip
+ header is not retained, so applications that need that information should
+ instead use raw inflate, see inflateInit2() below, or inflateBack() and
+ perform their own processing of the gzip header and trailer. When processing
+ gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+ producted so far. The CRC-32 is checked against the gzip trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may
+ then call inflateSync() to look for a good compression block if a partial
+ recovery of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by the
+ caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero), no
+ header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but is
+ slow and reduces compression ratio; memLevel=9 uses maximum memory for
+ optimal speed. The default value is 8. See zconf.h for total memory usage
+ as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
+ fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
+ strategy parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set appropriately.
+ Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+ decoder for special applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+ method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+ incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
+ set to null if there is no error message. deflateInit2 does not perform any
+ compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. When using the zlib format, this
+ function must be called immediately after deflateInit, deflateInit2 or
+ deflateReset, and before any call of deflate. When doing raw deflate, this
+ function must be called either before any call of deflate, or immediately
+ after the completion of a deflate block, i.e. after all input has been
+ consumed and all output has been delivered when using any of the flush
+ options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
+ compressor and decompressor must use exactly the same dictionary (see
+ inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size
+ provided in deflateInit or deflateInit2. Thus the strings most likely to be
+ useful should be put at the end of the dictionary, not at the front. In
+ addition, the current implementation of deflate will use at most the window
+ size minus 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if not at a block boundary for raw deflate). deflateSetDictionary does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and can
+ consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state. The
+ stream will keep the same compression level and any other attributes that
+ may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different strategy.
+ If the compression level is changed, the input available so far is
+ compressed with the old level (and may be flushed); the new level will take
+ effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to be
+ compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+ strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit() or
+ deflateInit2(), and after deflateSetHeader(), if used. This would be used
+ to allocate an output buffer for deflation in a single pass, and so would be
+ called before deflate(). If that first deflate() call is provided the
+ sourceLen input bytes, an output buffer allocated to the size returned by
+ deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+ to return Z_STREAM_END. Note that it is possible for the compressed size to
+ be larger than the value returned by deflateBound() if flush options other
+ than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+ unsigned *pending,
+ int *bits));
+/*
+ deflatePending() returns the number of bytes and bits of output that have
+ been generated, but not yet provided in the available output. The bytes not
+ provided would be due to the available output space having being consumed.
+ The number of bits of output not provided are between 0 and 7, where they
+ await more bits to join them in order to fill out a full byte. If pending
+ or bits are Z_NULL, then those values are not set.
+
+ deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the bits
+ leftover from a previous deflate stream when appending to it. As such, this
+ function can only be used for raw deflate, and must be used before the first
+ deflate() call after a deflateInit2() or deflateReset(). bits must be less
+ than or equal to 16, and that many of the least significant bits of value
+ will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+ room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be zero to request that inflate use the window size in
+ the zlib header of the compressed stream.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
+ crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit2 does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit2() does not process any header information -- that is
+ deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called at any
+ time to set the dictionary. If the provided dictionary is smaller than the
+ window and there is already data in the window, then the provided dictionary
+ will amend what's there. The application must insure that the dictionary
+ that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a possible full flush point (see above
+ for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+ All full flush points have this pattern, but not all occurences of this
+ pattern are full flush points.
+
+ inflateSync returns Z_OK if a possible full flush point has been found,
+ Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+ has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+ In the success case, the application may save the current current value of
+ total_in which indicates where valid compressed data was found. In the
+ error case, the application may repeatedly call inflateSync, providing more
+ input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state. The
+ stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+ int windowBits));
+/*
+ This function is the same as inflateReset, but it also permits changing
+ the wrap and window size requests. The windowBits parameter is interpreted
+ the same as it is for inflateInit2.
+
+ inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+ the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ If bits is negative, then the input stream bit buffer is emptied. Then
+ inflatePrime() can be called again to put bits in the buffer. This is used
+ to clear out bits leftover after feeding inflate a block description prior
+ to feeding inflate codes.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+ This function returns two values, one in the lower 16 bits of the return
+ value, and the other in the remaining upper bits, obtained by shifting the
+ return value down 16 bits. If the upper value is -1 and the lower value is
+ zero, then inflate() is currently decoding information outside of a block.
+ If the upper value is -1 and the lower value is non-zero, then inflate is in
+ the middle of a stored block, with the lower value equaling the number of
+ bytes from the input remaining to copy. If the upper value is not -1, then
+ it is the number of bits back from the current bit position in the input of
+ the code (literal or length/distance pair) currently being processed. In
+ that case the lower value is the number of bytes already emitted for that
+ code.
+
+ A code is being processed if inflate is waiting for more input to complete
+ decoding of the code, or if it has completed decoding but is waiting for
+ more output space to write the literal or match data.
+
+ inflateMark() is used to mark locations in the input data for random
+ access, which may be at bit positions, and to note those cases where the
+ output of a code may span boundaries of random access blocks. The current
+ location in the input stream can be determined from avail_in and data_type
+ as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+ inflateMark returns the value noted above or -1 << 16 if the provided
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
+ used to force inflate() to return immediately after header processing is
+ complete and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When any
+ of extra, name, or comment are not Z_NULL and the respective field is not
+ present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+ allocated, or Z_VERSION_ERROR if the version of the library does not match
+ the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is more efficient than inflate() for
+ file i/o applications in that it avoids copying between the output and the
+ sliding window by simply making the window itself the output buffer. This
+ function trusts the application to not change the output buffer passed by
+ the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free the
+ allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects only
+ the raw deflate stream to decompress. This is different from the normal
+ behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+ in the deflate stream (in which case strm->msg is set to indicate the nature
+ of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+ In the case of Z_BUF_ERROR, an input or output error can be distinguished
+ using strm->next_in which will be Z_NULL only if in() returned an error. If
+ strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+ non-zero. (in() will always be called before out(), so strm->next_in is
+ assured to be defined if out() returns non-zero.) Note that inflateBack()
+ cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the basic
+ stream-oriented functions. To simplify the interface, some default options
+ are assumed (compression level and memory usage, standard memory allocation
+ functions). The source code of these utility functions can be modified if
+ you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before a
+ compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit, destLen
+ is the actual size of the uncompressed buffer.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
+ the case where there is not enough room, uncompress() will fill the output
+ buffer with the uncompressed data up to that point.
+*/
+
+ /* gzip file access functions */
+
+/*
+ This library supports reading and writing files in gzip (.gz) format with
+ an interface similar to that of stdio, using the functions that start with
+ "gz". The gzip format is different from the zlib format. gzip is a gzip
+ wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+ Opens a gzip (.gz) file for reading or writing. The mode parameter is as
+ in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+ a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+ compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+ for fixed code compression as in "wb9F". (See the description of
+ deflateInit2 for more information about the strategy parameter.) 'T' will
+ request transparent writing or appending with no compression and not using
+ the gzip format.
+
+ "a" can be used instead of "w" to request that the gzip stream that will
+ be written be appended to the file. "+" will result in an error, since
+ reading and writing to the same gzip file is not supported. The addition of
+ "x" when writing will create the file exclusively, which fails if the file
+ already exists. On systems that support it, the addition of "e" when
+ reading or writing will set the flag to close the file on an execve() call.
+
+ These functions, as well as gzip, will read and decode a sequence of gzip
+ streams in a file. The append function of gzopen() can be used to create
+ such a file. (Also see gzflush() for another way to do this.) When
+ appending, gzopen does not test whether the file begins with a gzip stream,
+ nor does it look for the end of the gzip streams to begin appending. gzopen
+ will simply append a gzip stream to the existing file.
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression. When
+ reading, this will be detected automatically by looking for the magic two-
+ byte gzip header.
+
+ gzopen returns NULL if the file could not be opened, if there was
+ insufficient memory to allocate the gzFile state, or if an invalid mode was
+ specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+ errno can be checked to determine if the reason gzopen failed was that the
+ file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen associates a gzFile with the file descriptor fd. File descriptors
+ are obtained from calls like open, dup, creat, pipe or fileno (if the file
+ has been previously opened with fopen). The mode parameter is as in gzopen.
+
+ The next call of gzclose on the returned gzFile will also close the file
+ descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+ fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+ mode);. The duplicated descriptor should be saved to avoid a leak, since
+ gzdopen does not close fd if it fails. If you are using fileno() to get the
+ file descriptor from a FILE *, then you will have to use dup() to avoid
+ double-close()ing the file descriptor. Both gzclose() and fclose() will
+ close the associated file descriptor, so they need to have different file
+ descriptors.
+
+ gzdopen returns NULL if there was insufficient memory to allocate the
+ gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+ provided, or '+' was provided), or if fd is -1. The file descriptor is not
+ used until the next gz* read, write, seek, or close operation, so gzdopen
+ will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+ Set the internal buffer size used by this library's functions. The
+ default buffer size is 8192 bytes. This function must be called after
+ gzopen() or gzdopen(), and before any other calls that read or write the
+ file. The buffer memory allocation is always deferred to the first read or
+ write. Two buffers are allocated, either both of the specified size when
+ writing, or one of the specified size and the other twice that size when
+ reading. A larger buffer size of, for example, 64K or 128K bytes will
+ noticeably increase the speed of decompression (reading).
+
+ The new buffer size also affects the maximum length for gzprintf().
+
+ gzbuffer() returns 0 on success, or -1 on failure, such as being called
+ too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file. If
+ the input file is not in gzip format, gzread copies the given number of
+ bytes into the buffer directly from the file.
+
+ After reaching the end of a gzip stream in the input, gzread will continue
+ to read, looking for another gzip stream. Any number of gzip streams may be
+ concatenated in the input file, and will all be decompressed by gzread().
+ If something other than a gzip stream is encountered after a gzip stream,
+ that remaining trailing garbage is ignored (and no error is returned).
+
+ gzread can be used to read a gzip file that is being concurrently written.
+ Upon reaching the end of the input, gzread will return with the available
+ data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+ gzclearerr can be used to clear the end of file indicator in order to permit
+ gzread to be tried again. Z_OK indicates that a gzip stream was completed
+ on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
+ middle of a gzip stream. Note that gzread does not return -1 in the event
+ of an incomplete gzip stream. This error is deferred until gzclose(), which
+ will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+ stream. Alternatively, gzerror can be used before gzclose to detect this
+ case.
+
+ gzread returns the number of uncompressed bytes actually read, less than
+ len for end of file, or -1 for error.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes written or 0 in case of
+ error.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the arguments to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written, or 0 in case of error. The number of
+ uncompressed bytes written is limited to 8191, or one less than the buffer
+ size given to gzbuffer(). The caller should assure that this limit is not
+ exceeded. If it is exceeded, then gzprintf() will return an error (0) with
+ nothing written. In this case, there may also be a buffer overflow with
+ unpredictable consequences, which is possible only if zlib was compiled with
+ the insecure functions sprintf() or vsprintf() because the secure snprintf()
+ or vsnprintf() functions were not available. This can be determined using
+ zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or a
+ newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. If any characters are read or if len == 1, the
+ string is terminated with a null character. If no characters are read due
+ to an end-of-file or len < 1, then the buffer is left untouched.
+
+ gzgets returns buf which is a null-terminated string, or it returns NULL
+ for end-of-file or in case of error. If there was an error, the contents at
+ buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file. gzputc
+ returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte or -1
+ in case of end of file or error. This is implemented as a macro for speed.
+ As such, it does not do all of the checking the other functions do. I.e.
+ it does not check to see if file is NULL, nor whether the structure file
+ points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read as the first character
+ on the next read. At least one character of push-back is allowed.
+ gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
+ fail if c is -1, and may fail if a character has been pushed but not read
+ yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
+ output buffer size of pushed characters is allowed. (See gzbuffer above.)
+ The pushed character will be discarded if the stream is repositioned with
+ gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter flush
+ is as in the deflate() function. The return value is the zlib error number
+ (see function gzerror below). gzflush is only permitted when writing.
+
+ If the flush parameter is Z_FINISH, the remaining data is written and the
+ gzip stream is completed in the output. If gzwrite() is called again, a new
+ gzip stream will be started in the output. gzread() is able to read such
+ concatented gzip streams.
+
+ gzflush should be called only when strictly necessary because it will
+ degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+
+ Returns the starting position for the next gzread or gzwrite on the given
+ compressed file. This position represents a number of bytes in the
+ uncompressed data stream, and is zero when starting, even if appending or
+ reading a gzip stream from the middle of a file using gzdopen().
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+ Returns the current offset in the file being read or written. This offset
+ includes the count of bytes that precede the gzip stream, for example when
+ appending or when using gzdopen() for reading. When reading, the offset
+ does not include as yet unused buffered input. This information can be used
+ for a progress indicator. On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns true (1) if the end-of-file indicator has been set while reading,
+ false (0) otherwise. Note that the end-of-file indicator is set only if the
+ read tried to go past the end of the input, but came up short. Therefore,
+ just like feof(), gzeof() may return false even if there is no more data to
+ read, in the event that the last read request was for the exact number of
+ bytes remaining in the input file. This will happen if the input file size
+ is an exact multiple of the buffer size.
+
+ If gzeof() returns true, then the read functions will return no more data,
+ unless the end-of-file indicator is reset by gzclearerr() and the input file
+ has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns true (1) if file is being copied directly while reading, or false
+ (0) if file is a gzip stream being decompressed.
+
+ If the input file is empty, gzdirect() will return true, since the input
+ does not contain a gzip stream.
+
+ If gzdirect() is used immediately after gzopen() or gzdopen() it will
+ cause buffers to be allocated to allow reading the file to determine if it
+ is a gzip file. Therefore if gzbuffer() is used, it should be called before
+ gzdirect().
+
+ When writing, gzdirect() returns true (1) if transparent writing was
+ requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
+ gzdirect() is not needed when writing. Transparent writing must be
+ explicitly requested, so the application already knows the answer. When
+ linking statically, using gzdirect() will include all of the zlib code for
+ gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file and
+ deallocates the (de)compression state. Note that once file is closed, you
+ cannot call gzerror with file, since its structures have been deallocated.
+ gzclose must not be called more than once on the same file, just as free
+ must not be called more than once on the same allocation.
+
+ gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+ file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+ last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+ Same as gzclose(), but gzclose_r() is only for use when reading, and
+ gzclose_w() is only for use when writing or appending. The advantage to
+ using these instead of gzclose() is that they avoid linking in zlib
+ compression or decompression code that is not used when only reading or only
+ writing respectively. If gzclose() is used, then both compression and
+ decompression code will be included the application when linking to a static
+ zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the given
+ compressed file. errnum is set to zlib error number. If an error occurred
+ in the file system and not in the compression library, errnum is set to
+ Z_ERRNO and the application may consult errno to get the exact error code.
+
+ The application must not modify the returned string. Future calls to
+ this function may invalidate the previously returned string. If file is
+ closed, then the string previously returned by gzerror will no longer be
+ available.
+
+ gzerror() should be used to distinguish errors from end-of-file for those
+ functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the compression
+ library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is Z_NULL, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster.
+
+ Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
+ that the z_off_t type (like off_t) is a signed integer. If len2 is
+ negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is Z_NULL, this function returns the required
+ initial value for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
+
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure. Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro. The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously. They can
+ * only be used by the gzgetc() macro. You have been warned.
+ */
+struct gzFile_s {
+ unsigned have;
+ unsigned char *next;
+ z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+# define z_gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#else
+# define gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+# ifdef Z_PREFIX_SET
+# define z_gzopen z_gzopen64
+# define z_gzseek z_gzseek64
+# define z_gztell z_gztell64
+# define z_gzoffset z_gzoffset64
+# define z_adler32_combine z_adler32_combine64
+# define z_crc32_combine z_crc32_combine64
+# else
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# endif
+# ifndef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+# endif
+#else
+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* hack for buggy compilers */
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;};
+#endif
+
+/* undocumented functions */
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
+#if defined(_WIN32) && !defined(Z_SOLO)
+ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
+ const char *mode));
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
--
Gitblit v1.6.2