270 lines
6.2 KiB
C
270 lines
6.2 KiB
C
|
#ifdef __RTOS__
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/types.h>
|
||
|
#include <linux/skbuff.h>
|
||
|
#include <linux/netdevice.h>
|
||
|
#ifdef HGIC_SMAC
|
||
|
#include "umac_config.h"
|
||
|
#endif
|
||
|
#else
|
||
|
#include <linux/version.h>
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/sched.h>
|
||
|
#include <linux/firmware.h>
|
||
|
#include <linux/interrupt.h>
|
||
|
#include <linux/netdevice.h>
|
||
|
#endif
|
||
|
#include "utils.h"
|
||
|
#include "../hgic_def.h"
|
||
|
|
||
|
#define aSymbolLength 40
|
||
|
#define STATBUF_SIZE (64*1024)
|
||
|
#define SAFE_DIV(a, b) (((b) == 0) ? 0 : ((a) / (b)))
|
||
|
|
||
|
int hgic_skip_padding(struct sk_buff *skb)
|
||
|
{
|
||
|
int i = 0;
|
||
|
|
||
|
for (i = 0; i < 3 && skb->data[i] == 0xFF; i++);
|
||
|
if (i) {
|
||
|
if (skb->len > 0) {
|
||
|
skb_pull(skb, i);
|
||
|
} else {
|
||
|
skb->data += i;
|
||
|
skb->tail += i;
|
||
|
}
|
||
|
}
|
||
|
return i;
|
||
|
}
|
||
|
EXPORT_SYMBOL(hgic_skip_padding);
|
||
|
|
||
|
#if 0
|
||
|
int hgic_aligned_padding(struct sk_buff *skb)
|
||
|
{
|
||
|
uint32_t i = 0;
|
||
|
uint32_t count = 0;
|
||
|
uint8_t *data = skb->data - 4;
|
||
|
if (!IS_ALIGNED((uint32_t)skb->data, 4)) {
|
||
|
count = (uint32_t)skb->data - (uint32_t)ALIGN((uint32_t)data, 4);
|
||
|
if (count > 0) {
|
||
|
skb_push(skb, count);
|
||
|
for (i = 0; i < count; i++) {
|
||
|
skb->data[i] = 0xFF;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return count;
|
||
|
}
|
||
|
EXPORT_SYMBOL(hgic_aligned_padding);
|
||
|
#endif
|
||
|
|
||
|
void hgic_print_hex(char *buf, int len)
|
||
|
{
|
||
|
int i = 0;
|
||
|
|
||
|
for (i = 0; i < len; i++) {
|
||
|
if (i > 0 && i % 16 == 0) { printk("\r\n"); }
|
||
|
else if (i > 0 && i % 8 == 0) { printk(" "); }
|
||
|
printk("%02x ", buf[i] & 0xff);
|
||
|
}
|
||
|
printk("\r\n\r\n");
|
||
|
}
|
||
|
EXPORT_SYMBOL(hgic_print_hex);
|
||
|
|
||
|
int hgic_config_read_int(char *conf, char *field)
|
||
|
{
|
||
|
char *ptr = strstr(conf, field);
|
||
|
if (ptr) {
|
||
|
return simple_strtol(ptr + strlen(field) + 1, 0, 10);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
EXPORT_SYMBOL(hgic_config_read_int);
|
||
|
|
||
|
int hgic_config_read_str(char *conf, char *field, char *str, int size)
|
||
|
{
|
||
|
char *ptr = strstr(conf, field);
|
||
|
if (ptr) {
|
||
|
ptr += strlen(field) + 1;
|
||
|
while (*ptr && *ptr != '\r' && *ptr != '\n' && size > 0) {
|
||
|
*str++ = *ptr++;
|
||
|
size--;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
EXPORT_SYMBOL(hgic_config_read_str);
|
||
|
|
||
|
int hgic_config_read_u32_array(char *conf, char *field, u32 *arr, int count)
|
||
|
{
|
||
|
int cnt = 0;
|
||
|
int val = 0;
|
||
|
char *ptr = strstr(conf, field);
|
||
|
|
||
|
if (ptr) {
|
||
|
ptr += strlen(field) + 1;
|
||
|
while (cnt < count) {
|
||
|
while (*ptr >= '0' && *ptr <= '9') {
|
||
|
val *= 10;
|
||
|
val += (*ptr - 0x30);
|
||
|
ptr++;
|
||
|
}
|
||
|
if (val) {
|
||
|
arr[cnt++] = val;
|
||
|
}
|
||
|
|
||
|
if (*ptr != ',' || val == 0) {
|
||
|
break;
|
||
|
}
|
||
|
ptr++;
|
||
|
val = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return cnt;
|
||
|
}
|
||
|
EXPORT_SYMBOL(hgic_config_read_u32_array);
|
||
|
|
||
|
int hgic_config_read_u16_array(char *conf, char *field, u16 *arr, int count)
|
||
|
{
|
||
|
int cnt = 0;
|
||
|
int val = 0;
|
||
|
char *ptr = strstr(conf, field);
|
||
|
|
||
|
if (ptr) {
|
||
|
ptr += strlen(field) + 1;
|
||
|
while (cnt < count) {
|
||
|
while (*ptr >= '0' && *ptr <= '9') {
|
||
|
val *= 10;
|
||
|
val += (*ptr - 0x30);
|
||
|
ptr++;
|
||
|
}
|
||
|
if (val) {
|
||
|
arr[cnt++] = val;
|
||
|
}
|
||
|
|
||
|
if (*ptr != ',' || val == 0) {
|
||
|
break;
|
||
|
}
|
||
|
ptr++;
|
||
|
val = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return cnt;
|
||
|
}
|
||
|
EXPORT_SYMBOL(hgic_config_read_u16_array);
|
||
|
|
||
|
void hgic_clear_queue(struct sk_buff_head *q)
|
||
|
{
|
||
|
ulong flags = 0;
|
||
|
struct sk_buff *skb = NULL;
|
||
|
struct sk_buff *tmp = NULL;
|
||
|
|
||
|
spin_lock_irqsave(&q->lock, flags);
|
||
|
if (!skb_queue_empty(q)) {
|
||
|
skb_queue_walk_safe(q, skb, tmp) {
|
||
|
__skb_unlink(skb, q);
|
||
|
kfree_skb(skb);
|
||
|
}
|
||
|
}
|
||
|
spin_unlock_irqrestore(&q->lock, flags);
|
||
|
}
|
||
|
|
||
|
int hgic_hex2num(char c)
|
||
|
{
|
||
|
if (c >= '0' && c <= '9') {
|
||
|
return c - '0';
|
||
|
}
|
||
|
if (c >= 'a' && c <= 'f') {
|
||
|
return c - 'a' + 10;
|
||
|
}
|
||
|
if (c >= 'A' && c <= 'F') {
|
||
|
return c - 'A' + 10;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
int hgic_hex2byte(const char *hex)
|
||
|
{
|
||
|
int a, b;
|
||
|
a = hgic_hex2num(*hex++);
|
||
|
if (a < 0) {
|
||
|
return -1;
|
||
|
}
|
||
|
b = hgic_hex2num(*hex++);
|
||
|
if (b < 0) {
|
||
|
return -1;
|
||
|
}
|
||
|
return (a << 4) | b;
|
||
|
}
|
||
|
|
||
|
int hgic_pick_macaddr(char *mac_str, u8 *addr)
|
||
|
{
|
||
|
int i = 0;
|
||
|
int val = 0;
|
||
|
const char *ptr = (const char *)mac_str;
|
||
|
|
||
|
memset(addr, 0, 6);
|
||
|
while (ptr && i < 6 && strlen(mac_str) >= 17) {
|
||
|
if (i < 5 && ptr[2] != ':') { break; }
|
||
|
val = hgic_hex2byte(ptr);
|
||
|
if (val < 0) { break; }
|
||
|
addr[i++] = (u8)val;
|
||
|
ptr += 3;
|
||
|
}
|
||
|
return (i == 6);
|
||
|
}
|
||
|
|
||
|
|
||
|
#if defined(__RTOS__) && defined(HGIC_SMAC)
|
||
|
int umac_config_read(const char *name, char *buff, int size)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct umac_config *cfg = sys_get_umaccfg();
|
||
|
struct net_device *ndev = net_device_get_by_name(name);
|
||
|
|
||
|
if (ndev == NULL) {
|
||
|
PRINTF("dev:%s is not exist!\r\n", name);
|
||
|
return -1;
|
||
|
}
|
||
|
if (ndev->ifindex == 0) {
|
||
|
strcpy(buff, (const char *)cfg->hg0);
|
||
|
buff[strlen(cfg->hg0)] = 0;
|
||
|
} else if (ndev->ifindex == 1) {
|
||
|
strcpy(buff, (const char *)cfg->hg1);
|
||
|
buff[strlen(cfg->hg1)] = 0;
|
||
|
} else {
|
||
|
ret = -1;
|
||
|
}
|
||
|
PRINTF("read %s:\r\n%s\r\n", name, buff);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int umac_config_write(const char *name, char *buff, int size)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
struct umac_config *cfg = sys_get_umaccfg();
|
||
|
struct net_device *ndev = net_device_get_by_name(name);
|
||
|
|
||
|
PRINTF("write %s:\r\n%s\r\n", name, buff);
|
||
|
if (ndev == NULL) {
|
||
|
PRINTF("dev:%s is not exist!\r\n", name);
|
||
|
return -1;
|
||
|
}
|
||
|
if ((ndev->ifindex == 0) && size < sizeof(cfg->hg0)) {
|
||
|
strcpy((char *)cfg->hg0, buff);
|
||
|
} else if ((ndev->ifindex == 1) && size < sizeof(cfg->hg1)) {
|
||
|
strcpy((char *)cfg->hg1, buff);
|
||
|
} else {
|
||
|
ret = -1;
|
||
|
}
|
||
|
if (!ret) {
|
||
|
ret = sys_save_umaccfg(cfg);
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
#endif
|