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

📄 asix.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
				0, 0, 6, buf)) < 0) {		dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);		goto out2;	}	memcpy(dev->net->dev_addr, buf, ETH_ALEN);	/* Get the PHY id */	if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID,				0, 0, 2, buf)) < 0) {		dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret);		goto out2;	} else if (ret < 2) {		/* this should always return 2 bytes */		dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",				ret);		ret = -EIO;		goto out2;	}	/* Initialize MII structure */	dev->mii.dev = dev->net;	dev->mii.mdio_read = ax8817x_mdio_read;	dev->mii.mdio_write = ax8817x_mdio_write;	dev->mii.phy_id_mask = 0x3f;	dev->mii.reg_num_mask = 0x1f;	dev->mii.phy_id = *((u8 *)buf + 1);	dev->net->do_ioctl = ax8817x_ioctl;	dev->net->set_multicast_list = ax8817x_set_multicast;	dev->net->ethtool_ops = &ax8817x_ethtool_ops;	ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);	ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE,		ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);	mii_nway_restart(&dev->mii);	return 0;out2:	kfree(buf);out1:	return ret;}static struct ethtool_ops ax88772_ethtool_ops = {	.get_drvinfo		= ax8817x_get_drvinfo,	.get_link		= ethtool_op_get_link,	.get_msglevel		= usbnet_get_msglevel,	.set_msglevel		= usbnet_set_msglevel,	.get_wol		= ax8817x_get_wol,	.set_wol		= ax8817x_set_wol,	.get_eeprom_len		= ax8817x_get_eeprom_len,	.get_eeprom		= ax8817x_get_eeprom,	.get_settings		= ax8817x_get_settings,	.set_settings		= ax8817x_set_settings,};static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf){	int ret;	void *buf;	usbnet_get_endpoints(dev,intf);	buf = kmalloc(6, GFP_KERNEL);	if(!buf) {		dbg ("Cannot allocate memory for buffer");		ret = -ENOMEM;		goto out1;	}	if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,				     0x00B0, 0, 0, buf)) < 0)		goto out2;	msleep(5);	if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT,				0x0001, 0, 0, buf)) < 0) {		dbg("Select PHY #1 failed: %d", ret);		goto out2;	}	if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD,				0, 0, buf)) < 0) {		dbg("Failed to power down internal PHY: %d", ret);		goto out2;	}	msleep(150);	if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR,				0, 0, buf)) < 0) {		dbg("Failed to perform software reset: %d", ret);		goto out2;	}	msleep(150);	if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET,	     			AX_SWRESET_IPRL | AX_SWRESET_PRL,				0, 0, buf)) < 0) {		dbg("Failed to set Internal/External PHY reset control: %d",					ret);		goto out2;	}	msleep(150);	if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL,				0x0000, 0, 0, buf)) < 0) {		dbg("Failed to reset RX_CTL: %d", ret);		goto out2;	}	/* Get the MAC address */	memset(buf, 0, ETH_ALEN);	if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID,				0, 0, ETH_ALEN, buf)) < 0) {		dbg("Failed to read MAC address: %d", ret);		goto out2;	}	memcpy(dev->net->dev_addr, buf, ETH_ALEN);	if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII,				0, 0, 0, buf)) < 0) {		dbg("Enabling software MII failed: %d", ret);		goto out2;	}	if (((ret = ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG,	      			0x0010, 2, 2, buf)) < 0)			|| (*((u16 *)buf) != 0x003b)) {		dbg("Read PHY register 2 must be 0x3b00: %d", ret);		goto out2;	}	/* Initialize MII structure */	dev->mii.dev = dev->net;	dev->mii.mdio_read = ax8817x_mdio_read;	dev->mii.mdio_write = ax8817x_mdio_write;	dev->mii.phy_id_mask = 0xff;	dev->mii.reg_num_mask = 0xff;	dev->net->do_ioctl = ax8817x_ioctl;	/* Get the PHY id */	if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID,			0, 0, 2, buf)) < 0) {		dbg("Error reading PHY ID: %02x", ret);		goto out2;	} else if (ret < 2) {		/* this should always return 2 bytes */		dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",		    ret);		ret = -EIO;		goto out2;	}	dev->mii.phy_id = *((u8 *)buf + 1);	if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL,				0, 0, buf)) < 0) {		dbg("Set external PHY reset pin level: %d", ret);		goto out2;	}	msleep(150);	if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET,	     			AX_SWRESET_IPRL | AX_SWRESET_PRL,				0, 0, buf)) < 0) {		dbg("Set Internal/External PHY reset control: %d", ret);		goto out2;	}	msleep(150);	dev->net->set_multicast_list = ax8817x_set_multicast;	dev->net->ethtool_ops = &ax88772_ethtool_ops;	ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);	ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE,			ADVERTISE_ALL | ADVERTISE_CSMA);	mii_nway_restart(&dev->mii);	if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE,				AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) {		dbg("Write medium mode register: %d", ret);		goto out2;	}	if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0,				AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,				AX88772_IPG2_DEFAULT, 0, buf)) < 0) {		dbg("Write IPG,IPG1,IPG2 failed: %d", ret);		goto out2;	}	if ((ret =	     ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) {		dbg("Failed to set hardware MII: %02x", ret);		goto out2;	}	/* Set RX_CTL to default values with 2k buffer, and enable cactus */	if ((ret =	     ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0,			       buf)) < 0) {		dbg("Reset RX_CTL failed: %d", ret);		goto out2;	}	kfree(buf);	/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */	if (dev->driver_info->flags & FLAG_FRAMING_AX) {		/* hard_mtu  is still the default - the device does not support		   jumbo eth frames */		dev->rx_urb_size = 2048;	}	return 0;out2:	kfree(buf);out1:	return ret;}static int ax88772_rx_fixup(struct usbnet *dev, struct sk_buff *skb){	u8  *head;	u32  header;	char *packet;	struct sk_buff *ax_skb;	u16 size;	head = (u8 *) skb->data;	memcpy(&header, head, sizeof(header));	le32_to_cpus(&header);	packet = head + sizeof(header);	skb_pull(skb, 4);	while (skb->len > 0) {		if ((short)(header & 0x0000ffff) !=		    ~((short)((header & 0xffff0000) >> 16))) {			devdbg(dev,"header length data is error");		}		/* get the packet length */		size = (u16) (header & 0x0000ffff);		if ((skb->len) - ((size + 1) & 0xfffe) == 0)			return 2;		if (size > ETH_FRAME_LEN) {			devdbg(dev,"invalid rx length %d", size);			return 0;		}		ax_skb = skb_clone(skb, GFP_ATOMIC);		if (ax_skb) {			ax_skb->len = size;			ax_skb->data = packet;			ax_skb->tail = packet + size;			usbnet_skb_return(dev, ax_skb);		} else {			return 0;		}		skb_pull(skb, (size + 1) & 0xfffe);		if (skb->len == 0)			break;		head = (u8 *) skb->data;		memcpy(&header, head, sizeof(header));		le32_to_cpus(&header);		packet = head + sizeof(header);		skb_pull(skb, 4);	}	if (skb->len < 0) {		devdbg(dev,"invalid rx length %d", skb->len);		return 0;	}	return 1;}static struct sk_buff *ax88772_tx_fixup(struct usbnet *dev, struct sk_buff *skb,					gfp_t flags){	int padlen;	int headroom = skb_headroom(skb);	int tailroom = skb_tailroom(skb);	u32 packet_len;	u32 padbytes = 0xffff0000;	padlen = ((skb->len + 4) % 512) ? 0 : 4;	if ((!skb_cloned(skb))	    && ((headroom + tailroom) >= (4 + padlen))) {		if ((headroom < 4) || (tailroom < padlen)) {			skb->data = memmove(skb->head + 4, skb->data, skb->len);			skb->tail = skb->data + skb->len;		}	} else {		struct sk_buff *skb2;		skb2 = skb_copy_expand(skb, 4, padlen, flags);		dev_kfree_skb_any(skb);		skb = skb2;		if (!skb)			return NULL;	}	skb_push(skb, 4);	packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);	memcpy(skb->data, &packet_len, sizeof(packet_len));	if ((skb->len % 512) == 0) {		memcpy( skb->tail, &padbytes, sizeof(padbytes));		skb_put(skb, sizeof(padbytes));	}	return skb;}static int ax88772_link_reset(struct usbnet *dev){	u16 lpa;	u16 adv;	u16 res;	u16 mode;	mode = AX88772_MEDIUM_DEFAULT;	lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA);	adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE);	res = mii_nway_result(lpa|adv);	if ((res & LPA_DUPLEX) == 0)		mode &= ~AX88772_MEDIUM_FULL_DUPLEX;	if ((res & LPA_100) == 0)		mode &= ~AX88772_MEDIUM_100MB;	ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);	return 0;}static const struct driver_info ax8817x_info = {	.description = "ASIX AX8817x USB 2.0 Ethernet",	.bind = ax8817x_bind,	.status = ax8817x_status,	.link_reset = ax88172_link_reset,	.reset = ax88172_link_reset,	.flags =  FLAG_ETHER,	.data = 0x00130103,};static const struct driver_info dlink_dub_e100_info = {	.description = "DLink DUB-E100 USB Ethernet",	.bind = ax8817x_bind,	.status = ax8817x_status,	.link_reset = ax88172_link_reset,	.reset = ax88172_link_reset,	.flags =  FLAG_ETHER,	.data = 0x009f9d9f,};static const struct driver_info netgear_fa120_info = {	.description = "Netgear FA-120 USB Ethernet",	.bind = ax8817x_bind,	.status = ax8817x_status,	.link_reset = ax88172_link_reset,	.reset = ax88172_link_reset,	.flags =  FLAG_ETHER,	.data = 0x00130103,};static const struct driver_info hawking_uf200_info = {	.description = "Hawking UF200 USB Ethernet",	.bind = ax8817x_bind,	.status = ax8817x_status,	.link_reset = ax88172_link_reset,	.reset = ax88172_link_reset,	.flags =  FLAG_ETHER,	.data = 0x001f1d1f,};static const struct driver_info ax88772_info = {	.description = "ASIX AX88772 USB 2.0 Ethernet",	.bind = ax88772_bind,	.status = ax8817x_status,	.link_reset = ax88772_link_reset,	.reset = ax88772_link_reset,	.flags = FLAG_ETHER | FLAG_FRAMING_AX,	.rx_fixup = ax88772_rx_fixup,	.tx_fixup = ax88772_tx_fixup,	.data = 0x00130103,};static const struct usb_device_id	products [] = {{	// Linksys USB200M	USB_DEVICE (0x077b, 0x2226),	.driver_info =	(unsigned long) &ax8817x_info,}, {	// Netgear FA120	USB_DEVICE (0x0846, 0x1040),	.driver_info =  (unsigned long) &netgear_fa120_info,}, {	// DLink DUB-E100	USB_DEVICE (0x2001, 0x1a00),	.driver_info =  (unsigned long) &dlink_dub_e100_info,}, {	// Intellinet, ST Lab USB Ethernet	USB_DEVICE (0x0b95, 0x1720),	.driver_info =  (unsigned long) &ax8817x_info,}, {	// Hawking UF200, TrendNet TU2-ET100	USB_DEVICE (0x07b8, 0x420a),	.driver_info =  (unsigned long) &hawking_uf200_info,}, {        // Billionton Systems, USB2AR        USB_DEVICE (0x08dd, 0x90ff),        .driver_info =  (unsigned long) &ax8817x_info,}, {	// ATEN UC210T	USB_DEVICE (0x0557, 0x2009),	.driver_info =  (unsigned long) &ax8817x_info,}, {	// Buffalo LUA-U2-KTX	USB_DEVICE (0x0411, 0x003d),	.driver_info =  (unsigned long) &ax8817x_info,}, {	// Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"	USB_DEVICE (0x6189, 0x182d),	.driver_info =  (unsigned long) &ax8817x_info,}, {	// corega FEther USB2-TX	USB_DEVICE (0x07aa, 0x0017),	.driver_info =  (unsigned long) &ax8817x_info,}, {	// Surecom EP-1427X-2	USB_DEVICE (0x1189, 0x0893),	.driver_info = (unsigned long) &ax8817x_info,}, {	// goodway corp usb gwusb2e	USB_DEVICE (0x1631, 0x6200),	.driver_info = (unsigned long) &ax8817x_info,}, {	// ASIX AX88772 10/100        USB_DEVICE (0x0b95, 0x7720),        .driver_info = (unsigned long) &ax88772_info,},	{ },		// END};MODULE_DEVICE_TABLE(usb, products);static struct usb_driver asix_driver = {	.owner =	THIS_MODULE,	.name =		"asix",	.id_table =	products,	.probe =	usbnet_probe,	.suspend =	usbnet_suspend,	.resume =	usbnet_resume,	.disconnect =	usbnet_disconnect,};static int __init asix_init(void){ 	return usb_register(&asix_driver);}module_init(asix_init);static void __exit asix_exit(void){ 	usb_deregister(&asix_driver);}module_exit(asix_exit);MODULE_AUTHOR("David Hollis");MODULE_DESCRIPTION("ASIX AX8817X based USB 2.0 Ethernet Devices");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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