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

📄 ueagle-atm.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	for (i = 0; i < le16_to_cpu(p->page_header[0].PageNumber); i++) {		if (E4_IS_BOOT_PAGE(p->page_header[i].PageSize))			__uea_load_page_e4(sc, i, 1);	}	uea_dbg(INS_TO_USBDEV(sc),"sending start bi\n");	bi.wHdr = cpu_to_be16(UEA_BIHDR);	bi.bBootPage = 0;	bi.bPageNumber = 0xff;	bi.wReserved = cpu_to_be16(UEA_RESERVED);	bi.dwSize = cpu_to_be32(E4_PAGE_BYTES(p->page_header[0].PageSize));	bi.dwAddress = swab32(p->page_header[0].PageAddress);	/* send block info through the IDMA pipe */	if (uea_idma_write(sc, &bi, E4_BLOCK_INFO_SIZE))		uea_err(INS_TO_USBDEV(sc), "sending DSP start bi failed\n");}static inline void wake_up_cmv_ack(struct uea_softc *sc){	BUG_ON(sc->cmv_ack);	sc->cmv_ack = 1;	wake_up(&sc->sync_q);}static inline int wait_cmv_ack(struct uea_softc *sc){	int ret = uea_wait(sc, sc->cmv_ack , ACK_TIMEOUT);	sc->cmv_ack = 0;	uea_dbg(INS_TO_USBDEV(sc), "wait_event_timeout : %d ms\n",			jiffies_to_msecs(ret));	if (ret < 0)		return ret;	return (ret == 0) ? -ETIMEDOUT : 0;}#define UCDC_SEND_ENCAPSULATED_COMMAND 0x00static int uea_request(struct uea_softc *sc,		u16 value, u16 index, u16 size, void *data){	u8 *xfer_buff;	int ret = -ENOMEM;	xfer_buff = kmemdup(data, size, GFP_KERNEL);	if (!xfer_buff) {		uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");		return ret;	}	ret = usb_control_msg(sc->usb_dev, usb_sndctrlpipe(sc->usb_dev, 0),			      UCDC_SEND_ENCAPSULATED_COMMAND,			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,			      value, index, xfer_buff, size, CTRL_TIMEOUT);	kfree(xfer_buff);	if (ret < 0) {		uea_err(INS_TO_USBDEV(sc), "usb_control_msg error %d\n", ret);		return ret;	}	if (ret != size) {		uea_err(INS_TO_USBDEV(sc),		       "usb_control_msg send only %d bytes (instead of %d)\n",		       ret, size);		return -EIO;	}	return 0;}static int uea_cmv_e1(struct uea_softc *sc,		u8 function, u32 address, u16 offset, u32 data){	struct cmv_e1 cmv;	int ret;	uea_enters(INS_TO_USBDEV(sc));	uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, "			"offset : 0x%04x, data : 0x%08x\n",			E1_FUNCTION_TYPE(function), E1_FUNCTION_SUBTYPE(function),			E1_GETSA1(address), E1_GETSA2(address), E1_GETSA3(address),			E1_GETSA4(address), offset, data);	/* we send a request, but we expect a reply */	sc->cmv_dsc.e1.function = function | 0x2;	sc->cmv_dsc.e1.idx++;	sc->cmv_dsc.e1.address = address;	sc->cmv_dsc.e1.offset = offset;	cmv.wPreamble = cpu_to_le16(E1_PREAMBLE);	cmv.bDirection = E1_HOSTTOMODEM;	cmv.bFunction = function;	cmv.wIndex = cpu_to_le16(sc->cmv_dsc.e1.idx);	put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress);	cmv.wOffsetAddress = cpu_to_le16(offset);	put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData);	ret = uea_request(sc, UEA_E1_SET_BLOCK, UEA_MPTX_START, sizeof(cmv), &cmv);	if (ret < 0)		return ret;	ret = wait_cmv_ack(sc);	uea_leaves(INS_TO_USBDEV(sc));	return ret;}static int uea_cmv_e4(struct uea_softc *sc,		u16 function, u16 group, u16 address, u16 offset, u32 data){	struct cmv_e4 cmv;	int ret;	uea_enters(INS_TO_USBDEV(sc));	memset(&cmv, 0, sizeof(cmv));	uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Group : 0x%04x, "		 "Address : 0x%04x, offset : 0x%04x, data : 0x%08x\n",		 E4_FUNCTION_TYPE(function), E4_FUNCTION_SUBTYPE(function),		 group, address, offset, data);	/* we send a request, but we expect a reply */	sc->cmv_dsc.e4.function = function | (0x1 << 4);	sc->cmv_dsc.e4.offset = offset;	sc->cmv_dsc.e4.address = address;	sc->cmv_dsc.e4.group = group;	cmv.wFunction = cpu_to_be16(function);	cmv.wGroup = cpu_to_be16(group);	cmv.wAddress = cpu_to_be16(address);	cmv.wOffset = cpu_to_be16(offset);	cmv.dwData[0] = cpu_to_be32(data);	ret = uea_request(sc, UEA_E4_SET_BLOCK, UEA_MPTX_START, sizeof(cmv), &cmv);	if (ret < 0)		return ret;	ret = wait_cmv_ack(sc);	uea_leaves(INS_TO_USBDEV(sc));	return ret;}static inline int uea_read_cmv_e1(struct uea_softc *sc,		u32 address, u16 offset, u32 *data){	int ret = uea_cmv_e1(sc, E1_MAKEFUNCTION(E1_MEMACCESS, E1_REQUESTREAD),			  address, offset, 0);	if (ret < 0)		uea_err(INS_TO_USBDEV(sc),			"reading cmv failed with error %d\n", ret);	else	 	*data = sc->data;	return ret;}static inline int uea_read_cmv_e4(struct uea_softc *sc,		u8 size, u16 group, u16 address, u16 offset, u32 *data){	int ret = uea_cmv_e4(sc, E4_MAKEFUNCTION(E4_MEMACCESS, E4_REQUESTREAD, size),			  group, address, offset, 0);	if (ret < 0)		uea_err(INS_TO_USBDEV(sc),			"reading cmv failed with error %d\n", ret);	else {	 	*data = sc->data;		/* size is in 16-bit word quantities */		if (size > 2)			*(data + 1) = sc->data1;	}	return ret;}static inline int uea_write_cmv_e1(struct uea_softc *sc,		u32 address, u16 offset, u32 data){	int ret = uea_cmv_e1(sc, E1_MAKEFUNCTION(E1_MEMACCESS, E1_REQUESTWRITE),			  address, offset, data);	if (ret < 0)		uea_err(INS_TO_USBDEV(sc),			"writing cmv failed with error %d\n", ret);	return ret;}static inline int uea_write_cmv_e4(struct uea_softc *sc,		u8 size, u16 group, u16 address, u16 offset, u32 data){	int ret = uea_cmv_e4(sc, E4_MAKEFUNCTION(E4_MEMACCESS, E4_REQUESTWRITE, size),			  group, address, offset, data);	if (ret < 0)		uea_err(INS_TO_USBDEV(sc),			"writing cmv failed with error %d\n", ret);	return ret;}static void uea_set_bulk_timeout(struct uea_softc *sc, u32 dsrate){	int ret;	u16 timeout;	/* in bulk mode the modem have problem with high rate	 * changing internal timing could improve things, but the	 * value is misterious.	 * ADI930 don't support it (-EPIPE error).	 */	if (UEA_CHIP_VERSION(sc) == ADI930 ||	    altsetting[sc->modem_index] > 0 ||	    sc->stats.phy.dsrate == dsrate)		return;	/* Original timming (1Mbit/s) from ADI (used in windows driver) */	timeout = (dsrate <= 1024*1024) ? 0 : 1;	ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL);	uea_info(INS_TO_USBDEV(sc), "setting new timeout %d%s\n",		 timeout,  ret < 0 ? " failed" : "");}/* * Monitor the modem and update the stat * return 0 if everything is ok * return < 0 if an error occurs (-EAGAIN reboot needed) */static int uea_stat_e1(struct uea_softc *sc){	u32 data;	int ret;	uea_enters(INS_TO_USBDEV(sc));	data = sc->stats.phy.state;	ret = uea_read_cmv_e1(sc, E1_SA_STAT, 0, &sc->stats.phy.state);	if (ret < 0)		return ret;	switch (GET_STATUS(sc->stats.phy.state)) {	case 0:		/* not yet synchronized */		uea_dbg(INS_TO_USBDEV(sc),		       "modem not yet synchronized\n");		return 0;	case 1:		/* initialization */		uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n");		return 0;	case 2:		/* operational */		uea_vdbg(INS_TO_USBDEV(sc), "modem operational\n");		break;	case 3:		/* fail ... */		uea_info(INS_TO_USBDEV(sc), "modem synchronization failed"					" (may be try other cmv/dsp)\n");		return -EAGAIN;	case 4 ... 6:	/* test state */		uea_warn(INS_TO_USBDEV(sc),				"modem in test mode - not supported\n");		return -EAGAIN;	case 7:		/* fast-retain ... */		uea_info(INS_TO_USBDEV(sc), "modem in fast-retain mode\n");		return 0;	default:		uea_err(INS_TO_USBDEV(sc), "modem invalid SW mode %d\n",			GET_STATUS(sc->stats.phy.state));		return -EAGAIN;	}	if (GET_STATUS(data) != 2) {		uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL);		uea_info(INS_TO_USBDEV(sc), "modem operational\n");		/* release the dsp firmware as it is not needed until		 * the next failure		 */		if (sc->dsp_firm) {			release_firmware(sc->dsp_firm);			sc->dsp_firm = NULL;		}	}	/* always update it as atm layer could not be init when we switch to	 * operational state	 */	UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND);	/* wake up processes waiting for synchronization */	wake_up(&sc->sync_q);	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 2, &sc->stats.phy.flags);	if (ret < 0)		return ret;	sc->stats.phy.mflags |= sc->stats.phy.flags;	/* in case of a flags ( for example delineation LOSS (& 0x10)),	 * we check the status again in order to detect the failure earlier	 */	if (sc->stats.phy.flags) {		uea_dbg(INS_TO_USBDEV(sc), "Stat flag = 0x%x\n",		       sc->stats.phy.flags);		return 0;	}	ret = uea_read_cmv_e1(sc, E1_SA_RATE, 0, &data);	if (ret < 0)		return ret;	uea_set_bulk_timeout(sc, (data >> 16) * 32);	sc->stats.phy.dsrate = (data >> 16) * 32;	sc->stats.phy.usrate = (data & 0xffff) * 32;	UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424);	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 23, &data);	if (ret < 0)		return ret;	sc->stats.phy.dsattenuation = (data & 0xff) / 2;	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 47, &data);	if (ret < 0)		return ret;	sc->stats.phy.usattenuation = (data & 0xff) / 2;	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 25, &sc->stats.phy.dsmargin);	if (ret < 0)		return ret;	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 49, &sc->stats.phy.usmargin);	if (ret < 0)		return ret;	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 51, &sc->stats.phy.rxflow);	if (ret < 0)		return ret;	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 52, &sc->stats.phy.txflow);	if (ret < 0)		return ret;	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 54, &sc->stats.phy.dsunc);	if (ret < 0)		return ret;	/* only for atu-c */	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 58, &sc->stats.phy.usunc);	if (ret < 0)		return ret;	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 53, &sc->stats.phy.dscorr);	if (ret < 0)		return ret;	/* only for atu-c */	ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 57, &sc->stats.phy.uscorr);	if (ret < 0)		return ret;	ret = uea_read_cmv_e1(sc, E1_SA_INFO, 8, &sc->stats.phy.vidco);	if (ret < 0)		return ret;	ret = uea_read_cmv_e1(sc, E1_SA_INFO, 13, &sc->stats.phy.vidcpe);	if (ret < 0)		return ret;	return 0;}static int uea_stat_e4(struct uea_softc *sc){	u32 data;	u32 tmp_arr[2];	int ret;	uea_enters(INS_TO_USBDEV(sc));	data = sc->stats.phy.state;	/* XXX only need to be done before operationnal... */	ret = uea_read_cmv_e4(sc, 1, E4_SA_STAT, 0, 0, &sc->stats.phy.state);	if (ret < 0)		return ret;	switch (sc->stats.phy.state) {		case 0x0:	/* not yet synchronized */		case 0x1:		case 0x3:		case 0x4:			uea_dbg(INS_TO_USBDEV(sc), "modem not yet synchronized\n");			return 0;		case 0x5:	/* initialization */		case 0x6:		case 0x9:		case 0xa:			uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n");			return 0;		case 0x2:	/* fail ... */			uea_info(INS_TO_USBDEV(sc), "modem synchronization failed"					" (may be try other cmv/dsp)\n");			return -EAGAIN;		case 0x7: 	/* operational */			break;		default:			uea_warn(INS_TO_USBDEV(sc), "unknown state: %x\n", sc->stats.phy.state);			return 0;	}	if (data != 7) {		uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL);		uea_info(INS_TO_USBDEV(sc), "modem operational\n");		/* release the dsp firmware as it is not needed until		 * the next failure		 */		if (sc->dsp_firm) {			release_firmware(sc->dsp_firm);			sc->dsp_firm = NULL;		}	}	/* always update it as atm layer could not be init when we switch to	 * operational state	 */	UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND);	/* wake up processes waiting for synchronization */	wake_up(&sc->sync_q);	/* TODO improve this state machine :	 * we need some CMV info : what they do and their unit	 * we should find the equivalent of eagle3- CMV	 */	/* check flags */	ret = uea_read_cmv_e4(sc, 1, E4_SA_DIAG, 0, 0, &sc->stats.phy.flags);	if (ret < 0)		return ret;	sc->stats.phy.mflags |= sc->stats.phy.flags;	/* in case of a flags ( for example delineation LOSS (& 0x10)),	 * we check the status again in order to detect the failure earlier	 */	if (sc->stats.phy.flags) {		uea_dbg(INS_TO_USBDEV(sc), "Stat flag = 0x%x\n",		       sc->stats.phy.flags);		if (sc->stats.phy.flags & 1) //delineation LOSS			return -EAGAIN;		if (sc->stats.phy.flags & 0x4000) //Reset Flag			return -EAGAIN;		return 0;	}	/* rate data may be in upper or lower half of 64 bit word, strange */	ret = uea_read_cmv_e4(sc, 4, E4_SA_RATE, 0, 0, tmp_arr);	if (ret < 0)		return ret;	data = (tmp_arr[0]) ? tmp_arr[0] : tmp_arr[1];	sc->stats.phy.usrate = data / 1000;	ret = uea_read_cmv_e4(sc, 4, E4_SA_RATE, 1, 0, tmp_arr);	if (ret < 0)		return ret;	data = (tmp_arr[0]) ? tmp_arr[0] : tmp_arr[1];	uea_set_bulk_timeout(sc, data / 1000);	sc->stats.phy.dsrate = data / 1000;	UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424);	ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 68, 1, &data);	if (ret < 0)		return ret;	sc->stats.phy.dsattenuation = data / 10;	ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 69, 1, &data);	if (ret < 0)		return ret;	sc->stats.phy.usattenuation = data / 10;	ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 68, 3, &data);	if (ret < 0)		return ret;	sc->stats.phy.dsmargin = data / 2;	ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 69, 3, &data);	if (ret < 0)		return ret;	sc->stats.phy.usmargin = data / 10;	return 0;}static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver){	char file_arr[] = "CMVxy.bin";	char *file;	/* set proper name corresponding modem version and line type */	if (cmv_file[sc->modem_index] == NULL) {		if (UEA_CHIP_VERSION(sc) == ADI930)			file_arr[3] = '9';		else if (UEA_CHIP_VERSION(sc) == EAGLE_IV)			file_arr[3] = '4';		else			file_arr[3] = 'e';		file_arr[4] = IS_ISDN(sc) ? 'i' : 'p';		file = file_arr;	} else		file = cmv_file[sc->modem_index];	strcpy(cmv_name, FW_DIR);	strlcat(cmv_name, file, FIRMWARE_NAME_MAX);	if (ver == 2)		strlcat(cmv_name, ".v2", FIRMWARE_NAME_MAX);}static int request_cmvs_old(struct uea_softc *sc,		 void **cmvs, const struct firmware **fw){	int ret, size;	u8 *data;	char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */	cmvs_file_name(sc, cmv_name, 1);

⌨️ 快捷键说明

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