]>
Commit | Line | Data |
---|---|---|
25f3b3fc | 1 | --- linux.orig/drivers/net/3c59x.c Sun Sep 30 21:26:06 2001 |
2 | +++ linux/drivers/net/3c59x.c Wed Oct 24 21:52:10 2001 | |
3 | @@ -308,6 +308,9 @@ | |
4 | code size of a per-interface flag is not worthwhile. */ | |
5 | static char mii_preamble_required; | |
6 | ||
7 | +/* The Ethernet Type used for 802.1q tagged frames */ | |
8 | +#define VLAN_ETHER_TYPE 0x8100 | |
9 | + | |
10 | #define PFX DRV_NAME ": " | |
11 | ||
12 | ||
13 | @@ -651,7 +654,7 @@ | |
14 | Wn2_ResetOptions=12, | |
15 | }; | |
16 | enum Window3 { /* Window 3: MAC/config bits. */ | |
17 | - Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8, | |
18 | + Wn3_Config=0, Wn3_MaxPktSize=4, Wn3_MAC_Ctrl=6, Wn3_Options=8, | |
19 | }; | |
20 | ||
21 | #define BFEXT(value, offset, bitcount) \ | |
22 | @@ -679,7 +682,8 @@ | |
23 | Media_LnkBeat = 0x0800, | |
24 | }; | |
25 | enum Window7 { /* Window 7: Bus Master control. */ | |
26 | - Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12, | |
27 | + Wn7_MasterAddr = 0, Wn7_VlanEtherType=4, Wn7_MasterLen = 6, | |
28 | + Wn7_MasterStatus = 12, | |
29 | }; | |
30 | /* Boomerang bus master control registers. */ | |
31 | enum MasterCtrl { | |
32 | @@ -776,7 +780,8 @@ | |
33 | pm_state_valid:1, /* power_state[] has sane contents */ | |
34 | open:1, | |
35 | medialock:1, | |
36 | - must_free_region:1; /* Flag: if zero, Cardbus owns the I/O region */ | |
37 | + must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ | |
38 | + large_frames:1; /* accept large frames */ | |
39 | int drv_flags; | |
40 | u16 status_enable; | |
41 | u16 intr_enable; | |
42 | @@ -844,6 +849,9 @@ | |
43 | static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | |
44 | static void vortex_tx_timeout(struct net_device *dev); | |
45 | static void acpi_set_WOL(struct net_device *dev); | |
46 | +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | |
47 | +static void set_8021q_mode(struct net_device *dev, int enable); | |
48 | +#endif | |
49 | \f | |
50 | /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */ | |
51 | /* Option count limit only -- unlimited interfaces are supported. */ | |
52 | @@ -1030,6 +1038,7 @@ | |
53 | dev->base_addr = ioaddr; | |
54 | dev->irq = irq; | |
55 | dev->mtu = mtu; | |
56 | + vp->large_frames = mtu > 1500; | |
57 | vp->drv_flags = vci->drv_flags; | |
58 | vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0; | |
59 | vp->io_size = vci->io_size; | |
60 | @@ -1461,7 +1470,7 @@ | |
61 | ||
62 | /* Set the full-duplex bit. */ | |
63 | outw( ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) | | |
64 | - (dev->mtu > 1500 ? 0x40 : 0) | | |
65 | + (vp->large_frames ? 0x40 : 0) | | |
66 | ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0), | |
67 | ioaddr + Wn3_MAC_Ctrl); | |
68 | ||
69 | @@ -1545,6 +1554,10 @@ | |
70 | } | |
71 | /* Set receiver mode: presumably accept b-case and phys addr only. */ | |
72 | set_rx_mode(dev); | |
73 | +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | |
74 | + /* enable 802.1q tagged frames */ | |
75 | + set_8021q_mode(dev, 1); | |
76 | +#endif | |
77 | outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ | |
78 | ||
79 | // issue_and_wait(dev, SetTxStart|0x07ff); | |
80 | @@ -1680,7 +1693,7 @@ | |
81 | /* Set the full-duplex bit. */ | |
82 | EL3WINDOW(3); | |
83 | outw( (vp->full_duplex ? 0x20 : 0) | | |
84 | - (dev->mtu > 1500 ? 0x40 : 0) | | |
85 | + (vp->large_frames ? 0x40 : 0) | | |
86 | ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0), | |
87 | ioaddr + Wn3_MAC_Ctrl); | |
88 | if (vortex_debug > 1) | |
89 | @@ -1900,6 +1913,10 @@ | |
90 | issue_and_wait(dev, RxReset|0x07); | |
91 | /* Set the Rx filter to the current state. */ | |
92 | set_rx_mode(dev); | |
93 | +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | |
94 | + /* enable 802.1q VLAN tagged frames */ | |
95 | + set_8021q_mode(dev, 1); | |
96 | +#endif | |
97 | outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */ | |
98 | outw(AckIntr | HostError, ioaddr + EL3_CMD); | |
99 | } | |
100 | @@ -2497,6 +2514,11 @@ | |
101 | outw(RxDisable, ioaddr + EL3_CMD); | |
102 | outw(TxDisable, ioaddr + EL3_CMD); | |
103 | ||
104 | +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | |
105 | + /* Disable receiving 802.1q tagged frames */ | |
106 | + set_8021q_mode(dev, 0); | |
107 | +#endif | |
108 | + | |
109 | if (dev->if_port == XCVR_10base2) | |
110 | /* Turn off thinnet power. Green! */ | |
111 | outw(StopCoax, ioaddr + EL3_CMD); | |
112 | @@ -2760,6 +2782,50 @@ | |
113 | ||
114 | outw(new_mode, ioaddr + EL3_CMD); | |
115 | } | |
116 | + | |
117 | +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | |
118 | +/* Setup the card so that it can receive frames with an 802.1q VLAN tag. | |
119 | + Note that this must be done after each RxReset due to some backwards | |
120 | + compatibility logic in the Cyclone and Tornado ASICs */ | |
121 | +static void set_8021q_mode(struct net_device *dev, int enable) | |
122 | +{ | |
123 | + struct vortex_private *vp = (struct vortex_private *)dev->priv; | |
124 | + long ioaddr = dev->base_addr; | |
125 | + int old_window = inw(ioaddr + EL3_CMD); | |
126 | + int mac_ctrl; | |
127 | + | |
128 | + if (vp->drv_flags&IS_CYCLONE || vp->drv_flags&IS_TORNADO) { | |
129 | + /* cyclone and tornado chipsets can recognize 802.1q | |
130 | + * tagged frames and treat them correctly */ | |
131 | + | |
132 | + int max_pkt_size = dev->mtu+14; /* MTU+Ethernet header */ | |
133 | + if (enable) | |
134 | + max_pkt_size += 4; /* 802.1Q VLAN tag */ | |
135 | + | |
136 | + EL3WINDOW(3); | |
137 | + outw(max_pkt_size, ioaddr+Wn3_MaxPktSize); | |
138 | + | |
139 | + /* set VlanEtherType to let the hardware checksumming | |
140 | + treat tagged frames correctly */ | |
141 | + EL3WINDOW(7); | |
142 | + outw(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType); | |
143 | + } else { | |
144 | + /* on older cards we have to enable large frames */ | |
145 | + | |
146 | + vp->large_frames = dev->mtu > 1500 || enable; | |
147 | + | |
148 | + EL3WINDOW(3); | |
149 | + mac_ctrl = inw(ioaddr+Wn3_MAC_Ctrl); | |
150 | + if (vp->large_frames) | |
151 | + mac_ctrl |= 0x40; | |
152 | + else | |
153 | + mac_ctrl &= ~0x40; | |
154 | + outw(mac_ctrl, ioaddr+Wn3_MAC_Ctrl); | |
155 | + } | |
156 | + | |
157 | + EL3WINDOW(old_window); | |
158 | +} | |
159 | +#endif | |
160 | ||
161 | /* MII transceiver control section. | |
162 | Read and write the MII registers using software-generated serial |