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