drivers/net/ethernet/dec/tulip/media.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/dec/tulip/media.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/dec/tulip/media.c
Extension
.c
Size
16575 bytes
Lines
548
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (mleaf->type) {
		case 0:					/* 21140 non-MII xcvr. */
			if (tulip_debug > 1)
				netdev_dbg(dev, "Using a 21140 non-MII transceiver with control setting %02x\n",
					   p[1]);
			dev->if_port = p[0];
			if (startup)
				iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
			iowrite32(p[1], ioaddr + CSR12);
			new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18);
			break;
		case 2: case 4: {
			u16 setup[5];
			u32 csr13val, csr14val, csr15dir, csr15val;
			for (i = 0; i < 5; i++)
				setup[i] = get_u16(&p[i*2 + 1]);

			dev->if_port = p[0] & MEDIA_MASK;
			if (tulip_media_cap[dev->if_port] & MediaAlwaysFD)
				tp->full_duplex = 1;

			if (startup && mtable->has_reset) {
				struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
				unsigned char *rst = rleaf->leafdata;
				if (tulip_debug > 1)
					netdev_dbg(dev, "Resetting the transceiver\n");
				for (i = 0; i < rst[0]; i++)
					iowrite32(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
			}
			if (tulip_debug > 1)
				netdev_dbg(dev, "21143 non-MII %s transceiver control %04x/%04x\n",
					   medianame[dev->if_port],
					   setup[0], setup[1]);
			if (p[0] & 0x40) {	/* SIA (CSR13-15) setup values are provided. */
				csr13val = setup[0];
				csr14val = setup[1];
				csr15dir = (setup[3]<<16) | setup[2];
				csr15val = (setup[4]<<16) | setup[2];
				iowrite32(0, ioaddr + CSR13);
				iowrite32(csr14val, ioaddr + CSR14);
				iowrite32(csr15dir, ioaddr + CSR15);	/* Direction */
				iowrite32(csr15val, ioaddr + CSR15);	/* Data */
				iowrite32(csr13val, ioaddr + CSR13);
			} else {
				csr13val = 1;
				csr14val = 0;
				csr15dir = (setup[0]<<16) | 0x0008;
				csr15val = (setup[1]<<16) | 0x0008;
				if (dev->if_port <= 4)
					csr14val = t21142_csr14[dev->if_port];
				if (startup) {
					iowrite32(0, ioaddr + CSR13);
					iowrite32(csr14val, ioaddr + CSR14);
				}
				iowrite32(csr15dir, ioaddr + CSR15);	/* Direction */
				iowrite32(csr15val, ioaddr + CSR15);	/* Data */
				if (startup) iowrite32(csr13val, ioaddr + CSR13);
			}
			if (tulip_debug > 1)
				netdev_dbg(dev, "Setting CSR15 to %08x/%08x\n",
					   csr15dir, csr15val);
			if (mleaf->type == 4)
				new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
			else
				new_csr6 = 0x82420000;
			break;
		}
		case 1: case 3: {
			int phy_num = p[0];
			int init_length = p[1];
			u16 *misc_info, tmp_info;

			dev->if_port = 11;
			new_csr6 = 0x020E0000;
			if (mleaf->type == 3) {	/* 21142 */
				u16 *init_sequence = (u16*)(p+2);
				u16 *reset_sequence = &((u16*)(p+3))[init_length];
				int reset_length = p[2 + init_length*2];
				misc_info = reset_sequence + reset_length;
				if (startup) {
					int timeout = 10;	/* max 1 ms */
					for (i = 0; i < reset_length; i++)
						iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);

					/* flush posted writes */
					ioread32(ioaddr + CSR15);

					/* Sect 3.10.3 in DP83840A.pdf (p39) */
					udelay(500);

Annotation

Implementation Notes