1779 lines
48 KiB
C
Executable File
1779 lines
48 KiB
C
Executable File
/*
|
|
* AutoPVC.c
|
|
*
|
|
* Created on: Mar 4, 2009
|
|
* Author: krammer
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/atmdev.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <asm/tc3162/tc3162.h>
|
|
#include <asm/tc3162/cmdparse.h>
|
|
#include "tsarm.h"
|
|
#include "autoPVC.h"
|
|
#include "aal5.h"
|
|
|
|
#define ALIGN32BYTESBASE 32
|
|
#define AAL5_CELL_BUFFER_SIZE 1024
|
|
#define PROBE_PKT_SIZE 1024
|
|
|
|
|
|
/* Pseudo-header for TCP and UDP checksumming */
|
|
typedef struct {
|
|
int32 source; /* IP source */
|
|
int32 dest; /* IP destination */
|
|
uint8 protocol; /* Protocol */
|
|
uint16 length; /* Data field length */
|
|
} pseudohdr_t;
|
|
|
|
/*extern function*/
|
|
extern int subcmd(const cmds_t tab[], int argc, char *argv[], void *p);
|
|
extern int autopvc_cmd_register_to_sys(cmds_t *cmds_p);
|
|
extern int autopvc_cmd_unregister_to_sys(void);
|
|
extern uint8 atmCcDataReq(uint8 *data_p);
|
|
extern void delay1ms(int ms);
|
|
extern uint32 align32Byte(uint32 addr);
|
|
extern void dumpCell(uint8* src, int len);
|
|
/*extern function*/
|
|
|
|
/*function declare*/
|
|
void vcPoolControlCC(uint8 flag);
|
|
#if !defined(TCSUPPORT_CPU_MT7510)
|
|
void clearTxCcDescrPool(void);
|
|
#endif
|
|
|
|
/*global data*/
|
|
uint32 g_manageFlag=0;
|
|
uint32 g_vcPoolProbeService=0;
|
|
vc_pool_t g_pvc_pool[MAX_PVC_NUM];
|
|
vc_pool_t g_vc_pool[MAX_VC_POOL_NUM];
|
|
uint8 g_pcmac_addr[6], fin = 0;
|
|
int g_vcHuntSet=0;
|
|
static spinlock_t autopvcLock;
|
|
cmds_t vcPoolCmd;
|
|
#if !defined(TCSUPPORT_CPU_MT7510)
|
|
static int tx_raw_flag;
|
|
extern atmTxCcDescrPool_t *atmTxCcDescrPool;
|
|
#else
|
|
int tx_raw_flag;
|
|
#endif
|
|
|
|
uint8 *AAL5_CELL;
|
|
unsigned int vpi_detected, vci_detected, encap_detected, service_detected;
|
|
|
|
static uint8 RFC1483_LLC_HDR[] = {
|
|
0xaa, 0xaa, 0x03, 0x00, 0x80, 0xc2, 0x00, 0x07, 0x00, 0x00
|
|
};
|
|
static uint8 RFC1483_LLC_FCS_HDR[] = {
|
|
0xaa, 0xaa, 0x03, 0x00, 0x80, 0xc2, 0x00, 0x01, 0x00, 0x00
|
|
};
|
|
static uint8 PPPOE_PADO[] = {
|
|
0x88, 0x63, 0x11, 0x07, 0x00, 0x00
|
|
};
|
|
static uint8 RFC1483_VC_HDR[] = {
|
|
0x00, 0x00
|
|
};
|
|
//static uint8 PPPOA_LLC_HDR[] = {
|
|
// 0xfe, 0xfe, 0x03, 0xcf, 0xc0, 0x21
|
|
//};
|
|
//static uint8 PPPOA_VC_HDR[] = {
|
|
// 0xc0, 0x21
|
|
//};
|
|
|
|
static uint8 PADI_PPPOE[] = {
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xaa, 0xbb, 0x01, 0x23, 0x45, 0x88, 0x63, 0x11, 0x09,
|
|
0x00, 0x00, 0x00, 0x0c, 0x01, 0x01, 0x00, 0x00, 0x01, 0x03, 0x00, 0x04, 0x31, 0x30, 0x30, 0x30,
|
|
0x08, 0x00, 0x45, 0x00, 0x02, 0x28, 0x13, 0xf5, 0x40, 0x00, 0x80, 0x06, 0x61, 0x68, 0xc0, 0xa8,
|
|
0x01, 0x21, 0xc0, 0xa8, 0x01, 0x01, 0x05, 0xcc, 0x00, 0x14, 0x2a, 0x31, 0x0a, 0x30, 0xff, 0x78
|
|
};
|
|
/*global data*/
|
|
/*crc_L2autopvc*/
|
|
|
|
#include "crc.h"
|
|
|
|
/******************************************************************************
|
|
* Macros (This is used to speedup code in the calc_crc first while loop)
|
|
******************************************************************************/
|
|
|
|
#define DO1(c, crc) ((crc) = crc32tab[((unsigned int)((crc)>>24) ^ (*c++)) & 0xff] ^ ((crc) << 8))
|
|
#define DO2(c, crc) DO1(c, crc); DO1(c, crc);
|
|
#define DO4(c, crc) DO2(c, crc); DO2(c, crc);
|
|
#define DO8(c, crc) DO4(c, crc); DO4(c, crc);
|
|
|
|
|
|
/******************************************************************************
|
|
* Precomputed AAL5 CRC32 lookup table
|
|
******************************************************************************/
|
|
|
|
static unsigned long crc32tab[256] = {
|
|
|
|
0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
|
|
0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
|
|
0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L,
|
|
0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL,
|
|
0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L,
|
|
0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L,
|
|
0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L,
|
|
0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL,
|
|
0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L,
|
|
0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L,
|
|
0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L,
|
|
0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL,
|
|
0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L,
|
|
0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L,
|
|
0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L,
|
|
0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL,
|
|
0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL,
|
|
0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L,
|
|
0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L,
|
|
0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL,
|
|
0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL,
|
|
0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L,
|
|
0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L,
|
|
0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL,
|
|
0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL,
|
|
0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L,
|
|
0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L,
|
|
0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL,
|
|
0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL,
|
|
0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L,
|
|
0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L,
|
|
0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL,
|
|
0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L,
|
|
0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL,
|
|
0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL,
|
|
0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L,
|
|
0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L,
|
|
0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL,
|
|
0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL,
|
|
0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L,
|
|
0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L,
|
|
0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL,
|
|
0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL,
|
|
0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L,
|
|
0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L,
|
|
0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL,
|
|
0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL,
|
|
0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L,
|
|
0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L,
|
|
0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL,
|
|
0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L,
|
|
0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L,
|
|
0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L,
|
|
0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL,
|
|
0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L,
|
|
0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L,
|
|
0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L,
|
|
0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL,
|
|
0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L,
|
|
0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L,
|
|
0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L,
|
|
0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL,
|
|
0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
|
|
0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
|
|
|
|
};
|
|
|
|
/******************************************************************************
|
|
* Precomputed ATM CRC8 lookup table
|
|
******************************************************************************/
|
|
|
|
unsigned char hec_table[256]=
|
|
{
|
|
|
|
0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15,
|
|
0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,
|
|
0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
|
|
0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,
|
|
0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5,
|
|
0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
|
|
0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85,
|
|
0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,
|
|
0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
|
|
0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,
|
|
0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2,
|
|
0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
|
|
0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32,
|
|
0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,
|
|
0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
|
|
0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
|
|
0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c,
|
|
0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
|
|
0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec,
|
|
0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,
|
|
0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
|
|
0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,
|
|
0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c,
|
|
0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
|
|
0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b,
|
|
0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,
|
|
0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
|
|
0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,
|
|
0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb,
|
|
0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
|
|
0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb,
|
|
0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3
|
|
|
|
};
|
|
|
|
static uint8 DHCP_DISCOVER[] = {
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1c, 0xda, 0x29, 0x4b, 0x08, 0x00, 0x45, 0x00,
|
|
0x01, 0x48, 0x00, 0x0a, 0x00, 0x00, 0x80, 0x11, 0x39, 0x9c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
|
0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, 0xe4, 0x81, 0x01, 0x01, 0x06, 0x00, 0x5b, 0xec,
|
|
0xd7, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xda, 0x29, 0x4b, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x01, 0x74, 0x01, 0x01,
|
|
0x3d, 0x07, 0x01, 0x00, 0x00, 0x1c, 0xda, 0x29, 0x4b, 0x0c, 0x0f, 0x74, 0x63, 0x2d, 0x65, 0x34,
|
|
0x66, 0x36, 0x65, 0x64, 0x32, 0x66, 0x35, 0x62, 0x38, 0x37, 0x3c, 0x08, 0x4d, 0x53, 0x46, 0x54,
|
|
0x20, 0x35, 0x2e, 0x30, 0x37, 0x0b, 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, 0x21, 0xf9,
|
|
0x2b, 0xff, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
static uint16
|
|
get16(
|
|
uint8 *cp
|
|
)
|
|
{
|
|
register uint16 x;
|
|
|
|
x = *cp++;
|
|
x <<= 8;
|
|
x |= *cp;
|
|
return x;
|
|
} /* get16 */
|
|
|
|
static uint32
|
|
get32 (
|
|
uint8 *cp
|
|
)
|
|
{
|
|
uint32 rval;
|
|
|
|
rval = *cp++;
|
|
rval <<= 8;
|
|
rval |= *cp++;
|
|
rval <<= 8;
|
|
rval |= *cp++;
|
|
rval <<= 8;
|
|
rval |= *cp;
|
|
|
|
return rval;
|
|
} /* get32 */
|
|
|
|
static uint8 *
|
|
put32(
|
|
uint8 *cp,
|
|
uint32 x
|
|
)
|
|
{
|
|
*cp++ = x >> 24;
|
|
*cp++ = x >> 16;
|
|
*cp++ = x >> 8;
|
|
*cp++ = x;
|
|
return cp;
|
|
} /* put32 */
|
|
|
|
static uint8 *
|
|
put16(
|
|
uint8 *cp,
|
|
uint16 x
|
|
)
|
|
{
|
|
*cp++ = x >> 8;
|
|
*cp++ = x;
|
|
|
|
return cp;
|
|
} /* put16 */
|
|
|
|
/*
|
|
* Function : aal5_calc_crc
|
|
* Return Value : crc calculated for the given buffer ( needs to be xor'ed)
|
|
* Description : none
|
|
*/
|
|
|
|
unsigned int aal5_calc_crc(unsigned char *mem, int len, unsigned int initial)
|
|
{
|
|
|
|
register unsigned int crc;
|
|
|
|
crc = initial;
|
|
|
|
while( len >= 8) {
|
|
DO8(mem, crc);
|
|
len -= 8;
|
|
}
|
|
|
|
while( len ) {
|
|
DO1(mem, crc);
|
|
len--;
|
|
}
|
|
|
|
return(crc);
|
|
|
|
}
|
|
|
|
unsigned char atm_calc_hec(unsigned char *header)
|
|
{
|
|
|
|
register unsigned char hec,i;
|
|
|
|
hec = 0;
|
|
|
|
for(i=0; i<4; i++)
|
|
hec = hec_table[hec^header[i]];
|
|
|
|
return(hec^ATM_HEADER_COSET_LEADER);
|
|
|
|
}
|
|
|
|
/*crc_L2autopvc*/
|
|
|
|
/*aal5*/
|
|
/*
|
|
* Function : atm_header_create
|
|
* Return value : none
|
|
* Description : Creates an atm cell header to (vpi, vci, pti, clp)
|
|
*/
|
|
|
|
void atm_header_create(unsigned char *header, int vpi, int vci, int pti, int clp)
|
|
{
|
|
|
|
/*
|
|
* ATM UNI cell header
|
|
*
|
|
* 8 7 6 5 4 3 2 1
|
|
* *************************************************
|
|
* * GFC * VPI *
|
|
* *************************************************
|
|
* * (VPI) * *
|
|
* *********************** *
|
|
* * VCI *
|
|
* * ***************************
|
|
* * * PTI * CLP *
|
|
* *************************************************
|
|
* * Header CRC *
|
|
* *************************************************
|
|
*
|
|
*/
|
|
|
|
vpi &= 0x000000ff;
|
|
vci &= 0x0000ffff;
|
|
pti &= 0x00000007;
|
|
clp &= 0x00000001;
|
|
|
|
header[0] = (vpi >> 4);
|
|
header[1] = (vpi << 4) | (vci >> 12);
|
|
header[2] = (vci & 0x00000ff0) >> 4;
|
|
header[3] = ((vci & 0x0000000f) << 4) | (pti << 1) | clp;
|
|
#if 0
|
|
#ifdef DEBUG
|
|
header[4] = atm_calc_hec(header);
|
|
#else
|
|
header[4] = 0xec; /* Arbitrary constant */
|
|
#endif
|
|
#endif
|
|
|
|
}
|
|
|
|
void atm_cell_create_with_header(unsigned char *cell, unsigned char *data, unsigned char *header)
|
|
{
|
|
|
|
memcpy(cell + ATM_CELL_HEADER_SIZE, data, ATM_CELL_DATA_SIZE);
|
|
memcpy(cell, header, ATM_CELL_HEADER_SIZE);
|
|
|
|
}
|
|
|
|
/*
|
|
* Function : aal5_frame_to_atm_cells
|
|
* Return value : -1 if the aal5 frame is not recognized (its length is not %48)
|
|
* or atm cell buffer size
|
|
* Description : given an aal5 frame, build an atm cell queue
|
|
*/
|
|
|
|
int aal5_frame_to_atm_cells(unsigned char *atm_cells, unsigned char *aal5_frame, int length, int vpi, int vci)
|
|
{
|
|
|
|
unsigned char *src, *dst;
|
|
unsigned char header[5];
|
|
unsigned int cells;
|
|
|
|
if(length%ATM_CELL_DATA_SIZE)
|
|
return(-1);
|
|
|
|
cells = length/ATM_CELL_DATA_SIZE - 1;
|
|
|
|
|
|
/*
|
|
* We will write atm cells from last to first
|
|
* This allow us to use the same buffer for src and dst
|
|
* This cell must have pti = 1 to mark end af the aal5 frame
|
|
*/
|
|
|
|
src = aal5_frame + ATM_CELL_DATA_SIZE *cells;
|
|
dst = atm_cells + ATM_CELL_TOTAL_SIZE*cells;
|
|
atm_header_create(header, vpi, vci, 1, 0);
|
|
|
|
atm_cell_create_with_header(dst, src, header);
|
|
|
|
/* (Re)Create the header */
|
|
atm_header_create(header, vpi, vci, 0, 0);
|
|
|
|
/* Build all the other cells */
|
|
while(cells--) {
|
|
|
|
src -= ATM_CELL_DATA_SIZE;
|
|
dst -= ATM_CELL_TOTAL_SIZE;
|
|
atm_cell_create_with_header(dst, src, header);
|
|
|
|
}
|
|
|
|
return((length/ATM_CELL_DATA_SIZE) * ATM_CELL_TOTAL_SIZE);
|
|
|
|
}
|
|
|
|
/*aal5*/
|
|
|
|
|
|
//int
|
|
//vcPoolProbeVcOamRx(
|
|
// uint8 vpi_in,
|
|
// uint16 vci_in
|
|
//)
|
|
//{
|
|
// uint8 vpi;
|
|
// uint16 vci;
|
|
// int i;
|
|
//
|
|
//// if (!(vcPoolProbeService & PROBE_OAM))
|
|
//// return 0;
|
|
//
|
|
// /* check if it is remote node's vpi/vci */
|
|
// vpi = spSysParam.remoteNode[0].atmPf.vpiBrdg;
|
|
// vci = spSysParam.remoteNode[0].atmPf.vciBrdg;
|
|
// if ((vpi_in == vpi) && (vci_in == vci)) {
|
|
// VCPOOL_DBG_B("\r\n probe VC RX remote node vpi=", vpi);
|
|
// VCPOOL_DBG_W(" vci=", vci);
|
|
// vcPoolManageFlag |= VC_HUNT_FLAG_MANG_STOP;
|
|
// return 0;
|
|
// }
|
|
//
|
|
// for (i = 0; i < spSysParam.nVCHuntSet; i++) {
|
|
// vpi = vcPoolSet[i].vpi;
|
|
// vci = vcPoolSet[i].vci;
|
|
// if (vci == 0)
|
|
// continue;
|
|
// if ((vpi_in == vpi) && (vci_in == vci)) {
|
|
// vcPoolSet[i].flags |= VC_HUNT_FLAG_HUNT_SUCC;
|
|
// return 1;
|
|
// }
|
|
// }
|
|
// return 0;
|
|
//}
|
|
|
|
|
|
/*______________________________________________________________________________
|
|
** RawCcCellRecv
|
|
**
|
|
** descriptions:check header
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** 1 yes
|
|
** 0 no
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
void RawCcCellRecv(uint8 * cellp)
|
|
{
|
|
atmOamCell_t *oamCellp;
|
|
// uint32 aal5Len;
|
|
// int i;
|
|
// uint8 * data_p;
|
|
uint8 *cp;
|
|
#if 1
|
|
int ihl;
|
|
uint8 protocol, ETHER_TYPE_IP[2] = {0x08, 0x00};
|
|
uint16 src_port, dst_port;
|
|
#endif
|
|
uint8 chk;
|
|
uint16 flags;
|
|
uint8 /*vpi,*/ vpi_in;
|
|
uint16 /*vci,*/ vci_in;
|
|
int encap=0,i=0;
|
|
int vcHuntSetNumber=0;
|
|
vc_pool_t *pTmpVcPool=NULL;
|
|
|
|
// if ( !(g_manageFlag & VC_HUNT_FLAG_MANG_START)) {
|
|
// return;
|
|
// }
|
|
|
|
if(g_vcHuntSet == HUNT_PVC){
|
|
vcHuntSetNumber=MAX_PVC_NUM;
|
|
pTmpVcPool=g_pvc_pool;
|
|
}
|
|
else if(g_vcHuntSet == HUNT_VCPOOL){
|
|
vcHuntSetNumber=MAX_VC_POOL_NUM;
|
|
pTmpVcPool=g_vc_pool;
|
|
}
|
|
|
|
oamCellp = (atmOamCell_t *) cellp;
|
|
if ((oamCellp->vci == 3) || (oamCellp->vci == 4)){
|
|
printk("discard oam cell...\n");
|
|
return;
|
|
}
|
|
|
|
vpi_in = oamCellp->vpi;
|
|
vci_in = oamCellp->vci;
|
|
|
|
// if(g_vcHuntSet == HUNT_PVC){
|
|
// for(i=0;i<MAX_PVC_NUM;i++){
|
|
// if((vpi_in == g_pvc_pool[i].vpi)&&(vci_in == g_pvc_pool[i].vci)){
|
|
// break;
|
|
// }
|
|
// }
|
|
// encap=g_pvc_pool[i].encap;
|
|
// }
|
|
// else{
|
|
// encap=g_encap;
|
|
// }
|
|
for(i=0;i<vcHuntSetNumber;i++){
|
|
if((vpi_in == pTmpVcPool[i].vpi)&&(vci_in == pTmpVcPool[i].vci)){
|
|
break;
|
|
}
|
|
}
|
|
encap=pTmpVcPool[i].encap;
|
|
|
|
flags = 0;
|
|
#if 1
|
|
if (g_vcPoolProbeService & PROBE_DHCP) {
|
|
cp = &cellp[4];
|
|
chk = 0;
|
|
/* check if RFC1483 LLC header */
|
|
if(!encap){
|
|
if (memcmp(cp, RFC1483_LLC_HDR, sizeof(RFC1483_LLC_HDR)) == 0 ||
|
|
memcmp(cp, RFC1483_LLC_FCS_HDR, sizeof(RFC1483_LLC_FCS_HDR)) == 0) {
|
|
cp += sizeof(RFC1483_LLC_HDR);
|
|
chk = 1;
|
|
}
|
|
}
|
|
else{
|
|
if (memcmp(cp, RFC1483_VC_HDR, sizeof(RFC1483_VC_HDR)) == 0){
|
|
cp += sizeof(RFC1483_VC_HDR);
|
|
chk = 1;
|
|
}
|
|
}
|
|
if (chk) {
|
|
/* skip ethernet mac address */
|
|
cp += 12;
|
|
/* check if IP packet */
|
|
if (memcmp(cp, ETHER_TYPE_IP, sizeof(ETHER_TYPE_IP)) == 0) {
|
|
printk("ETHER_TYPE_IP\r\n");
|
|
cp += sizeof(ETHER_TYPE_IP);
|
|
protocol = *(cp + 9);
|
|
/* check if UDP protocol */
|
|
if (protocol == 0x11) {
|
|
printk("protocol == 0x11\r\n");
|
|
/* skip ip header */
|
|
ihl = (*cp & 0xf) << 2;
|
|
cp += ihl;
|
|
src_port = get16(cp);
|
|
dst_port = get16(cp + 2);
|
|
printk("src_port = 0x%X, dst_port = 0x%X\r\n", src_port, dst_port);
|
|
/* check if DHCP packet */
|
|
if ((src_port == 0x43) && (dst_port == 0x44)){
|
|
// VCPOOL_DBG("\r\n *****CC dhcp back *****");
|
|
flags |= PROBE_DHCP;
|
|
goto find;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
#endif
|
|
if (g_vcPoolProbeService & PROBE_PPPOE) {
|
|
cp = &cellp[4];
|
|
chk = 0;
|
|
/* check if RFC1483 LLC header */
|
|
if(!encap){
|
|
if (memcmp(cp, RFC1483_LLC_HDR, sizeof(RFC1483_LLC_HDR)) == 0 ||
|
|
memcmp(cp, RFC1483_LLC_FCS_HDR, sizeof(RFC1483_LLC_FCS_HDR)) == 0) {
|
|
cp += sizeof(RFC1483_LLC_HDR);
|
|
chk = 1;
|
|
}
|
|
}
|
|
else{
|
|
if (memcmp(cp, RFC1483_VC_HDR, sizeof(RFC1483_VC_HDR)) == 0) {
|
|
cp += sizeof(RFC1483_VC_HDR);
|
|
chk = 1;
|
|
}
|
|
}
|
|
if (chk) {
|
|
/* skip ethernet mac address */
|
|
cp += 12;
|
|
/* check PPPoE PADO packet */
|
|
if (memcmp(cp, PPPOE_PADO, sizeof(PPPOE_PADO)) == 0) {
|
|
flags |= PROBE_PPPOE;
|
|
goto find;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if( vcPoolProbeService & PROBE_ARP){
|
|
// cp = &cellp[4];
|
|
// chk = 0;
|
|
// /* check if RFC1483 LLC header */
|
|
// if (memcmp(cp, RFC1483_LLC_HDR, sizeof(RFC1483_LLC_HDR)) == 0 ||
|
|
// memcmp(cp, RFC1483_LLC_FCS_HDR, sizeof(RFC1483_LLC_FCS_HDR)) == 0) {
|
|
// cp += sizeof(RFC1483_LLC_HDR);
|
|
// chk = 1;
|
|
// }
|
|
// /* check dst ethernet mac address */
|
|
// if( (chk == 1) && (memcmp(cp, pcmac_addr, sizeof(pcmac_addr)) == 0) ){
|
|
// //printf("is my mac\n");
|
|
// chk =2;
|
|
// }
|
|
// if( chk == 2){
|
|
// cp += 12;
|
|
// /* check if ARP packet */
|
|
// if (memcmp(cp, ETHER_TYPE_ARP, sizeof(ETHER_TYPE_ARP)) == 0) {
|
|
// VCPOOL_DBG("\r\n ******* CC arp back! *******");
|
|
// flags |= PROBE_ARP;
|
|
// goto find;
|
|
// }
|
|
// }
|
|
// }
|
|
find:
|
|
if(flags){
|
|
vcPoolProbeVcPktRx(vpi_in,vci_in);
|
|
}
|
|
|
|
}
|
|
|
|
/*______________________________________________________________________________
|
|
** vcPoolProbeVcPktRx
|
|
**
|
|
** descriptions:check if the vci and vci is in our vcpool!
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** 1 yes
|
|
** 0 no
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
int
|
|
vcPoolProbeVcPktRx(
|
|
uint8 vpi_in,
|
|
uint16 vci_in
|
|
// struct sk_buff *bp
|
|
)
|
|
{
|
|
uint8 vpi=0;
|
|
uint16 vci=0;
|
|
int i;
|
|
int vcHuntSetNumber=0;
|
|
vc_pool_t *pTmpVcPool=NULL;
|
|
vpi_detected = vpi_in;
|
|
vci_detected = vci_in;
|
|
service_detected = g_vcPoolProbeService;
|
|
encap_detected = g_vc_pool[0].encap;
|
|
|
|
//g_manageFlag &= ~VC_HUNT_FLAG_MANG_START;
|
|
//vcPoolControlCC(0);
|
|
//clearTxCcDescrPool();
|
|
//fin = 1;
|
|
|
|
if(g_vcHuntSet == HUNT_PVC){
|
|
vcHuntSetNumber=MAX_PVC_NUM;
|
|
pTmpVcPool=g_pvc_pool;
|
|
}
|
|
else if(g_vcHuntSet == HUNT_VCPOOL){
|
|
vcHuntSetNumber=MAX_VC_POOL_NUM;
|
|
pTmpVcPool=g_vc_pool;
|
|
}
|
|
|
|
|
|
for (i = 0; i < vcHuntSetNumber; i++) {
|
|
vpi=pTmpVcPool[i].vpi;
|
|
vci=pTmpVcPool[i].vci;
|
|
if (vci == 0){
|
|
continue;
|
|
}
|
|
if ((vpi_in == vpi) && (vci_in == vci) ) {
|
|
pTmpVcPool[i].management |= VC_HUNT_FLAG_HUNT_SUCC;
|
|
return 1;
|
|
}
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#if 0
|
|
/*______________________________________________________________________________
|
|
** sarAAL5RxComplete
|
|
**
|
|
** descriptions:check the vci and vci , if is in our vcpool, free it!
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
void
|
|
sarAAL5RxComplete(
|
|
struct sk_buff *bp,
|
|
uint8 vpi,
|
|
uint16 vci
|
|
)
|
|
{
|
|
if (vcPoolProbeVcPktRx(vpi, vci)) {
|
|
dev_kfree_skb_any(bp);
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*______________________________________________________________________________
|
|
** setTxRaw
|
|
**
|
|
** descriptions:set tx_raw enable
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
void
|
|
setTxRaw(atmTxCcDescr_t * atmTxCcDescrp){
|
|
if(tx_raw_flag){
|
|
atmTxCcDescrp->tdes0 |= TSARM_TX_RAW_EN;
|
|
}
|
|
}
|
|
|
|
/*______________________________________________________________________________
|
|
** vcPoolControlCC
|
|
**
|
|
** descriptions:set cc channel control register
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
void vcPoolControlCC(uint8 flag)
|
|
{
|
|
if(flag){
|
|
TSARM_GFR |= GFR_ACTIVE_MIS;
|
|
TSARM_GFR &= ~(GFR_RX_INACT_VC_M);
|
|
}
|
|
else{
|
|
TSARM_GFR &= ~(GFR_ACTIVE_MIS);
|
|
TSARM_GFR |= GFR_RX_INACT_VC_M;
|
|
}
|
|
}
|
|
|
|
/*______________________________________________________________________________
|
|
** vcPoolSendPkt
|
|
**
|
|
** descriptions:transform packet to atmcell and send to cc channel
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
int
|
|
vcPoolSendPkt(
|
|
uint8 *pProbePkt,
|
|
int size,
|
|
uint8 vpi,
|
|
uint16 vci
|
|
)
|
|
{
|
|
// unsigned char *pCell;
|
|
unsigned int crc;
|
|
unsigned int total_length;
|
|
int cell_totallen;
|
|
int cellnum;
|
|
int /*i,*/ j;
|
|
// int i_state;
|
|
atmOamCell_t *oamCellp;
|
|
uint32 flags;
|
|
|
|
total_length = ATM_CELL_DATA_SIZE * ((size + 8 + ATM_CELL_DATA_SIZE - 1) / ATM_CELL_DATA_SIZE);
|
|
memset(pProbePkt + size, 0, total_length - size);
|
|
|
|
pProbePkt[total_length - 6] = (size & 0x0000ff00)>>8;
|
|
pProbePkt[total_length - 5] = (size & 0x000000ff);
|
|
|
|
crc = ~ aal5_calc_crc(pProbePkt, total_length - 4, ~0);
|
|
|
|
pProbePkt[total_length - 4] = (crc & 0xff000000)>>24;
|
|
pProbePkt[total_length - 3] = (crc & 0x00ff0000)>>16;
|
|
pProbePkt[total_length - 2] = (crc & 0x0000ff00)>> 8;
|
|
pProbePkt[total_length - 1] = (crc & 0x000000ff);
|
|
|
|
/* aal5 frame to atm cell */
|
|
cell_totallen = aal5_frame_to_atm_cells(AAL5_CELL, pProbePkt, total_length, vpi, vci);
|
|
cellnum = cell_totallen / ATM_CELL_TOTAL_SIZE;
|
|
|
|
/* send raw data out */
|
|
// oamCellp = (atmOamCell_t *)(CACHE_TO_NONCACHE(AAL5_CELL));
|
|
oamCellp = (atmOamCell_t *)(AAL5_CELL);
|
|
|
|
// for (i = 0; i < 1; i++) { // send pkt for 2 times
|
|
for( j=0; j<cellnum; j++){
|
|
// i_state = dirps();
|
|
spin_lock_irqsave(&autopvcLock, flags);
|
|
tx_raw_flag=1;
|
|
atmCcDataReq((uint8 *)oamCellp/*, 1*/);
|
|
tx_raw_flag=0;
|
|
spin_unlock_irqrestore(&autopvcLock, flags);
|
|
// restore(i_state);
|
|
oamCellp++;
|
|
}
|
|
delay1ms(10);
|
|
// }
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*______________________________________________________________________________
|
|
** vcPoolProbeVcWithPADI
|
|
**
|
|
** descriptions:send probe packet with padi
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
void
|
|
vcPoolProbeVcWithPADI(uint8 vpi, uint16 vci, int encap)
|
|
{
|
|
uint8 *pProbePkt;
|
|
uint8 *my_mac = NULL;
|
|
int i;
|
|
|
|
pProbePkt=kmalloc(PROBE_PKT_SIZE, GFP_KERNEL);
|
|
if(pProbePkt == NULL){
|
|
printk("Error:in %s ,can't allocate a buffer for probe packet, so stop this probe\n",__func__);
|
|
return;
|
|
}
|
|
my_mac = g_pcmac_addr;
|
|
|
|
if (g_vcPoolProbeService & PROBE_PPPOE) {
|
|
/* send pppoe llc probe packet */
|
|
memset(pProbePkt, 0, PROBE_PKT_SIZE);
|
|
if(!encap){//llc
|
|
memcpy(pProbePkt, RFC1483_LLC_HDR, sizeof(RFC1483_LLC_HDR));
|
|
memcpy(pProbePkt + sizeof(RFC1483_LLC_HDR), PADI_PPPOE, sizeof(PADI_PPPOE));
|
|
memcpy(pProbePkt + sizeof(RFC1483_LLC_HDR) + 6, my_mac, 6);
|
|
vcPoolSendPkt(pProbePkt, sizeof(RFC1483_LLC_HDR) + sizeof(PADI_PPPOE), vpi, vci);
|
|
vcPoolSendPkt(pProbePkt, sizeof(RFC1483_LLC_HDR) + sizeof(PADI_PPPOE), vpi, vci);
|
|
}
|
|
else{
|
|
memcpy(pProbePkt, RFC1483_VC_HDR, sizeof(RFC1483_VC_HDR));
|
|
memcpy(pProbePkt + sizeof(RFC1483_VC_HDR), PADI_PPPOE, sizeof(PADI_PPPOE));
|
|
memcpy(pProbePkt + sizeof(RFC1483_VC_HDR) + 6, my_mac, 6);
|
|
vcPoolSendPkt(pProbePkt, sizeof(RFC1483_VC_HDR) + sizeof(PADI_PPPOE), vpi, vci);
|
|
vcPoolSendPkt(pProbePkt, sizeof(RFC1483_VC_HDR) + sizeof(PADI_PPPOE), vpi, vci);
|
|
}
|
|
}
|
|
kfree(pProbePkt);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* Extract a short from a long */
|
|
#define hiword(x) ((uint16)((x) >> 16))
|
|
#define loword(x) ((uint16)(x))
|
|
|
|
static uint16 in_cksum(pseudohdr_t *pseudohdr, uint16 *ptr, int nbytes)
|
|
{
|
|
register int32 sum; /* assumes long == 32 bits */
|
|
uint16 oddbyte;
|
|
register uint16 answer; /* assumes u_short == 16 bits */
|
|
|
|
/*
|
|
* Our algorithm is simple, using a 32-bit accumulator (sum),
|
|
* we add sequential 16-bit words to it, and at the end, fold back
|
|
* all the carry bits from the top 16 bits into the lower 16 bits.
|
|
*/
|
|
|
|
sum = 0;
|
|
|
|
/* Sum pseudo-header, if present */
|
|
if(pseudohdr != NULL){
|
|
sum = hiword(pseudohdr->source);
|
|
sum += loword(pseudohdr->source);
|
|
sum += hiword(pseudohdr->dest);
|
|
sum += loword(pseudohdr->dest);
|
|
sum += pseudohdr->protocol;
|
|
sum += pseudohdr->length;
|
|
}
|
|
|
|
while (nbytes > 1) {
|
|
sum += *ptr++;
|
|
nbytes -= 2;
|
|
}
|
|
|
|
/* mop up an odd byte, if necessary */
|
|
if (nbytes == 1) {
|
|
oddbyte = 0; /* make sure top half is zero */
|
|
*((u_char *) &oddbyte) = *(u_char *)ptr; /* one byte only */
|
|
sum += oddbyte;
|
|
}
|
|
|
|
/*
|
|
* Add back carry outs from top 16 bits to low 16 bits.
|
|
*/
|
|
|
|
sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */
|
|
sum += (sum >> 16); /* add carry */
|
|
answer = ~sum; /* ones-complement, then truncate to 16 bits */
|
|
return(answer);
|
|
}
|
|
|
|
int
|
|
vcPoolSendOnePkt(
|
|
uint8 *pProbePkt,
|
|
int size,
|
|
uint8 vpi,
|
|
uint16 vci
|
|
)
|
|
{
|
|
|
|
unsigned char *pCell;
|
|
unsigned int crc;
|
|
unsigned int total_length;
|
|
int cell_totallen;
|
|
int cellnum;
|
|
int i, j, n;
|
|
int i_state;
|
|
atmOamCell_t *oamCellp;
|
|
uint32 flags;
|
|
|
|
total_length = ATM_CELL_DATA_SIZE * ((size + 8 + ATM_CELL_DATA_SIZE - 1) / ATM_CELL_DATA_SIZE);
|
|
//printf("total_length of aal5 frame with tail is %d \n", total_length);
|
|
|
|
memset(pProbePkt + size, 0, total_length - size);
|
|
|
|
pProbePkt[total_length - 6] = (size & 0x0000ff00)>>8;
|
|
pProbePkt[total_length - 5] = (size & 0x000000ff);
|
|
|
|
crc = ~ aal5_calc_crc(pProbePkt, total_length - 4, ~0);
|
|
|
|
pProbePkt[total_length - 4] = (crc & 0xff000000)>>24;
|
|
pProbePkt[total_length - 3] = (crc & 0x00ff0000)>>16;
|
|
pProbePkt[total_length - 2] = (crc & 0x0000ff00)>> 8;
|
|
pProbePkt[total_length - 1] = (crc & 0x000000ff);
|
|
|
|
/* aal5 frame to atm cell */
|
|
cell_totallen = aal5_frame_to_atm_cells(AAL5_CELL, pProbePkt, total_length, vpi, vci);
|
|
cellnum = cell_totallen / ATM_CELL_TOTAL_SIZE;
|
|
//printf("total cell length is %d, cell number is %d \n", cell_totallen, cellnum);
|
|
|
|
/* send raw data out */
|
|
oamCellp = (atmOamCell_t *)(CACHE_TO_NONCACHE(AAL5_CELL));
|
|
|
|
for (i = 0; i < 1; i++) { // send pkt for 2 times
|
|
for( j=0; j<cellnum; j++){
|
|
#if 0 //test by zhj
|
|
if(vpi == 0 && vci == 35){
|
|
dbg_pline_1("\n ---- dhcp ---\n");
|
|
for(n=0; n<52; n++)
|
|
dbg_plineb_1(" ", *(((uint8 *)oamCellp)+n));
|
|
dbg_pline_1("\n -------\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
// i_state = dirps();
|
|
spin_lock_irqsave(&autopvcLock, flags);
|
|
tx_raw_flag=1;
|
|
atmCcDataReq((uint8 *)oamCellp/*, 1*/);
|
|
tx_raw_flag=0;
|
|
spin_unlock_irqrestore(&autopvcLock, flags);
|
|
// restore(i_state);
|
|
oamCellp++;
|
|
|
|
}
|
|
// pause(10);
|
|
delay1ms(10);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
vcPoolProbeVcWithDHCP(uint8 vpi, uint16 vci, int encap)
|
|
{
|
|
static uint16 trans_id = 0;
|
|
uint8 probePkt[670]; //should be larger than 656 jianli 060727
|
|
uint8 *pProbePkt;
|
|
uint8 *my_mac = NULL;
|
|
pseudohdr_t pseudohdr;
|
|
int i;
|
|
|
|
pProbePkt = probePkt;
|
|
my_mac = g_pcmac_addr;
|
|
|
|
if (g_vcPoolProbeService & PROBE_DHCP) {
|
|
/* send dhcp req llc probe packet */
|
|
memset(pProbePkt, 0, sizeof(probePkt));
|
|
if(!encap){
|
|
memcpy(pProbePkt, RFC1483_LLC_HDR, sizeof(RFC1483_LLC_HDR));
|
|
// if (vcPoolProbeDHCPDiscover) {
|
|
if(1){
|
|
memcpy(pProbePkt + sizeof(RFC1483_LLC_HDR), DHCP_DISCOVER, sizeof(DHCP_DISCOVER));
|
|
/* SA */
|
|
memcpy(pProbePkt + 10 + 6, my_mac, 6);
|
|
/* client hardware address */
|
|
memcpy(pProbePkt + 10 + 70, my_mac, 6);
|
|
/* client identifier */
|
|
memcpy(pProbePkt + 10 + 291, my_mac, 6);
|
|
|
|
memset(pProbePkt + 10 + 24, 0, 2);
|
|
put16(pProbePkt + 10 + 18, get16(pProbePkt + 10 + 18) + trans_id++);
|
|
put16(pProbePkt + 10 + 24, in_cksum(NULL, (uint16 *)(pProbePkt + 10 + 14), 20));
|
|
put32(pProbePkt + 10 + 46, get32(pProbePkt + 10 + 46) + trans_id++);
|
|
|
|
/* Clear checksum for later recalculation */
|
|
pseudohdr.source= 0x0000;
|
|
pseudohdr.dest = 0xffff;
|
|
pseudohdr.protocol = 17;
|
|
pseudohdr.length = 308;
|
|
memset(pProbePkt + 10 + 40, 0, 2);
|
|
/* If requested, recompute checksum and insert into header */
|
|
put16(pProbePkt + 10 + 40,in_cksum(&pseudohdr, (uint16 *)(pProbePkt + 10 + 34), 308));
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_LLC_HDR) + sizeof(DHCP_DISCOVER), vpi, vci);
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_LLC_HDR) + sizeof(DHCP_DISCOVER), vpi, vci);
|
|
}
|
|
#if 0
|
|
else {
|
|
if (!vcPoolProbeNewDHCP) {
|
|
memcpy(pProbePkt + sizeof(RFC1483_LLC_HDR), DHCP_REQ, sizeof(DHCP_REQ));
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_LLC_HDR) + sizeof(DHCP_REQ), vpi, vci);
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_LLC_HDR) + sizeof(DHCP_REQ), vpi, vci);
|
|
} else {
|
|
memcpy(pProbePkt + sizeof(RFC1483_LLC_HDR), DHCP_REQ_NEW, sizeof(DHCP_REQ_NEW));
|
|
/* SA */
|
|
memcpy(pProbePkt + 10 + 6, my_mac, 6);
|
|
/* client hardware address */
|
|
memcpy(pProbePkt + 10 + 70, my_mac, 6);
|
|
/* client identifier */
|
|
memcpy(pProbePkt + 10 + 288, my_mac, 6);
|
|
|
|
memset(pProbePkt + 10 + 24, 0, 2);
|
|
put16(pProbePkt + 10 + 18, get16(pProbePkt + 10 + 18) + trans_id++);
|
|
put16(pProbePkt + 10 + 24, in_cksum(NULL, (uint16 *)(pProbePkt + 10 + 14), 20));
|
|
|
|
put32(pProbePkt + 10 + 46, get32(pProbePkt + 10 + 46) + trans_id++);
|
|
|
|
|
|
/* Clear checksum for later recalculation */
|
|
pseudohdr.source= 0x0000;
|
|
pseudohdr.dest = 0xffff;
|
|
pseudohdr.protocol = 17;
|
|
pseudohdr.length = 556;
|
|
memset(pProbePkt + 10 + 40, 0, 2);
|
|
/* If requested, recompute checksum and insert into header */
|
|
put16(pProbePkt + 10 + 40,in_cksum(&pseudohdr, (uint16 *)(pProbePkt + 10 + 34), 556));
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_LLC_HDR) + sizeof(DHCP_REQ_NEW), vpi, vci);
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_LLC_HDR) + sizeof(DHCP_REQ_NEW), vpi, vci);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
else{
|
|
memcpy(pProbePkt, RFC1483_VC_HDR, sizeof(RFC1483_VC_HDR));
|
|
// if (vcPoolProbeDHCPDiscover) {
|
|
if(1){
|
|
memcpy(pProbePkt + sizeof(RFC1483_VC_HDR), DHCP_DISCOVER, sizeof(DHCP_DISCOVER));
|
|
/* SA */
|
|
memcpy(pProbePkt + 10 + 6, my_mac, 6);
|
|
/* client hardware address */
|
|
memcpy(pProbePkt + 10 + 70, my_mac, 6);
|
|
/* client identifier */
|
|
memcpy(pProbePkt + 10 + 291, my_mac, 6);
|
|
|
|
memset(pProbePkt + 10 + 24, 0, 2);
|
|
put16(pProbePkt + 10 + 18, get16(pProbePkt + 10 + 18) + trans_id++);
|
|
put16(pProbePkt + 10 + 24, in_cksum(NULL, (uint16 *)(pProbePkt + 10 + 14), 20));
|
|
put32(pProbePkt + 10 + 46, get32(pProbePkt + 10 + 46) + trans_id++);
|
|
|
|
/* Clear checksum for later recalculation */
|
|
pseudohdr.source= 0x0000;
|
|
pseudohdr.dest = 0xffff;
|
|
pseudohdr.protocol = 17;
|
|
pseudohdr.length = 308;
|
|
memset(pProbePkt + 10 + 40, 0, 2);
|
|
/* If requested, recompute checksum and insert into header */
|
|
put16(pProbePkt + 10 + 40,in_cksum(&pseudohdr, (uint16 *)(pProbePkt + 10 + 34), 308));
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_VC_HDR) + sizeof(DHCP_DISCOVER), vpi, vci);
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_VC_HDR) + sizeof(DHCP_DISCOVER), vpi, vci);
|
|
}
|
|
#if 0
|
|
else {
|
|
if (!vcPoolProbeNewDHCP) {
|
|
memcpy(pProbePkt + sizeof(RFC1483_VC_HDR), DHCP_REQ, sizeof(DHCP_REQ));
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_VC_HDR) + sizeof(DHCP_REQ), vpi, vci);
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_VC_HDR) + sizeof(DHCP_REQ), vpi, vci);
|
|
} else {
|
|
memcpy(pProbePkt + sizeof(RFC1483_VC_HDR), DHCP_REQ_NEW, sizeof(DHCP_REQ_NEW));
|
|
/* SA */
|
|
memcpy(pProbePkt + 10 + 6, my_mac, 6);
|
|
/* client hardware address */
|
|
memcpy(pProbePkt + 10 + 70, my_mac, 6);
|
|
/* client identifier */
|
|
memcpy(pProbePkt + 10 + 288, my_mac, 6);
|
|
|
|
memset(pProbePkt + 10 + 24, 0, 2);
|
|
put16(pProbePkt + 10 + 18, get16(pProbePkt + 10 + 18) + trans_id++);
|
|
put16(pProbePkt + 10 + 24, in_cksum(NULL, (uint16 *)(pProbePkt + 10 + 14), 20));
|
|
|
|
put32(pProbePkt + 10 + 46, get32(pProbePkt + 10 + 46) + trans_id++);
|
|
|
|
|
|
/* Clear checksum for later recalculation */
|
|
pseudohdr.source= 0x0000;
|
|
pseudohdr.dest = 0xffff;
|
|
pseudohdr.protocol = 17;
|
|
pseudohdr.length = 556;
|
|
memset(pProbePkt + 10 + 40, 0, 2);
|
|
/* If requested, recompute checksum and insert into header */
|
|
put16(pProbePkt + 10 + 40,in_cksum(&pseudohdr, (uint16 *)(pProbePkt + 10 + 34), 556));
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_VC_HDR) + sizeof(DHCP_REQ_NEW), vpi, vci);
|
|
vcPoolSendOnePkt(pProbePkt, sizeof(RFC1483_VC_HDR) + sizeof(DHCP_REQ_NEW), vpi, vci);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
/*______________________________________________________________________________
|
|
** reset_all_data
|
|
**
|
|
** descriptions:reset all global data
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
void reset_all_data(void){
|
|
g_manageFlag=0;
|
|
g_vcPoolProbeService=0;
|
|
memset(g_pvc_pool, 0, sizeof(g_pvc_pool));
|
|
memset(g_vc_pool, 0, sizeof(g_vc_pool));
|
|
memset(g_pcmac_addr, 0, sizeof(g_pcmac_addr));
|
|
}
|
|
|
|
#if !defined(TCSUPPORT_CPU_MT7510)
|
|
/*______________________________________________________________________________
|
|
** clearTxCcDescrPool
|
|
**
|
|
** descriptions:clear tx cc descriptor pool
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
void clearTxCcDescrPool(void){
|
|
uint8 descrId;
|
|
atmTxCcDescr_t *atmTxCcDescrp;
|
|
atmTxCcDescrPool_t *atmTxCcDescrVcPoolp;
|
|
atmTxCcDescrVcPoolp = (atmTxCcDescrPool_t *)CACHE_TO_NONCACHE(atmTxCcDescrPool);
|
|
if(atmTxCcDescrPool){
|
|
for ( descrId = 0; descrId < ATM_TX_CC_DESCR_NUMMAX; descrId++ )
|
|
{
|
|
atmTxCcDescrp = atmTxCcDescrVcPoolp->txCcDescrPool+ descrId;
|
|
if ( descrId == ATM_TX_CC_DESCR_NUMMAX - 1 ) {
|
|
//BD_GAP, EOR = 1, others=0;
|
|
atmTxCcDescrp->tdes0 =TSARM_TX_DESCR_BD_GAP(TSARM_TX_CC_BD_GAP)
|
|
| TSARM_TX_DESCR_EOR;
|
|
}else{
|
|
//BD_GAP, others=0;
|
|
atmTxCcDescrp->tdes0 =TSARM_TX_DESCR_BD_GAP(TSARM_TX_CC_BD_GAP);
|
|
}
|
|
// TDES1 =0 ; Buffer length =0;
|
|
atmTxCcDescrp->tdes1 = 0x0;
|
|
// TDES2 = 0x0; buffer address = null
|
|
atmTxCcDescrp->tdes2 = 0x0;
|
|
atmTxCcDescrp->tdes3 = 0x0;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*______________________________________________________________________________
|
|
** doVcPoolActive
|
|
**
|
|
** descriptions:use to control the sar side autopvc on/off
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
int
|
|
doVcPoolActive(
|
|
int argc,
|
|
char *argv[],
|
|
void *p
|
|
)
|
|
{
|
|
|
|
int active = simple_strtoul(argv[1],NULL,10);
|
|
|
|
if ((active!=0)&&(active!=1) ) {
|
|
printk("Usage: active <1|0>\n");
|
|
return -1;
|
|
}
|
|
|
|
reset_all_data();
|
|
|
|
if (active) {
|
|
fin = 0;
|
|
g_manageFlag |= VC_HUNT_FLAG_MANG_START;
|
|
vcPoolControlCC(0);
|
|
vcPoolControlCC(1);
|
|
} else {
|
|
fin = 1;
|
|
g_manageFlag &= ~VC_HUNT_FLAG_MANG_START;
|
|
vcPoolControlCC(0);
|
|
#if !defined(TCSUPPORT_CPU_MT7510)
|
|
clearTxCcDescrPool();
|
|
#endif
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*______________________________________________________________________________
|
|
** doVcPoolSet
|
|
**
|
|
** descriptions:
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
int
|
|
doVcPoolSet(
|
|
int argc,
|
|
char *argv[],
|
|
void *p
|
|
)
|
|
{
|
|
|
|
int rnIndex;
|
|
uint8 vpi;
|
|
uint16 vci;
|
|
int encap;
|
|
int i;
|
|
vc_pool_t tmpVC;
|
|
|
|
if((argc == 8) && (memcmp(argv[1], "mac", 3) == 0)){//set mac byte0 byte1 byte2 byte3 byte4 byte5 byte6
|
|
for(i=0;i<6;i++){
|
|
g_pcmac_addr[i]=simple_strtoul(argv[i+2],NULL,16);
|
|
}
|
|
printk("\r\n");
|
|
#if 0
|
|
printk("0: vpi = %d, vci = %d\r\n", g_vc_pool[0].vpi, g_vc_pool[0].vci);
|
|
printk("1: vpi = %d, vci = %d\r\n", g_vc_pool[1].vpi, g_vc_pool[1].vci);
|
|
#endif
|
|
}
|
|
/*
|
|
* set pvc index vpi vci encap
|
|
* set vcpool index vpi vci
|
|
*/
|
|
else if(argc >= 5){ //set pvc or vcpool
|
|
rnIndex = simple_strtoul(argv[2],NULL,10);
|
|
vpi = simple_strtoul(argv[3],NULL,10);
|
|
vci = simple_strtoul(argv[4],NULL,10);
|
|
if (vci < 1) {
|
|
printk("Error: vpi:%d or vci:%d is in the wrong range\r\n",vpi,vci);
|
|
return -1;
|
|
}
|
|
|
|
if((argc == 6) && (memcmp(argv[1], "pvc", 3) == 0)){//autopvc set pvc index vpi vci encap
|
|
/* Check the remoteNode conflict or not */
|
|
#if !defined(TCSUPPORT_AUTO_PVC_TRIGGER)
|
|
for (i = 0; i < MAX_PVC_NUM; i++) {
|
|
#endif
|
|
tmpVC = g_pvc_pool[i];
|
|
if ((tmpVC.vpi == vpi) &&
|
|
(tmpVC.vci == vci)) {
|
|
printk("Error: duplicate vpi %d and vci %d in current PVC setting\n",vpi,vci);
|
|
return -1;
|
|
}
|
|
#if !defined(TCSUPPORT_AUTO_PVC_TRIGGER)
|
|
}
|
|
#endif
|
|
encap=simple_strtoul(argv[5],NULL,10);
|
|
if((encap != 0) && (encap != 1)){
|
|
printk("Error: wrong encapsulation when setting pvc pool\n");
|
|
return -1;
|
|
}
|
|
#if !defined(TCSUPPORT_AUTO_PVC_TRIGGER)
|
|
if ((rnIndex < 0) || (rnIndex > MAX_PVC_NUM -1)) {
|
|
#endif
|
|
printk("Error: wrong index when set pvc pool, %d\r\n", rnIndex);
|
|
return -1;
|
|
}
|
|
g_pvc_pool[rnIndex].vpi=vpi;
|
|
g_pvc_pool[rnIndex].vci=vci;
|
|
g_pvc_pool[rnIndex].encap=encap;
|
|
}
|
|
else if((argc == 5) && (memcmp(argv[1], "vcpool", 6) == 0)){//autopvc set vcpool index vpi vci
|
|
if (vci < 1) {
|
|
printk("Error: vpi:%d or vci:%d is in the wrong range\r\n",vpi,vci);
|
|
return -1;
|
|
}
|
|
#if 0
|
|
for (i = 0; i < MAX_VC_POOL_NUM; i++) {
|
|
tmpVC = g_vc_pool[i];
|
|
if ((tmpVC.vpi == vpi) &&
|
|
(tmpVC.vci == vci)) {
|
|
printk("Error: duplicate vpi and vci in VC pool\n");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
if ((rnIndex < 0) || (rnIndex > MAX_VC_POOL_NUM -1)) {
|
|
printk("Error: wrong index when set vcpool, %d\r\n", rnIndex);
|
|
return -1;
|
|
}
|
|
g_vc_pool[rnIndex].vpi=vpi;
|
|
g_vc_pool[rnIndex].vci=vci;
|
|
}
|
|
else{
|
|
printk("Error: autopvc set <pvc|vcpool|mac>\r\n");
|
|
}
|
|
}
|
|
else{
|
|
printk("Error: too less arguments when autopvc set\r\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*______________________________________________________________________________
|
|
** doVcPoolProbe
|
|
**
|
|
** descriptions:
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
int
|
|
doVcPoolProbe(
|
|
int argc,
|
|
char *argv[],
|
|
void *p
|
|
)
|
|
{
|
|
int vcHuntSetNumber=0;
|
|
int n=0,i=0;
|
|
uint8 vpi=0;
|
|
uint16 vci=0;
|
|
int encap=0;
|
|
vc_pool_t *pTmpVcPool=NULL;
|
|
|
|
if(memcmp(argv[1],"pvc",3) == 0){
|
|
#if !defined(TCSUPPORT_AUTO_PVC_TRIGGER)
|
|
vcHuntSetNumber=MAX_PVC_NUM;
|
|
#endif
|
|
g_vcHuntSet=HUNT_PVC;
|
|
pTmpVcPool=g_pvc_pool;
|
|
}
|
|
else if(memcmp(argv[1],"vcpool",6) == 0){
|
|
vcHuntSetNumber=MAX_VC_POOL_NUM;
|
|
g_vcHuntSet=HUNT_VCPOOL;
|
|
pTmpVcPool=g_vc_pool;
|
|
#if 0
|
|
printk("0: vpi = %d, vci = %d\r\n", g_vc_pool[0].vpi, g_vc_pool[0].vci);
|
|
printk("1: vpi = %d, vci = %d\r\n", g_vc_pool[1].vpi, g_vc_pool[1].vci);
|
|
#endif
|
|
}
|
|
|
|
for( n=0; n<SERVICE_NUMBER; n++){ // three types of pkt
|
|
for (i = 0; i < vcHuntSetNumber; i++) {
|
|
vpi=pTmpVcPool[i].vpi;
|
|
vci=pTmpVcPool[i].vci;
|
|
encap=pTmpVcPool[i].encap;
|
|
if (vci == 0)
|
|
continue;
|
|
// if ((vpi == spSysParam.remoteNode[0].atmPf.vpiBrdg) &&
|
|
// (vci == spSysParam.remoteNode[0].atmPf.vciBrdg))
|
|
// continue;
|
|
// if (L2ProbePktReady & PADI_FIRST && n==0)
|
|
// continue;
|
|
// if( n==0 && (vcPoolProbeService & PROBE_ARP))
|
|
// vcPoolProbeVcWithARP(vpi, vci);
|
|
if( n==1 && (g_vcPoolProbeService & PROBE_PPPOE)){
|
|
vcPoolProbeVcWithPADI(vpi, vci, encap);
|
|
}
|
|
#if 1
|
|
else if( n==2 && (g_vcPoolProbeService & PROBE_DHCP)){
|
|
vcPoolProbeVcWithDHCP(vpi, vci, encap);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*______________________________________________________________________________
|
|
** doVcPoolService
|
|
**
|
|
** descriptions:
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
int
|
|
doVcPoolService(
|
|
int argc,
|
|
char *argv[],
|
|
void *p
|
|
)
|
|
{
|
|
if (argc == 2) {
|
|
g_vcPoolProbeService=simple_strtoul(argv[1],NULL,16);
|
|
// return 0;
|
|
}
|
|
#if 0
|
|
printk("Probe Service Type: ");
|
|
|
|
if (g_vcPoolProbeService & PROBE_OAM)
|
|
printk("OAM ");
|
|
if (g_vcPoolProbeService & PROBE_PPPOE)
|
|
printk("PPPoE ");
|
|
|
|
if (g_vcPoolProbeService & PROBE_ARP)
|
|
printk("ARP ");
|
|
|
|
if (g_vcPoolProbeService & PROBE_DHCP)
|
|
printk("DHCP ");
|
|
#endif
|
|
|
|
#if 0
|
|
printk("0: vpi = %d, vci = %d\r\n", g_vc_pool[0].vpi, g_vc_pool[0].vci);
|
|
printk("1: vpi = %d, vci = %d\r\n", g_vc_pool[1].vpi, g_vc_pool[1].vci);
|
|
#endif
|
|
|
|
printk("\n");
|
|
return 0;
|
|
}
|
|
|
|
/*______________________________________________________________________________
|
|
** doVcPoolEncap
|
|
**
|
|
** descriptions:set encap
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
int
|
|
doVcPoolEncap(
|
|
int argc,
|
|
char *argv[],
|
|
void *p
|
|
)
|
|
{
|
|
int i=0;
|
|
uint8 encap=0;
|
|
encap=simple_strtoul(argv[1],NULL,10);
|
|
for(i=0;i<MAX_VC_POOL_NUM;i++){
|
|
g_vc_pool[i].encap=encap;
|
|
}
|
|
#if 0
|
|
printk("0: vpi = %d, vci = %d\r\n", g_vc_pool[0].vpi, g_vc_pool[0].vci);
|
|
printk("1: vpi = %d, vci = %d\r\n", g_vc_pool[1].vpi, g_vc_pool[1].vci);
|
|
printk("encap = %d\r\n", g_vc_pool[0].encap);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
/*______________________________________________________________________________
|
|
** doVcPoolResult
|
|
**
|
|
** descriptions:add the autopvc result into buffer, this buffer will send to proc
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
static int doVcPoolResult(char *buf){
|
|
int i=0;
|
|
uint8 pvc_bit_map=0;
|
|
uint16 vc_pool_bit_map=0;
|
|
uint16 index = 0;
|
|
|
|
index += sprintf(buf+index, "pvc ");
|
|
#if !defined(TCSUPPORT_AUTO_PVC_TRIGGER)
|
|
for(i=0;i<MAX_PVC_NUM;i++){
|
|
#endif
|
|
if((g_pvc_pool[i].management == VC_HUNT_FLAG_HUNT_SUCC)){
|
|
pvc_bit_map|=(1<<i);
|
|
}
|
|
#if !defined(TCSUPPORT_AUTO_PVC_TRIGGER)
|
|
}
|
|
#endif
|
|
|
|
index += sprintf(buf+index, "%u\n",pvc_bit_map);
|
|
|
|
index += sprintf(buf+index, "vcpool ");
|
|
for(i=0;i<MAX_VC_POOL_NUM;i++){
|
|
if((g_vc_pool[i].management == VC_HUNT_FLAG_HUNT_SUCC)){
|
|
vc_pool_bit_map|=(1<<i);
|
|
}
|
|
}
|
|
index += sprintf(buf+index, "%u\n",vc_pool_bit_map);
|
|
return index;
|
|
}
|
|
|
|
|
|
/*autopvc cmd table*/
|
|
static const cmds_t vcPoolCmds[] = {
|
|
{"active", doVcPoolActive, 0x02, 1, "active <1|0>"},//0x02
|
|
{"set", doVcPoolSet, 0x02, 2, NULL},
|
|
{"encap", doVcPoolEncap, 0x02, 1, "<0(LLC)|1(VC)>"},
|
|
{"probe", doVcPoolProbe, 0x02, 1, "<pvc|vcpool>"},
|
|
{"service", doVcPoolService, 0x02, 0, "service [probe service]"},
|
|
};
|
|
/*autopvc cmd table*/
|
|
|
|
/*______________________________________________________________________________
|
|
** doVcPoolCmd
|
|
**
|
|
** descriptions:
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
int
|
|
doVcPoolCmd(
|
|
int argc,
|
|
char *argv[],
|
|
void *p
|
|
)
|
|
{
|
|
return subcmd(vcPoolCmds, argc, argv, p);
|
|
|
|
}
|
|
|
|
/*______________________________________________________________________________
|
|
** tsarm_autopvc_read_proc
|
|
**
|
|
** descriptions:return the result of autopvc from proc
|
|
** parameters:
|
|
** local:
|
|
** global:
|
|
** return:
|
|
** called by:
|
|
** call:
|
|
** revision:
|
|
**____________________________________________________________________________*/
|
|
static int tsarm_autopvc_read_proc(char *buf, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
int len = doVcPoolResult(buf);
|
|
if (len <= off+count)
|
|
*eof = 1;
|
|
*start = buf + off;
|
|
len -= off;
|
|
if (len>count)
|
|
len = count;
|
|
if (len<0)
|
|
len = 0;
|
|
return len;
|
|
}
|
|
|
|
static int tsarm_autopvc_fin_read_proc(char *buf, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
int len = sprintf(buf, "%d\r\n", fin);
|
|
return len;
|
|
}
|
|
|
|
static int tsarm_AUTOPVC_read_proc(char *buf, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
int len;
|
|
char encap[4], protocol[6];
|
|
|
|
// printk("g_vc_pool[0].encap = %d\r\n", g_vc_pool[0].encap);
|
|
switch(encap_detected){
|
|
case 0:
|
|
sprintf(encap, "%s", "llc");
|
|
break;
|
|
case 1:
|
|
sprintf(encap, "%s", "vc");
|
|
break;
|
|
default:
|
|
sprintf(encap, "%s", "llc");
|
|
break;
|
|
}
|
|
// printk("g_vcPoolProbeService = %d\r\n", g_vcPoolProbeService);
|
|
if (service_detected & PROBE_PPPOE)
|
|
sprintf(protocol, "pppoe");
|
|
else if (service_detected & PROBE_DHCP)
|
|
sprintf(protocol, "dhcp");
|
|
else
|
|
sprintf(protocol, "null");
|
|
|
|
if(!vpi_detected && !vci_detected)
|
|
len = 0;
|
|
else
|
|
len = sprintf(buf, "(%d,%d,%s,%s)\r\n", vpi_detected, vci_detected, encap, protocol);
|
|
|
|
return len;
|
|
}
|
|
|
|
static int tsarm_AUTOPVC_write_proc(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
char val_string[32];
|
|
|
|
if (count > sizeof(val_string) - 1)
|
|
return -EINVAL;
|
|
|
|
if (copy_from_user(val_string, buffer, count))
|
|
return -EFAULT;
|
|
|
|
val_string[count] = '\0';
|
|
|
|
if(val_string[0] == '1'){
|
|
vpi_detected = 0;
|
|
vci_detected = 0;
|
|
service_detected = 0;
|
|
encap_detected = 0;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/*_____________________________________________________________________________
|
|
** function name: autopvcInit
|
|
** descriptions:
|
|
** register autopvc cmd and allocate buffer.
|
|
** parameters:
|
|
** None
|
|
** global:
|
|
** None
|
|
** return:
|
|
** None
|
|
** call:
|
|
** autopvc_cmd_register_to_sys
|
|
** revision:
|
|
** 1. Krammer 2009/03/11
|
|
**____________________________________________________________________________
|
|
*/
|
|
void
|
|
autopvcInit(void)
|
|
{
|
|
uint32 mem_size=0;
|
|
/*Register autopvc ci-cmd*/
|
|
vcPoolCmd.func=doVcPoolCmd;
|
|
struct proc_dir_entry *tsarm_proc;
|
|
autopvc_cmd_register_to_sys(&vcPoolCmd);
|
|
|
|
create_proc_read_entry("tc3162/autopvc", 0, NULL, tsarm_autopvc_read_proc, NULL);
|
|
create_proc_read_entry("tc3162/autopvc_fin", 0, NULL, tsarm_autopvc_fin_read_proc, NULL);
|
|
tsarm_proc = create_proc_entry("AUTO_PVC_SEARCH", 0, NULL);
|
|
tsarm_proc->read_proc = tsarm_AUTOPVC_read_proc;
|
|
tsarm_proc->write_proc = tsarm_AUTOPVC_write_proc;
|
|
|
|
mem_size=sizeof(uint8)*AAL5_CELL_BUFFER_SIZE+ALIGN32BYTESBASE;
|
|
if ((AAL5_CELL = kmalloc(mem_size, GFP_KERNEL)) == NULL) {
|
|
printk("unable to kmalloc atmCellCirBuf structure.\n");
|
|
}
|
|
dma_cache_inv((unsigned long)AAL5_CELL, mem_size);
|
|
AAL5_CELL=(uint8 *) CACHE_TO_NONCACHE((uint32)AAL5_CELL);
|
|
memset((uint8*)AAL5_CELL, 0, mem_size);
|
|
AAL5_CELL=(uint8 *)align32Byte((uint32)AAL5_CELL);
|
|
|
|
}/*end autopvcInit*/
|
|
|
|
void
|
|
autopvcExit(void){
|
|
autopvc_cmd_unregister_to_sys();
|
|
remove_proc_entry("tc3162/autopvc",NULL);
|
|
remove_proc_entry("tc3162/autopvc_fin",NULL);
|
|
remove_proc_entry("AUTO_PVC_SEARCH",NULL);
|
|
if (AAL5_CELL){
|
|
AAL5_CELL=(uint8 *)K1_TO_K0((uint32)AAL5_CELL);
|
|
kfree(AAL5_CELL);
|
|
AAL5_CELL=NULL;
|
|
}
|
|
}
|