⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 userhermes.c

📁 linux 下的无限网卡驱动开发
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/io.h>#include <errno.h>#include <readline/readline.h>#include <readline/history.h>#include <linux/types.h>typedef __u8 uint8_t;typedef __u16  uint16_t;typedef __u32 uint32_t;#include "hermes.h"#define BAP_BUSY_TIMEOUT 50#define fatal(s) do { perror(s); exit(1); } while (0)typedef struct record_info {	uint16_t rid;	uint16_t len;	char *name;} record_info_t;record_info_t rid_table[] = {	{0xfc00,  2, "CNFPORTTYPE"},	{0xfc01,  6, "CNFOWNMACADDR"},	{0xfc02, 34, "CNFDESIREDSSID"},	{0xfc03,  2, "CNFOWNCHANNEL"},	{0xfc04, 34, "CNFOWNSSID"},	{0xfc05,  2, "CNFOWNATIMWIN"},	{0xfc06,  0, "CNFSYSSCALE"},	{0xfc07,  0, "CNFMAXDATALEN"},	{0xfc08,  0, "CNFWDSADDR"},	{0xfc09,  0, "CNFPMENABLED"},	{0xfc0a,  0, "CNFPMEPS"},	{0xfc0b,  0, "CNFMULTICASTRX"},	{0xfc0c,  0, "CNFMAXSLEEPDUR"},	{0xfc0d,  0, "CNFCNFPMHOLDDUR"},	{0xfc0e,  0, "CNFOWNNAME"},	{0xfc10,  0, "CNFOWNDTIMPER"},	{0xfc11,  0, "CNFWDSADDR1"},	{0xfc12,  0, "CNFWDSADDR2"},	{0xfc13,  0, "CNFWDSADDR3"},	{0xfc14,  0, "CNFWDSADDR4"},	{0xfc15,  0, "CNFWDSADDR5"},	{0xfc16,  0, "CNFWDSADDR6"},	{0xfc17,  0, "CNFMCASTPMBUFF"},	{0xfcb0,  0, "CNFSHORTPREAMBLE"}};#define NUM_RIDS (sizeof(rid_table) / sizeof(record_info_t))typedef struct record {	uint16_t len;	uint16_t type;	uint16_t value[4096];} record_t;/* Set up a BAP to read a particular chunk of data from card's internal buffer. * * Returns: < 0 on internal failure (errno), 0 on success, >0 on error from firmware  * * Callable from any context */static int hermes_bap_seek(ulong hw, int bap, uint16_t id, uint16_t offset){	int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;	int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;	int k;	uint16_t reg;	/* Paranoia.. */	if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )		return -EINVAL;	/* Now we actually set up the transfer */	hermes_write_reg(hw, sreg, id);	hermes_write_reg(hw, oreg, offset);	/* Wait for the BAP to be ready */	k = BAP_BUSY_TIMEOUT;	reg = hermes_read_reg(hw, oreg);	while ( (reg & HERMES_OFFSET_BUSY) && k) {		k--;		reg = hermes_read_reg(hw, oreg);	}	if (reg & HERMES_OFFSET_BUSY)		return -ETIMEDOUT;	if (reg & HERMES_OFFSET_ERR)		return reg;	return 0;}/* Read a block of data from the chip's buffer, via the * BAP. Synchronization/serialization is the caller's problem.  len * must be even. * * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware * * Callable from any context */int hermes_bap_pread(ulong hw, int bap, char *buf, uint16_t len,		      uint16_t id, uint16_t offset){	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;	int err;	err = hermes_bap_seek(hw, bap, id, offset);	if (err)		return err;	/* Actually do the transfer */	hermes_read_data(hw, dreg, buf, len/2);	return 0;}/* Write a block of data to the chip's buffer, via the * BAP. Synchronization/serialization is the caller's problem. len * must be even. * * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware * * Callable from any context */int hermes_bap_pwrite(ulong hw, int bap, const char *buf, uint16_t len,		       uint16_t id, uint16_t offset){	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;	int err;	if (len % 2)		return -EINVAL;	err = hermes_bap_seek(hw, bap, id, offset);	if (err)		return err;	/* Actually do the transfer */	hermes_write_data(hw, dreg, buf, len/2);	return 0;}void usage(void){	fprintf(stderr, "Usage: userprism <base io>\n");	exit(1);}char *rl_gets (void){	char * line;	/* Get a line from the user. */	line = readline ("> ");		/* If the line has any text in it, save it on the history. */	if (line && *line)		add_history (line);		return (line);}void display(unsigned long base){#define DREG(name) printf("%-16s: %04x\n", #name, inw(base + HERMES_##name))	DREG(CMD);	DREG(PARAM0);	DREG(PARAM1);	DREG(PARAM2);	DREG(STATUS);	DREG(RESP0);	DREG(RESP1);	DREG(RESP2);	DREG(INFOFID);	DREG(RXFID);	DREG(ALLOCFID);	DREG(TXCOMPLFID);	DREG(SELECT0);	DREG(OFFSET0);	DREG(SELECT1);	DREG(OFFSET1);	DREG(EVSTAT);	DREG(INTEN);	DREG(EVACK);	DREG(CONTROL);	DREG(SWSUPPORT0);	DREG(SWSUPPORT1);	DREG(SWSUPPORT2);	DREG(AUXPAGE);	DREG(AUXOFFSET);	DREG(AUXDATA);#undef DREG}int read_lt(ulong base, int bap, uint16_t rid, record_t *rec){	int err;	err = hermes_bap_pread(base, bap, (char *)rec, 4, rid, 0);	if (err) {		fprintf(stderr, "Error %d reading type/length\n", err);		return err;	}	printf("rec->len=%d rec->type=0x%04x\n", rec->len, rec->type);	err = hermes_bap_pread(base, bap, (char *)&rec->value, rec->len, rid, 4);	if (err) {		fprintf(stderr, "Error %d reading value (%d words)\n", err, rec->len);		return err;	}	return 0;}voidshow_records(unsigned long base){	int i, j;	record_t rec;	printf("%d records total.\n", NUM_RIDS);	for (i = 0; i < NUM_RIDS; i++) {		record_info_t *info = &rid_table[i];		printf("Record %s [0x%04x]: expected length %04d\n",		       info->name, info->rid, info->len);		read_lt(base, 1, info->rid, &rec);		printf("Type 0x%04x, Len %04d: ", rec.type, rec.len);		for (j = 0; j < rec.len; j++)			printf("%04x:", rec.value[j]);		printf("\n");	}}voidshow_record(unsigned long base, uint16_t rid){	record_t rec;	int j;	printf("RID 0x%04x: ", rid);	read_lt(base, 1, rid, &rec);	printf("type=0x%04x len=%04d value=\"", rec.type, rec.len);	for (j = 0; j < rec.len/2; j++)		printf("%04x:", rec.value[j]);	printf("\"\n");}void do_line(unsigned long base, const char *line){	char reg[100];	int off;	int val;	int n;	n = sscanf(line, "%s %i\n", reg, &val);	if (n < 1 || n > 2) {		fprintf(stderr, "?\n");		return;	}	if (strcasecmp(reg, "CMD") == 0) {		off = HERMES_CMD;	} else if (strcasecmp(reg, "PARAM0") == 0) {		off = HERMES_PARAM0;	} else if (strcasecmp(reg, "PARAM1") == 0) {		off = HERMES_PARAM1;	} else if (strcasecmp(reg, "PARAM2") == 0) {		off = HERMES_PARAM2;	} else if (strcasecmp(reg, "STATUS") == 0) {		off = HERMES_STATUS;	} else if (strcasecmp(reg, "RESP0") == 0) {		off = HERMES_RESP0;	} else if (strcasecmp(reg, "RESP1") == 0) {		off = HERMES_RESP1;	} else if (strcasecmp(reg, "RESP2") == 0) {		off = HERMES_RESP2;	} else if (strcasecmp(reg, "INFOFID") == 0) {		off = HERMES_INFOFID;	} else if (strcasecmp(reg, "RXFID") == 0) {		off = HERMES_RXFID;	} else if (strcasecmp(reg, "ALLOCFID") == 0) {		off = HERMES_ALLOCFID;	} else if (strcasecmp(reg, "TXCOMPLFID") == 0) {		off = HERMES_TXCOMPLFID;	} else if (strcasecmp(reg, "SELECT0") == 0) {		off = HERMES_SELECT0;	} else if (strcasecmp(reg, "OFFSET0") == 0) {		off = HERMES_OFFSET0;	} else if (strcasecmp(reg, "DATA0") == 0) {		off = HERMES_DATA0;	} else if (strcasecmp(reg, "SELECT1") == 0) {		off = HERMES_SELECT1;	} else if (strcasecmp(reg, "OFFSET1") == 0) {		off = HERMES_OFFSET1;	} else if (strcasecmp(reg, "DATA1") == 0) {		off = HERMES_DATA1;	} else if (strcasecmp(reg, "EVSTAT") == 0) {		off = HERMES_EVSTAT;	} else if (strcasecmp(reg, "INTEN") == 0) {		off = HERMES_INTEN;	} else if (strcasecmp(reg, "EVACK") == 0) {		off = HERMES_EVACK;	} else if (strcasecmp(reg, "CONTROL") == 0) {		off = HERMES_CONTROL;	} else if (strcasecmp(reg, "SWSUPPORT0") == 0) {		off = HERMES_SWSUPPORT0;	} else if (strcasecmp(reg, "SWSUPPORT1") == 0) {		off = HERMES_SWSUPPORT1;	} else if (strcasecmp(reg, "SWSUPPORT2") == 0) {		off = HERMES_SWSUPPORT2;	} else if (strcasecmp(reg, "AUXPAGE") == 0) {		off = HERMES_AUXPAGE;	} else if (strcasecmp(reg, "AUXOFFSET") == 0) {		off = HERMES_AUXOFFSET;	} else if (strcasecmp(reg, "AUXDATA") == 0) {		off = HERMES_AUXDATA;	} else if (strcasecmp(reg, ".") == 0) {		display(base);		return;	} else if (strcasecmp(reg, ",") == 0) {		if (n != 2) {			fprintf(stderr, "? No FID given\n");			return;		}		show_record(base, val);		return;	} else {		fprintf(stderr, "? Unknown register\"%s\"\n", reg);		return;	}	if (n == 2) {		printf("0x%04x -> 0x%04x\n", val, (int)base+off);		outw(val, base+off);	}	printf("%s (0x%04x) = 0x%04x\n", reg, off, inw(base+off));}intmain(int argc, char *argv[]){	char *e;	unsigned long base;	int err;	char * line;		if (argc < 2)		usage();	base = strtol(argv[1], &e, 0);	if (*e)		usage();	err = ioperm(base, 0x40, 1);	if (err != 0)		fatal("ioperm");	if (argc > 2) {		show_records(base);		exit(0);	}			while (1) {		line = rl_gets();				if (! line)			break;		do_line(base, line);		free(line);	};		exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -