1 | /************************************************************************** |
---|
2 | * |
---|
3 | * dmfe.c -- Etherboot device driver for the Davicom |
---|
4 | * DM9102/DM9102A/DM9102A+DM9801/DM9102A+DM9802 NIC fast ethernet card |
---|
5 | * |
---|
6 | * Written 2003-2003 by Timothy Legge <tlegge@rogers.com> |
---|
7 | * |
---|
8 | * This program is free software; you can redistribute it and/or modify |
---|
9 | * it under the terms of the GNU General Public License as published by |
---|
10 | * the Free Software Foundation; either version 2 of the License, or |
---|
11 | * (at your option) any later version. |
---|
12 | * |
---|
13 | * This program is distributed in the hope that it will be useful, |
---|
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
16 | * GNU General Public License for more details. |
---|
17 | * |
---|
18 | * You should have received a copy of the GNU General Public License |
---|
19 | * along with this program; if not, write to the Free Software |
---|
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
21 | * |
---|
22 | * Portions of this code based on: |
---|
23 | * |
---|
24 | * dmfe.c: A Davicom DM9102/DM9102A/DM9102A+DM9801/DM9102A+DM9802 |
---|
25 | * NIC fast ethernet driver for Linux. |
---|
26 | * Copyright (C) 1997 Sten Wang |
---|
27 | * (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved. |
---|
28 | * |
---|
29 | * |
---|
30 | * REVISION HISTORY: |
---|
31 | * ================ |
---|
32 | * v1.0 10-02-2004 timlegge Boots ltsp needs cleanup |
---|
33 | * |
---|
34 | * Indent Options: indent -kr -i8 |
---|
35 | * |
---|
36 | * |
---|
37 | ***************************************************************************/ |
---|
38 | |
---|
39 | FILE_LICENCE ( GPL2_OR_LATER ); |
---|
40 | |
---|
41 | /* to get some global routines like printf */ |
---|
42 | #include "etherboot.h" |
---|
43 | /* to get the interface to the body of the program */ |
---|
44 | #include "nic.h" |
---|
45 | /* to get the PCI support functions, if this is a PCI NIC */ |
---|
46 | #include <gpxe/pci.h> |
---|
47 | #include <gpxe/ethernet.h> |
---|
48 | |
---|
49 | /* #define EDEBUG 1 */ |
---|
50 | #ifdef EDEBUG |
---|
51 | #define dprintf(x) printf x |
---|
52 | #else |
---|
53 | #define dprintf(x) |
---|
54 | #endif |
---|
55 | |
---|
56 | /* Condensed operations for readability. */ |
---|
57 | #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) |
---|
58 | #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) |
---|
59 | |
---|
60 | /* Board/System/Debug information/definition ---------------- */ |
---|
61 | #define PCI_DM9132_ID 0x91321282 /* Davicom DM9132 ID */ |
---|
62 | #define PCI_DM9102_ID 0x91021282 /* Davicom DM9102 ID */ |
---|
63 | #define PCI_DM9100_ID 0x91001282 /* Davicom DM9100 ID */ |
---|
64 | #define PCI_DM9009_ID 0x90091282 /* Davicom DM9009 ID */ |
---|
65 | |
---|
66 | #define DM9102_IO_SIZE 0x80 |
---|
67 | #define DM9102A_IO_SIZE 0x100 |
---|
68 | #define TX_MAX_SEND_CNT 0x1 /* Maximum tx packet per time */ |
---|
69 | #define TX_DESC_CNT 0x10 /* Allocated Tx descriptors */ |
---|
70 | #define RX_DESC_CNT 0x20 /* Allocated Rx descriptors */ |
---|
71 | #define TX_FREE_DESC_CNT (TX_DESC_CNT - 2) /* Max TX packet count */ |
---|
72 | #define TX_WAKE_DESC_CNT (TX_DESC_CNT - 3) /* TX wakeup count */ |
---|
73 | #define DESC_ALL_CNT (TX_DESC_CNT + RX_DESC_CNT) |
---|
74 | #define TX_BUF_ALLOC 0x600 |
---|
75 | #define RX_ALLOC_SIZE 0x620 |
---|
76 | #define DM910X_RESET 1 |
---|
77 | #define CR0_DEFAULT 0x00E00000 /* TX & RX burst mode */ |
---|
78 | #define CR6_DEFAULT 0x00080000 /* HD */ |
---|
79 | #define CR7_DEFAULT 0x180c1 |
---|
80 | #define CR15_DEFAULT 0x06 /* TxJabber RxWatchdog */ |
---|
81 | #define TDES0_ERR_MASK 0x4302 /* TXJT, LC, EC, FUE */ |
---|
82 | #define MAX_PACKET_SIZE 1514 |
---|
83 | #define DMFE_MAX_MULTICAST 14 |
---|
84 | #define RX_COPY_SIZE 100 |
---|
85 | #define MAX_CHECK_PACKET 0x8000 |
---|
86 | #define DM9801_NOISE_FLOOR 8 |
---|
87 | #define DM9802_NOISE_FLOOR 5 |
---|
88 | |
---|
89 | #define DMFE_10MHF 0 |
---|
90 | #define DMFE_100MHF 1 |
---|
91 | #define DMFE_10MFD 4 |
---|
92 | #define DMFE_100MFD 5 |
---|
93 | #define DMFE_AUTO 8 |
---|
94 | #define DMFE_1M_HPNA 0x10 |
---|
95 | |
---|
96 | #define DMFE_TXTH_72 0x400000 /* TX TH 72 byte */ |
---|
97 | #define DMFE_TXTH_96 0x404000 /* TX TH 96 byte */ |
---|
98 | #define DMFE_TXTH_128 0x0000 /* TX TH 128 byte */ |
---|
99 | #define DMFE_TXTH_256 0x4000 /* TX TH 256 byte */ |
---|
100 | #define DMFE_TXTH_512 0x8000 /* TX TH 512 byte */ |
---|
101 | #define DMFE_TXTH_1K 0xC000 /* TX TH 1K byte */ |
---|
102 | |
---|
103 | #define DMFE_TIMER_WUT (jiffies + HZ * 1) /* timer wakeup time : 1 second */ |
---|
104 | #define DMFE_TX_TIMEOUT ((3*HZ)/2) /* tx packet time-out time 1.5 s" */ |
---|
105 | #define DMFE_TX_KICK (HZ/2) /* tx packet Kick-out time 0.5 s" */ |
---|
106 | |
---|
107 | #define DMFE_DBUG(dbug_now, msg, value) if (dmfe_debug || (dbug_now)) printk(KERN_ERR DRV_NAME ": %s %lx\n", (msg), (long) (value)) |
---|
108 | |
---|
109 | #define SHOW_MEDIA_TYPE(mode) printk(KERN_ERR DRV_NAME ": Change Speed to %sMhz %s duplex\n",mode & 1 ?"100":"10", mode & 4 ? "full":"half"); |
---|
110 | |
---|
111 | |
---|
112 | /* CR9 definition: SROM/MII */ |
---|
113 | #define CR9_SROM_READ 0x4800 |
---|
114 | #define CR9_SRCS 0x1 |
---|
115 | #define CR9_SRCLK 0x2 |
---|
116 | #define CR9_CRDOUT 0x8 |
---|
117 | #define SROM_DATA_0 0x0 |
---|
118 | #define SROM_DATA_1 0x4 |
---|
119 | #define PHY_DATA_1 0x20000 |
---|
120 | #define PHY_DATA_0 0x00000 |
---|
121 | #define MDCLKH 0x10000 |
---|
122 | |
---|
123 | #define PHY_POWER_DOWN 0x800 |
---|
124 | |
---|
125 | #define SROM_V41_CODE 0x14 |
---|
126 | |
---|
127 | #define SROM_CLK_WRITE(data, ioaddr) outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5); |
---|
128 | |
---|
129 | #define __CHK_IO_SIZE(pci_id, dev_rev) ( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x02000030) ) ? DM9102A_IO_SIZE: DM9102_IO_SIZE |
---|
130 | #define CHK_IO_SIZE(pci_dev, dev_rev) __CHK_IO_SIZE(((pci_dev)->device << 16) | (pci_dev)->vendor, dev_rev) |
---|
131 | |
---|
132 | /* Sten Check */ |
---|
133 | #define DEVICE net_device |
---|
134 | |
---|
135 | /* Structure/enum declaration ------------------------------- */ |
---|
136 | struct tx_desc { |
---|
137 | u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */ |
---|
138 | void * tx_buf_ptr; /* Data for us */ |
---|
139 | struct tx_desc * next_tx_desc; |
---|
140 | } __attribute__ ((aligned(32))); |
---|
141 | |
---|
142 | struct rx_desc { |
---|
143 | u32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */ |
---|
144 | void * rx_skb_ptr; /* Data for us */ |
---|
145 | struct rx_desc * next_rx_desc; |
---|
146 | } __attribute__ ((aligned(32))); |
---|
147 | |
---|
148 | static struct dmfe_private { |
---|
149 | u32 chip_id; /* Chip vendor/Device ID */ |
---|
150 | u32 chip_revision; /* Chip revision */ |
---|
151 | u32 cr0_data; |
---|
152 | // u32 cr5_data; |
---|
153 | u32 cr6_data; |
---|
154 | u32 cr7_data; |
---|
155 | u32 cr15_data; |
---|
156 | |
---|
157 | u16 HPNA_command; /* For HPNA register 16 */ |
---|
158 | u16 HPNA_timer; /* For HPNA remote device check */ |
---|
159 | u16 NIC_capability; /* NIC media capability */ |
---|
160 | u16 PHY_reg4; /* Saved Phyxcer register 4 value */ |
---|
161 | |
---|
162 | u8 HPNA_present; /* 0:none, 1:DM9801, 2:DM9802 */ |
---|
163 | u8 chip_type; /* Keep DM9102A chip type */ |
---|
164 | u8 media_mode; /* user specify media mode */ |
---|
165 | u8 op_mode; /* real work media mode */ |
---|
166 | u8 phy_addr; |
---|
167 | u8 dm910x_chk_mode; /* Operating mode check */ |
---|
168 | |
---|
169 | /* NIC SROM data */ |
---|
170 | unsigned char srom[128]; |
---|
171 | /* Etherboot Only */ |
---|
172 | u8 cur_tx; |
---|
173 | u8 cur_rx; |
---|
174 | } dfx; |
---|
175 | |
---|
176 | static struct dmfe_private *db; |
---|
177 | |
---|
178 | enum dmfe_offsets { |
---|
179 | DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20, |
---|
180 | DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48, |
---|
181 | DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 = |
---|
182 | 0x70, |
---|
183 | DCR15 = 0x78 |
---|
184 | }; |
---|
185 | |
---|
186 | enum dmfe_CR6_bits { |
---|
187 | CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80, |
---|
188 | CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000, |
---|
189 | CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000 |
---|
190 | }; |
---|
191 | |
---|
192 | /* Global variable declaration ----------------------------- */ |
---|
193 | static struct nic_operations dmfe_operations; |
---|
194 | |
---|
195 | static unsigned char dmfe_media_mode = DMFE_AUTO; |
---|
196 | static u32 dmfe_cr6_user_set; |
---|
197 | |
---|
198 | /* For module input parameter */ |
---|
199 | static u8 chkmode = 1; |
---|
200 | static u8 HPNA_mode; /* Default: Low Power/High Speed */ |
---|
201 | static u8 HPNA_rx_cmd; /* Default: Disable Rx remote command */ |
---|
202 | static u8 HPNA_tx_cmd; /* Default: Don't issue remote command */ |
---|
203 | static u8 HPNA_NoiseFloor; /* Default: HPNA NoiseFloor */ |
---|
204 | static u8 SF_mode; /* Special Function: 1:VLAN, 2:RX Flow Control |
---|
205 | 4: TX pause packet */ |
---|
206 | |
---|
207 | |
---|
208 | /********************************************** |
---|
209 | * Descriptor Ring and Buffer defination |
---|
210 | ***********************************************/ |
---|
211 | struct { |
---|
212 | struct tx_desc txd[TX_DESC_CNT] __attribute__ ((aligned(32))); |
---|
213 | unsigned char txb[TX_BUF_ALLOC * TX_DESC_CNT] |
---|
214 | __attribute__ ((aligned(32))); |
---|
215 | struct rx_desc rxd[RX_DESC_CNT] __attribute__ ((aligned(32))); |
---|
216 | unsigned char rxb[RX_ALLOC_SIZE * RX_DESC_CNT] |
---|
217 | __attribute__ ((aligned(32))); |
---|
218 | } dmfe_bufs __shared; |
---|
219 | #define txd dmfe_bufs.txd |
---|
220 | #define txb dmfe_bufs.txb |
---|
221 | #define rxd dmfe_bufs.rxd |
---|
222 | #define rxb dmfe_bufs.rxb |
---|
223 | |
---|
224 | /* NIC specific static variables go here */ |
---|
225 | static long int BASE; |
---|
226 | |
---|
227 | static u16 read_srom_word(long ioaddr, int offset); |
---|
228 | static void dmfe_init_dm910x(struct nic *nic); |
---|
229 | static void dmfe_descriptor_init(struct nic *, unsigned long ioaddr); |
---|
230 | static void update_cr6(u32, unsigned long); |
---|
231 | static void send_filter_frame(struct nic *nic); |
---|
232 | static void dm9132_id_table(struct nic *nic); |
---|
233 | |
---|
234 | static u16 phy_read(unsigned long, u8, u8, u32); |
---|
235 | static void phy_write(unsigned long, u8, u8, u16, u32); |
---|
236 | static void phy_write_1bit(unsigned long, u32); |
---|
237 | static u16 phy_read_1bit(unsigned long); |
---|
238 | static void dmfe_set_phyxcer(struct nic *nic); |
---|
239 | |
---|
240 | static void dmfe_parse_srom(struct nic *nic); |
---|
241 | static void dmfe_program_DM9801(struct nic *nic, int); |
---|
242 | static void dmfe_program_DM9802(struct nic *nic); |
---|
243 | |
---|
244 | static void dmfe_reset(struct nic *nic) |
---|
245 | { |
---|
246 | /* system variable init */ |
---|
247 | db->cr6_data = CR6_DEFAULT | dmfe_cr6_user_set; |
---|
248 | |
---|
249 | db->NIC_capability = 0xf; /* All capability */ |
---|
250 | db->PHY_reg4 = 0x1e0; |
---|
251 | |
---|
252 | /* CR6 operation mode decision */ |
---|
253 | if (!chkmode || (db->chip_id == PCI_DM9132_ID) || |
---|
254 | (db->chip_revision >= 0x02000030)) { |
---|
255 | db->cr6_data |= DMFE_TXTH_256; |
---|
256 | db->cr0_data = CR0_DEFAULT; |
---|
257 | db->dm910x_chk_mode = 4; /* Enter the normal mode */ |
---|
258 | } else { |
---|
259 | db->cr6_data |= CR6_SFT; /* Store & Forward mode */ |
---|
260 | db->cr0_data = 0; |
---|
261 | db->dm910x_chk_mode = 1; /* Enter the check mode */ |
---|
262 | } |
---|
263 | /* Initilize DM910X board */ |
---|
264 | dmfe_init_dm910x(nic); |
---|
265 | |
---|
266 | return; |
---|
267 | } |
---|
268 | |
---|
269 | /* Initilize DM910X board |
---|
270 | * Reset DM910X board |
---|
271 | * Initilize TX/Rx descriptor chain structure |
---|
272 | * Send the set-up frame |
---|
273 | * Enable Tx/Rx machine |
---|
274 | */ |
---|
275 | |
---|
276 | static void dmfe_init_dm910x(struct nic *nic) |
---|
277 | { |
---|
278 | unsigned long ioaddr = BASE; |
---|
279 | |
---|
280 | /* Reset DM910x MAC controller */ |
---|
281 | outl(DM910X_RESET, ioaddr + DCR0); /* RESET MAC */ |
---|
282 | udelay(100); |
---|
283 | outl(db->cr0_data, ioaddr + DCR0); |
---|
284 | udelay(5); |
---|
285 | |
---|
286 | /* Phy addr : DM910(A)2/DM9132/9801, phy address = 1 */ |
---|
287 | db->phy_addr = 1; |
---|
288 | |
---|
289 | /* Parser SROM and media mode */ |
---|
290 | dmfe_parse_srom(nic); |
---|
291 | db->media_mode = dmfe_media_mode; |
---|
292 | |
---|
293 | /* RESET Phyxcer Chip by GPR port bit 7 */ |
---|
294 | outl(0x180, ioaddr + DCR12); /* Let bit 7 output port */ |
---|
295 | if (db->chip_id == PCI_DM9009_ID) { |
---|
296 | outl(0x80, ioaddr + DCR12); /* Issue RESET signal */ |
---|
297 | mdelay(300); /* Delay 300 ms */ |
---|
298 | } |
---|
299 | outl(0x0, ioaddr + DCR12); /* Clear RESET signal */ |
---|
300 | |
---|
301 | /* Process Phyxcer Media Mode */ |
---|
302 | if (!(db->media_mode & 0x10)) /* Force 1M mode */ |
---|
303 | dmfe_set_phyxcer(nic); |
---|
304 | |
---|
305 | /* Media Mode Process */ |
---|
306 | if (!(db->media_mode & DMFE_AUTO)) |
---|
307 | db->op_mode = db->media_mode; /* Force Mode */ |
---|
308 | |
---|
309 | /* Initiliaze Transmit/Receive decriptor and CR3/4 */ |
---|
310 | dmfe_descriptor_init(nic, ioaddr); |
---|
311 | |
---|
312 | /* tx descriptor start pointer */ |
---|
313 | outl(virt_to_le32desc(&txd[0]), ioaddr + DCR4); /* TX DESC address */ |
---|
314 | |
---|
315 | /* rx descriptor start pointer */ |
---|
316 | outl(virt_to_le32desc(&rxd[0]), ioaddr + DCR3); /* RX DESC address */ |
---|
317 | |
---|
318 | /* Init CR6 to program DM910x operation */ |
---|
319 | update_cr6(db->cr6_data, ioaddr); |
---|
320 | |
---|
321 | /* Send setup frame */ |
---|
322 | if (db->chip_id == PCI_DM9132_ID) { |
---|
323 | dm9132_id_table(nic); /* DM9132 */ |
---|
324 | } else { |
---|
325 | send_filter_frame(nic); /* DM9102/DM9102A */ |
---|
326 | } |
---|
327 | |
---|
328 | /* Init CR7, interrupt active bit */ |
---|
329 | db->cr7_data = CR7_DEFAULT; |
---|
330 | outl(db->cr7_data, ioaddr + DCR7); |
---|
331 | /* Init CR15, Tx jabber and Rx watchdog timer */ |
---|
332 | outl(db->cr15_data, ioaddr + DCR15); |
---|
333 | /* Enable DM910X Tx/Rx function */ |
---|
334 | db->cr6_data |= CR6_RXSC | CR6_TXSC | 0x40000; |
---|
335 | update_cr6(db->cr6_data, ioaddr); |
---|
336 | } |
---|
337 | #ifdef EDEBUG |
---|
338 | void hex_dump(const char *data, const unsigned int len); |
---|
339 | #endif |
---|
340 | /************************************************************************** |
---|
341 | POLL - Wait for a frame |
---|
342 | ***************************************************************************/ |
---|
343 | static int dmfe_poll(struct nic *nic, int retrieve) |
---|
344 | { |
---|
345 | u32 rdes0; |
---|
346 | int entry = db->cur_rx % RX_DESC_CNT; |
---|
347 | int rxlen; |
---|
348 | rdes0 = le32_to_cpu(rxd[entry].rdes0); |
---|
349 | if (rdes0 & 0x80000000) |
---|
350 | return 0; |
---|
351 | |
---|
352 | if (!retrieve) |
---|
353 | return 1; |
---|
354 | |
---|
355 | if ((rdes0 & 0x300) != 0x300) { |
---|
356 | /* A packet without First/Last flag */ |
---|
357 | printf("strange Packet\n"); |
---|
358 | rxd[entry].rdes0 = cpu_to_le32(0x80000000); |
---|
359 | return 0; |
---|
360 | } else { |
---|
361 | /* A packet with First/Last flag */ |
---|
362 | rxlen = ((rdes0 >> 16) & 0x3fff) - 4; |
---|
363 | /* error summary bit check */ |
---|
364 | if (rdes0 & 0x8000) { |
---|
365 | printf("Error\n"); |
---|
366 | return 0; |
---|
367 | } |
---|
368 | if (!(rdes0 & 0x8000) || |
---|
369 | ((db->cr6_data & CR6_PM) && (rxlen > 6))) { |
---|
370 | if (db->dm910x_chk_mode & 1) |
---|
371 | printf("Silly check mode\n"); |
---|
372 | |
---|
373 | nic->packetlen = rxlen; |
---|
374 | memcpy(nic->packet, rxb + (entry * RX_ALLOC_SIZE), |
---|
375 | nic->packetlen); |
---|
376 | } |
---|
377 | } |
---|
378 | rxd[entry].rdes0 = cpu_to_le32(0x80000000); |
---|
379 | db->cur_rx++; |
---|
380 | return 1; |
---|
381 | } |
---|
382 | |
---|
383 | static void dmfe_irq(struct nic *nic __unused, irq_action_t action __unused) |
---|
384 | { |
---|
385 | switch ( action ) { |
---|
386 | case DISABLE : |
---|
387 | break; |
---|
388 | case ENABLE : |
---|
389 | break; |
---|
390 | case FORCE : |
---|
391 | break; |
---|
392 | } |
---|
393 | } |
---|
394 | |
---|
395 | /************************************************************************** |
---|
396 | TRANSMIT - Transmit a frame |
---|
397 | ***************************************************************************/ |
---|
398 | static void dmfe_transmit(struct nic *nic, |
---|
399 | const char *dest, /* Destination */ |
---|
400 | unsigned int type, /* Type */ |
---|
401 | unsigned int size, /* size */ |
---|
402 | const char *packet) /* Packet */ |
---|
403 | { |
---|
404 | u16 nstype; |
---|
405 | u8 *ptxb; |
---|
406 | |
---|
407 | ptxb = &txb[db->cur_tx]; |
---|
408 | |
---|
409 | /* Stop Tx */ |
---|
410 | outl(0, BASE + DCR7); |
---|
411 | memcpy(ptxb, dest, ETH_ALEN); |
---|
412 | memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); |
---|
413 | nstype = htons((u16) type); |
---|
414 | memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); |
---|
415 | memcpy(ptxb + ETH_HLEN, packet, size); |
---|
416 | |
---|
417 | size += ETH_HLEN; |
---|
418 | while (size < ETH_ZLEN) |
---|
419 | ptxb[size++] = '\0'; |
---|
420 | |
---|
421 | /* setup the transmit descriptor */ |
---|
422 | txd[db->cur_tx].tdes1 = cpu_to_le32(0xe1000000 | size); |
---|
423 | txd[db->cur_tx].tdes0 = cpu_to_le32(0x80000000); /* give ownership to device */ |
---|
424 | |
---|
425 | /* immediate transmit demand */ |
---|
426 | outl(0x1, BASE + DCR1); |
---|
427 | outl(db->cr7_data, BASE + DCR7); |
---|
428 | |
---|
429 | /* Point to next TX descriptor */ |
---|
430 | db->cur_tx++; |
---|
431 | db->cur_tx = db->cur_tx % TX_DESC_CNT; |
---|
432 | } |
---|
433 | |
---|
434 | /************************************************************************** |
---|
435 | DISABLE - Turn off ethernet interface |
---|
436 | ***************************************************************************/ |
---|
437 | static void dmfe_disable ( struct nic *nic __unused ) { |
---|
438 | /* Reset & stop DM910X board */ |
---|
439 | outl(DM910X_RESET, BASE + DCR0); |
---|
440 | udelay(5); |
---|
441 | phy_write(BASE, db->phy_addr, 0, 0x8000, db->chip_id); |
---|
442 | |
---|
443 | } |
---|
444 | |
---|
445 | /************************************************************************** |
---|
446 | PROBE - Look for an adapter, this routine's visible to the outside |
---|
447 | ***************************************************************************/ |
---|
448 | |
---|
449 | #define board_found 1 |
---|
450 | #define valid_link 0 |
---|
451 | static int dmfe_probe ( struct nic *nic, struct pci_device *pci ) { |
---|
452 | |
---|
453 | uint32_t dev_rev, pci_pmr; |
---|
454 | int i; |
---|
455 | |
---|
456 | if (pci->ioaddr == 0) |
---|
457 | return 0; |
---|
458 | |
---|
459 | BASE = pci->ioaddr; |
---|
460 | printf("dmfe.c: Found %s Vendor=0x%hX Device=0x%hX\n", |
---|
461 | pci->driver_name, pci->vendor, pci->device); |
---|
462 | |
---|
463 | /* Read Chip revision */ |
---|
464 | pci_read_config_dword(pci, PCI_REVISION_ID, &dev_rev); |
---|
465 | dprintf(("Revision %lX\n", dev_rev)); |
---|
466 | |
---|
467 | /* point to private storage */ |
---|
468 | db = &dfx; |
---|
469 | |
---|
470 | db->chip_id = ((u32) pci->device << 16) | pci->vendor; |
---|
471 | BASE = pci_bar_start(pci, PCI_BASE_ADDRESS_0); |
---|
472 | db->chip_revision = dev_rev; |
---|
473 | |
---|
474 | pci_read_config_dword(pci, 0x50, &pci_pmr); |
---|
475 | pci_pmr &= 0x70000; |
---|
476 | if ((pci_pmr == 0x10000) && (dev_rev == 0x02000031)) |
---|
477 | db->chip_type = 1; /* DM9102A E3 */ |
---|
478 | else |
---|
479 | db->chip_type = 0; |
---|
480 | |
---|
481 | dprintf(("Chip type : %d\n", db->chip_type)); |
---|
482 | |
---|
483 | /* read 64 word srom data */ |
---|
484 | for (i = 0; i < 64; i++) |
---|
485 | ((u16 *) db->srom)[i] = cpu_to_le16(read_srom_word(BASE, i)); |
---|
486 | |
---|
487 | /* Set Node address */ |
---|
488 | for (i = 0; i < 6; i++) |
---|
489 | nic->node_addr[i] = db->srom[20 + i]; |
---|
490 | |
---|
491 | /* Print out some hardware info */ |
---|
492 | DBG ( "%s: %s at ioaddr %4.4lx\n", pci->driver_name, eth_ntoa ( nic->node_addr ), BASE ); |
---|
493 | |
---|
494 | /* Set the card as PCI Bus Master */ |
---|
495 | adjust_pci_device(pci); |
---|
496 | |
---|
497 | dmfe_reset(nic); |
---|
498 | |
---|
499 | nic->irqno = 0; |
---|
500 | nic->ioaddr = pci->ioaddr; |
---|
501 | |
---|
502 | /* point to NIC specific routines */ |
---|
503 | nic->nic_op = &dmfe_operations; |
---|
504 | |
---|
505 | return 1; |
---|
506 | } |
---|
507 | |
---|
508 | /* |
---|
509 | * Initialize transmit/Receive descriptor |
---|
510 | * Using Chain structure, and allocate Tx/Rx buffer |
---|
511 | */ |
---|
512 | |
---|
513 | static void dmfe_descriptor_init(struct nic *nic __unused, unsigned long ioaddr) |
---|
514 | { |
---|
515 | int i; |
---|
516 | db->cur_tx = 0; |
---|
517 | db->cur_rx = 0; |
---|
518 | |
---|
519 | /* tx descriptor start pointer */ |
---|
520 | outl(virt_to_le32desc(&txd[0]), ioaddr + DCR4); /* TX DESC address */ |
---|
521 | |
---|
522 | /* rx descriptor start pointer */ |
---|
523 | outl(virt_to_le32desc(&rxd[0]), ioaddr + DCR3); /* RX DESC address */ |
---|
524 | |
---|
525 | /* Init Transmit chain */ |
---|
526 | for (i = 0; i < TX_DESC_CNT; i++) { |
---|
527 | txd[i].tx_buf_ptr = &txb[i]; |
---|
528 | txd[i].tdes0 = cpu_to_le32(0); |
---|
529 | txd[i].tdes1 = cpu_to_le32(0x81000000); /* IC, chain */ |
---|
530 | txd[i].tdes2 = cpu_to_le32(virt_to_bus(&txb[i])); |
---|
531 | txd[i].tdes3 = cpu_to_le32(virt_to_bus(&txd[i + 1])); |
---|
532 | txd[i].next_tx_desc = &txd[i + 1]; |
---|
533 | } |
---|
534 | /* Mark the last entry as wrapping the ring */ |
---|
535 | txd[i - 1].tdes3 = virt_to_le32desc(&txd[0]); |
---|
536 | txd[i - 1].next_tx_desc = &txd[0]; |
---|
537 | |
---|
538 | /* receive descriptor chain */ |
---|
539 | for (i = 0; i < RX_DESC_CNT; i++) { |
---|
540 | rxd[i].rx_skb_ptr = &rxb[i * RX_ALLOC_SIZE]; |
---|
541 | rxd[i].rdes0 = cpu_to_le32(0x80000000); |
---|
542 | rxd[i].rdes1 = cpu_to_le32(0x01000600); |
---|
543 | rxd[i].rdes2 = |
---|
544 | cpu_to_le32(virt_to_bus(&rxb[i * RX_ALLOC_SIZE])); |
---|
545 | rxd[i].rdes3 = cpu_to_le32(virt_to_bus(&rxd[i + 1])); |
---|
546 | rxd[i].next_rx_desc = &rxd[i + 1]; |
---|
547 | } |
---|
548 | /* Mark the last entry as wrapping the ring */ |
---|
549 | rxd[i - 1].rdes3 = cpu_to_le32(virt_to_bus(&rxd[0])); |
---|
550 | rxd[i - 1].next_rx_desc = &rxd[0]; |
---|
551 | |
---|
552 | } |
---|
553 | |
---|
554 | /* |
---|
555 | * Update CR6 value |
---|
556 | * Firstly stop DM910X , then written value and start |
---|
557 | */ |
---|
558 | |
---|
559 | static void update_cr6(u32 cr6_data, unsigned long ioaddr) |
---|
560 | { |
---|
561 | u32 cr6_tmp; |
---|
562 | |
---|
563 | cr6_tmp = cr6_data & ~0x2002; /* stop Tx/Rx */ |
---|
564 | outl(cr6_tmp, ioaddr + DCR6); |
---|
565 | udelay(5); |
---|
566 | outl(cr6_data, ioaddr + DCR6); |
---|
567 | udelay(5); |
---|
568 | } |
---|
569 | |
---|
570 | |
---|
571 | /* |
---|
572 | * Send a setup frame for DM9132 |
---|
573 | * This setup frame initilize DM910X addres filter mode |
---|
574 | */ |
---|
575 | |
---|
576 | static void dm9132_id_table(struct nic *nic __unused) |
---|
577 | { |
---|
578 | #ifdef LINUX |
---|
579 | u16 *addrptr; |
---|
580 | u8 dmi_addr[8]; |
---|
581 | unsigned long ioaddr = BASE + 0xc0; /* ID Table */ |
---|
582 | u32 hash_val; |
---|
583 | u16 i, hash_table[4]; |
---|
584 | #endif |
---|
585 | dprintf(("dm9132_id_table\n")); |
---|
586 | |
---|
587 | printf("FIXME: This function is broken. If you have this card contact " |
---|
588 | "Timothy Legge at the etherboot-user list\n"); |
---|
589 | |
---|
590 | #ifdef LINUX |
---|
591 | //DMFE_DBUG(0, "dm9132_id_table()", 0); |
---|
592 | |
---|
593 | /* Node address */ |
---|
594 | addrptr = (u16 *) nic->node_addr; |
---|
595 | outw(addrptr[0], ioaddr); |
---|
596 | ioaddr += 4; |
---|
597 | outw(addrptr[1], ioaddr); |
---|
598 | ioaddr += 4; |
---|
599 | outw(addrptr[2], ioaddr); |
---|
600 | ioaddr += 4; |
---|
601 | |
---|
602 | /* Clear Hash Table */ |
---|
603 | for (i = 0; i < 4; i++) |
---|
604 | hash_table[i] = 0x0; |
---|
605 | |
---|
606 | /* broadcast address */ |
---|
607 | hash_table[3] = 0x8000; |
---|
608 | |
---|
609 | /* the multicast address in Hash Table : 64 bits */ |
---|
610 | for (mcptr = mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { |
---|
611 | hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f; |
---|
612 | hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16); |
---|
613 | } |
---|
614 | |
---|
615 | /* Write the hash table to MAC MD table */ |
---|
616 | for (i = 0; i < 4; i++, ioaddr += 4) |
---|
617 | outw(hash_table[i], ioaddr); |
---|
618 | #endif |
---|
619 | } |
---|
620 | |
---|
621 | |
---|
622 | /* |
---|
623 | * Send a setup frame for DM9102/DM9102A |
---|
624 | * This setup frame initilize DM910X addres filter mode |
---|
625 | */ |
---|
626 | |
---|
627 | static void send_filter_frame(struct nic *nic) |
---|
628 | { |
---|
629 | |
---|
630 | u8 *ptxb; |
---|
631 | int i; |
---|
632 | |
---|
633 | dprintf(("send_filter_frame\n")); |
---|
634 | /* point to the current txb incase multiple tx_rings are used */ |
---|
635 | ptxb = &txb[db->cur_tx]; |
---|
636 | |
---|
637 | /* construct perfect filter frame with mac address as first match |
---|
638 | and broadcast address for all others */ |
---|
639 | for (i = 0; i < 192; i++) |
---|
640 | ptxb[i] = 0xFF; |
---|
641 | ptxb[0] = nic->node_addr[0]; |
---|
642 | ptxb[1] = nic->node_addr[1]; |
---|
643 | ptxb[4] = nic->node_addr[2]; |
---|
644 | ptxb[5] = nic->node_addr[3]; |
---|
645 | ptxb[8] = nic->node_addr[4]; |
---|
646 | ptxb[9] = nic->node_addr[5]; |
---|
647 | |
---|
648 | /* prepare the setup frame */ |
---|
649 | txd[db->cur_tx].tdes1 = cpu_to_le32(0x890000c0); |
---|
650 | txd[db->cur_tx].tdes0 = cpu_to_le32(0x80000000); |
---|
651 | update_cr6(db->cr6_data | 0x2000, BASE); |
---|
652 | outl(0x1, BASE + DCR1); /* Issue Tx polling */ |
---|
653 | update_cr6(db->cr6_data, BASE); |
---|
654 | db->cur_tx++; |
---|
655 | } |
---|
656 | |
---|
657 | /* |
---|
658 | * Read one word data from the serial ROM |
---|
659 | */ |
---|
660 | |
---|
661 | static u16 read_srom_word(long ioaddr, int offset) |
---|
662 | { |
---|
663 | int i; |
---|
664 | u16 srom_data = 0; |
---|
665 | long cr9_ioaddr = ioaddr + DCR9; |
---|
666 | |
---|
667 | outl(CR9_SROM_READ, cr9_ioaddr); |
---|
668 | outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); |
---|
669 | |
---|
670 | /* Send the Read Command 110b */ |
---|
671 | SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); |
---|
672 | SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); |
---|
673 | SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr); |
---|
674 | |
---|
675 | /* Send the offset */ |
---|
676 | for (i = 5; i >= 0; i--) { |
---|
677 | srom_data = |
---|
678 | (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0; |
---|
679 | SROM_CLK_WRITE(srom_data, cr9_ioaddr); |
---|
680 | } |
---|
681 | |
---|
682 | outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); |
---|
683 | |
---|
684 | for (i = 16; i > 0; i--) { |
---|
685 | outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr); |
---|
686 | udelay(5); |
---|
687 | srom_data = |
---|
688 | (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 |
---|
689 | : 0); |
---|
690 | outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); |
---|
691 | udelay(5); |
---|
692 | } |
---|
693 | |
---|
694 | outl(CR9_SROM_READ, cr9_ioaddr); |
---|
695 | return srom_data; |
---|
696 | } |
---|
697 | |
---|
698 | |
---|
699 | /* |
---|
700 | * Auto sense the media mode |
---|
701 | */ |
---|
702 | |
---|
703 | #if 0 /* not used */ |
---|
704 | static u8 dmfe_sense_speed(struct nic *nic __unused) |
---|
705 | { |
---|
706 | u8 ErrFlag = 0; |
---|
707 | u16 phy_mode; |
---|
708 | |
---|
709 | /* CR6 bit18=0, select 10/100M */ |
---|
710 | update_cr6((db->cr6_data & ~0x40000), BASE); |
---|
711 | |
---|
712 | phy_mode = phy_read(BASE, db->phy_addr, 1, db->chip_id); |
---|
713 | phy_mode = phy_read(BASE, db->phy_addr, 1, db->chip_id); |
---|
714 | |
---|
715 | if ((phy_mode & 0x24) == 0x24) { |
---|
716 | if (db->chip_id == PCI_DM9132_ID) /* DM9132 */ |
---|
717 | phy_mode = |
---|
718 | phy_read(BASE, db->phy_addr, 7, |
---|
719 | db->chip_id) & 0xf000; |
---|
720 | else /* DM9102/DM9102A */ |
---|
721 | phy_mode = |
---|
722 | phy_read(BASE, db->phy_addr, 17, |
---|
723 | db->chip_id) & 0xf000; |
---|
724 | /* printk(DRV_NAME ": Phy_mode %x ",phy_mode); */ |
---|
725 | switch (phy_mode) { |
---|
726 | case 0x1000: |
---|
727 | db->op_mode = DMFE_10MHF; |
---|
728 | break; |
---|
729 | case 0x2000: |
---|
730 | db->op_mode = DMFE_10MFD; |
---|
731 | break; |
---|
732 | case 0x4000: |
---|
733 | db->op_mode = DMFE_100MHF; |
---|
734 | break; |
---|
735 | case 0x8000: |
---|
736 | db->op_mode = DMFE_100MFD; |
---|
737 | break; |
---|
738 | default: |
---|
739 | db->op_mode = DMFE_10MHF; |
---|
740 | ErrFlag = 1; |
---|
741 | break; |
---|
742 | } |
---|
743 | } else { |
---|
744 | db->op_mode = DMFE_10MHF; |
---|
745 | //DMFE_DBUG(0, "Link Failed :", phy_mode); |
---|
746 | ErrFlag = 1; |
---|
747 | } |
---|
748 | |
---|
749 | return ErrFlag; |
---|
750 | } |
---|
751 | #endif |
---|
752 | |
---|
753 | /* |
---|
754 | * Set 10/100 phyxcer capability |
---|
755 | * AUTO mode : phyxcer register4 is NIC capability |
---|
756 | * Force mode: phyxcer register4 is the force media |
---|
757 | */ |
---|
758 | |
---|
759 | static void dmfe_set_phyxcer(struct nic *nic __unused) |
---|
760 | { |
---|
761 | u16 phy_reg; |
---|
762 | |
---|
763 | /* Select 10/100M phyxcer */ |
---|
764 | db->cr6_data &= ~0x40000; |
---|
765 | update_cr6(db->cr6_data, BASE); |
---|
766 | |
---|
767 | /* DM9009 Chip: Phyxcer reg18 bit12=0 */ |
---|
768 | if (db->chip_id == PCI_DM9009_ID) { |
---|
769 | phy_reg = |
---|
770 | phy_read(BASE, db->phy_addr, 18, |
---|
771 | db->chip_id) & ~0x1000; |
---|
772 | phy_write(BASE, db->phy_addr, 18, phy_reg, db->chip_id); |
---|
773 | } |
---|
774 | |
---|
775 | /* Phyxcer capability setting */ |
---|
776 | phy_reg = phy_read(BASE, db->phy_addr, 4, db->chip_id) & ~0x01e0; |
---|
777 | |
---|
778 | if (db->media_mode & DMFE_AUTO) { |
---|
779 | /* AUTO Mode */ |
---|
780 | phy_reg |= db->PHY_reg4; |
---|
781 | } else { |
---|
782 | /* Force Mode */ |
---|
783 | switch (db->media_mode) { |
---|
784 | case DMFE_10MHF: |
---|
785 | phy_reg |= 0x20; |
---|
786 | break; |
---|
787 | case DMFE_10MFD: |
---|
788 | phy_reg |= 0x40; |
---|
789 | break; |
---|
790 | case DMFE_100MHF: |
---|
791 | phy_reg |= 0x80; |
---|
792 | break; |
---|
793 | case DMFE_100MFD: |
---|
794 | phy_reg |= 0x100; |
---|
795 | break; |
---|
796 | } |
---|
797 | if (db->chip_id == PCI_DM9009_ID) |
---|
798 | phy_reg &= 0x61; |
---|
799 | } |
---|
800 | |
---|
801 | /* Write new capability to Phyxcer Reg4 */ |
---|
802 | if (!(phy_reg & 0x01e0)) { |
---|
803 | phy_reg |= db->PHY_reg4; |
---|
804 | db->media_mode |= DMFE_AUTO; |
---|
805 | } |
---|
806 | phy_write(BASE, db->phy_addr, 4, phy_reg, db->chip_id); |
---|
807 | |
---|
808 | /* Restart Auto-Negotiation */ |
---|
809 | if (db->chip_type && (db->chip_id == PCI_DM9102_ID)) |
---|
810 | phy_write(BASE, db->phy_addr, 0, 0x1800, db->chip_id); |
---|
811 | if (!db->chip_type) |
---|
812 | phy_write(BASE, db->phy_addr, 0, 0x1200, db->chip_id); |
---|
813 | } |
---|
814 | |
---|
815 | |
---|
816 | /* |
---|
817 | * Process op-mode |
---|
818 | * AUTO mode : PHY controller in Auto-negotiation Mode |
---|
819 | * Force mode: PHY controller in force mode with HUB |
---|
820 | * N-way force capability with SWITCH |
---|
821 | */ |
---|
822 | |
---|
823 | #if 0 /* not used */ |
---|
824 | static void dmfe_process_mode(struct nic *nic __unused) |
---|
825 | { |
---|
826 | u16 phy_reg; |
---|
827 | |
---|
828 | /* Full Duplex Mode Check */ |
---|
829 | if (db->op_mode & 0x4) |
---|
830 | db->cr6_data |= CR6_FDM; /* Set Full Duplex Bit */ |
---|
831 | else |
---|
832 | db->cr6_data &= ~CR6_FDM; /* Clear Full Duplex Bit */ |
---|
833 | |
---|
834 | /* Transciver Selection */ |
---|
835 | if (db->op_mode & 0x10) /* 1M HomePNA */ |
---|
836 | db->cr6_data |= 0x40000; /* External MII select */ |
---|
837 | else |
---|
838 | db->cr6_data &= ~0x40000; /* Internal 10/100 transciver */ |
---|
839 | |
---|
840 | update_cr6(db->cr6_data, BASE); |
---|
841 | |
---|
842 | /* 10/100M phyxcer force mode need */ |
---|
843 | if (!(db->media_mode & 0x18)) { |
---|
844 | /* Forece Mode */ |
---|
845 | phy_reg = phy_read(BASE, db->phy_addr, 6, db->chip_id); |
---|
846 | if (!(phy_reg & 0x1)) { |
---|
847 | /* parter without N-Way capability */ |
---|
848 | phy_reg = 0x0; |
---|
849 | switch (db->op_mode) { |
---|
850 | case DMFE_10MHF: |
---|
851 | phy_reg = 0x0; |
---|
852 | break; |
---|
853 | case DMFE_10MFD: |
---|
854 | phy_reg = 0x100; |
---|
855 | break; |
---|
856 | case DMFE_100MHF: |
---|
857 | phy_reg = 0x2000; |
---|
858 | break; |
---|
859 | case DMFE_100MFD: |
---|
860 | phy_reg = 0x2100; |
---|
861 | break; |
---|
862 | } |
---|
863 | phy_write(BASE, db->phy_addr, 0, phy_reg, |
---|
864 | db->chip_id); |
---|
865 | if (db->chip_type |
---|
866 | && (db->chip_id == PCI_DM9102_ID)) |
---|
867 | mdelay(20); |
---|
868 | phy_write(BASE, db->phy_addr, 0, phy_reg, |
---|
869 | db->chip_id); |
---|
870 | } |
---|
871 | } |
---|
872 | } |
---|
873 | #endif |
---|
874 | |
---|
875 | /* |
---|
876 | * Write a word to Phy register |
---|
877 | */ |
---|
878 | |
---|
879 | static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset, |
---|
880 | u16 phy_data, u32 chip_id) |
---|
881 | { |
---|
882 | u16 i; |
---|
883 | unsigned long ioaddr; |
---|
884 | |
---|
885 | if (chip_id == PCI_DM9132_ID) { |
---|
886 | ioaddr = iobase + 0x80 + offset * 4; |
---|
887 | outw(phy_data, ioaddr); |
---|
888 | } else { |
---|
889 | /* DM9102/DM9102A Chip */ |
---|
890 | ioaddr = iobase + DCR9; |
---|
891 | |
---|
892 | /* Send 33 synchronization clock to Phy controller */ |
---|
893 | for (i = 0; i < 35; i++) |
---|
894 | phy_write_1bit(ioaddr, PHY_DATA_1); |
---|
895 | |
---|
896 | /* Send start command(01) to Phy */ |
---|
897 | phy_write_1bit(ioaddr, PHY_DATA_0); |
---|
898 | phy_write_1bit(ioaddr, PHY_DATA_1); |
---|
899 | |
---|
900 | /* Send write command(01) to Phy */ |
---|
901 | phy_write_1bit(ioaddr, PHY_DATA_0); |
---|
902 | phy_write_1bit(ioaddr, PHY_DATA_1); |
---|
903 | |
---|
904 | /* Send Phy addres */ |
---|
905 | for (i = 0x10; i > 0; i = i >> 1) |
---|
906 | phy_write_1bit(ioaddr, |
---|
907 | phy_addr & i ? PHY_DATA_1 : |
---|
908 | PHY_DATA_0); |
---|
909 | |
---|
910 | /* Send register addres */ |
---|
911 | for (i = 0x10; i > 0; i = i >> 1) |
---|
912 | phy_write_1bit(ioaddr, |
---|
913 | offset & i ? PHY_DATA_1 : |
---|
914 | PHY_DATA_0); |
---|
915 | |
---|
916 | /* written trasnition */ |
---|
917 | phy_write_1bit(ioaddr, PHY_DATA_1); |
---|
918 | phy_write_1bit(ioaddr, PHY_DATA_0); |
---|
919 | |
---|
920 | /* Write a word data to PHY controller */ |
---|
921 | for (i = 0x8000; i > 0; i >>= 1) |
---|
922 | phy_write_1bit(ioaddr, |
---|
923 | phy_data & i ? PHY_DATA_1 : |
---|
924 | PHY_DATA_0); |
---|
925 | } |
---|
926 | } |
---|
927 | |
---|
928 | |
---|
929 | /* |
---|
930 | * Read a word data from phy register |
---|
931 | */ |
---|
932 | |
---|
933 | static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, |
---|
934 | u32 chip_id) |
---|
935 | { |
---|
936 | int i; |
---|
937 | u16 phy_data; |
---|
938 | unsigned long ioaddr; |
---|
939 | |
---|
940 | if (chip_id == PCI_DM9132_ID) { |
---|
941 | /* DM9132 Chip */ |
---|
942 | ioaddr = iobase + 0x80 + offset * 4; |
---|
943 | phy_data = inw(ioaddr); |
---|
944 | } else { |
---|
945 | /* DM9102/DM9102A Chip */ |
---|
946 | ioaddr = iobase + DCR9; |
---|
947 | |
---|
948 | /* Send 33 synchronization clock to Phy controller */ |
---|
949 | for (i = 0; i < 35; i++) |
---|
950 | phy_write_1bit(ioaddr, PHY_DATA_1); |
---|
951 | |
---|
952 | /* Send start command(01) to Phy */ |
---|
953 | phy_write_1bit(ioaddr, PHY_DATA_0); |
---|
954 | phy_write_1bit(ioaddr, PHY_DATA_1); |
---|
955 | |
---|
956 | /* Send read command(10) to Phy */ |
---|
957 | phy_write_1bit(ioaddr, PHY_DATA_1); |
---|
958 | phy_write_1bit(ioaddr, PHY_DATA_0); |
---|
959 | |
---|
960 | /* Send Phy addres */ |
---|
961 | for (i = 0x10; i > 0; i = i >> 1) |
---|
962 | phy_write_1bit(ioaddr, |
---|
963 | phy_addr & i ? PHY_DATA_1 : |
---|
964 | PHY_DATA_0); |
---|
965 | |
---|
966 | /* Send register addres */ |
---|
967 | for (i = 0x10; i > 0; i = i >> 1) |
---|
968 | phy_write_1bit(ioaddr, |
---|
969 | offset & i ? PHY_DATA_1 : |
---|
970 | PHY_DATA_0); |
---|
971 | |
---|
972 | /* Skip transition state */ |
---|
973 | phy_read_1bit(ioaddr); |
---|
974 | |
---|
975 | /* read 16bit data */ |
---|
976 | for (phy_data = 0, i = 0; i < 16; i++) { |
---|
977 | phy_data <<= 1; |
---|
978 | phy_data |= phy_read_1bit(ioaddr); |
---|
979 | } |
---|
980 | } |
---|
981 | |
---|
982 | return phy_data; |
---|
983 | } |
---|
984 | |
---|
985 | |
---|
986 | /* |
---|
987 | * Write one bit data to Phy Controller |
---|
988 | */ |
---|
989 | |
---|
990 | static void phy_write_1bit(unsigned long ioaddr, u32 phy_data) |
---|
991 | { |
---|
992 | outl(phy_data, ioaddr); /* MII Clock Low */ |
---|
993 | udelay(1); |
---|
994 | outl(phy_data | MDCLKH, ioaddr); /* MII Clock High */ |
---|
995 | udelay(1); |
---|
996 | outl(phy_data, ioaddr); /* MII Clock Low */ |
---|
997 | udelay(1); |
---|
998 | } |
---|
999 | |
---|
1000 | |
---|
1001 | /* |
---|
1002 | * Read one bit phy data from PHY controller |
---|
1003 | */ |
---|
1004 | |
---|
1005 | static u16 phy_read_1bit(unsigned long ioaddr) |
---|
1006 | { |
---|
1007 | u16 phy_data; |
---|
1008 | |
---|
1009 | outl(0x50000, ioaddr); |
---|
1010 | udelay(1); |
---|
1011 | phy_data = (inl(ioaddr) >> 19) & 0x1; |
---|
1012 | outl(0x40000, ioaddr); |
---|
1013 | udelay(1); |
---|
1014 | |
---|
1015 | return phy_data; |
---|
1016 | } |
---|
1017 | |
---|
1018 | |
---|
1019 | /* |
---|
1020 | * Parser SROM and media mode |
---|
1021 | */ |
---|
1022 | |
---|
1023 | static void dmfe_parse_srom(struct nic *nic) |
---|
1024 | { |
---|
1025 | unsigned char *srom = db->srom; |
---|
1026 | int dmfe_mode, tmp_reg; |
---|
1027 | |
---|
1028 | /* Init CR15 */ |
---|
1029 | db->cr15_data = CR15_DEFAULT; |
---|
1030 | |
---|
1031 | /* Check SROM Version */ |
---|
1032 | if (((int) srom[18] & 0xff) == SROM_V41_CODE) { |
---|
1033 | /* SROM V4.01 */ |
---|
1034 | /* Get NIC support media mode */ |
---|
1035 | db->NIC_capability = *(u16 *) (srom + 34); |
---|
1036 | db->PHY_reg4 = 0; |
---|
1037 | for (tmp_reg = 1; tmp_reg < 0x10; tmp_reg <<= 1) { |
---|
1038 | switch (db->NIC_capability & tmp_reg) { |
---|
1039 | case 0x1: |
---|
1040 | db->PHY_reg4 |= 0x0020; |
---|
1041 | break; |
---|
1042 | case 0x2: |
---|
1043 | db->PHY_reg4 |= 0x0040; |
---|
1044 | break; |
---|
1045 | case 0x4: |
---|
1046 | db->PHY_reg4 |= 0x0080; |
---|
1047 | break; |
---|
1048 | case 0x8: |
---|
1049 | db->PHY_reg4 |= 0x0100; |
---|
1050 | break; |
---|
1051 | } |
---|
1052 | } |
---|
1053 | |
---|
1054 | /* Media Mode Force or not check */ |
---|
1055 | dmfe_mode = *((int *) srom + 34) & *((int *) srom + 36); |
---|
1056 | switch (dmfe_mode) { |
---|
1057 | case 0x4: |
---|
1058 | dmfe_media_mode = DMFE_100MHF; |
---|
1059 | break; /* 100MHF */ |
---|
1060 | case 0x2: |
---|
1061 | dmfe_media_mode = DMFE_10MFD; |
---|
1062 | break; /* 10MFD */ |
---|
1063 | case 0x8: |
---|
1064 | dmfe_media_mode = DMFE_100MFD; |
---|
1065 | break; /* 100MFD */ |
---|
1066 | case 0x100: |
---|
1067 | case 0x200: |
---|
1068 | dmfe_media_mode = DMFE_1M_HPNA; |
---|
1069 | break; /* HomePNA */ |
---|
1070 | } |
---|
1071 | |
---|
1072 | /* Special Function setting */ |
---|
1073 | /* VLAN function */ |
---|
1074 | if ((SF_mode & 0x1) || (srom[43] & 0x80)) |
---|
1075 | db->cr15_data |= 0x40; |
---|
1076 | |
---|
1077 | /* Flow Control */ |
---|
1078 | if ((SF_mode & 0x2) || (srom[40] & 0x1)) |
---|
1079 | db->cr15_data |= 0x400; |
---|
1080 | |
---|
1081 | /* TX pause packet */ |
---|
1082 | if ((SF_mode & 0x4) || (srom[40] & 0xe)) |
---|
1083 | db->cr15_data |= 0x9800; |
---|
1084 | } |
---|
1085 | |
---|
1086 | /* Parse HPNA parameter */ |
---|
1087 | db->HPNA_command = 1; |
---|
1088 | |
---|
1089 | /* Accept remote command or not */ |
---|
1090 | if (HPNA_rx_cmd == 0) |
---|
1091 | db->HPNA_command |= 0x8000; |
---|
1092 | |
---|
1093 | /* Issue remote command & operation mode */ |
---|
1094 | if (HPNA_tx_cmd == 1) |
---|
1095 | switch (HPNA_mode) { /* Issue Remote Command */ |
---|
1096 | case 0: |
---|
1097 | db->HPNA_command |= 0x0904; |
---|
1098 | break; |
---|
1099 | case 1: |
---|
1100 | db->HPNA_command |= 0x0a00; |
---|
1101 | break; |
---|
1102 | case 2: |
---|
1103 | db->HPNA_command |= 0x0506; |
---|
1104 | break; |
---|
1105 | case 3: |
---|
1106 | db->HPNA_command |= 0x0602; |
---|
1107 | break; |
---|
1108 | } else |
---|
1109 | switch (HPNA_mode) { /* Don't Issue */ |
---|
1110 | case 0: |
---|
1111 | db->HPNA_command |= 0x0004; |
---|
1112 | break; |
---|
1113 | case 1: |
---|
1114 | db->HPNA_command |= 0x0000; |
---|
1115 | break; |
---|
1116 | case 2: |
---|
1117 | db->HPNA_command |= 0x0006; |
---|
1118 | break; |
---|
1119 | case 3: |
---|
1120 | db->HPNA_command |= 0x0002; |
---|
1121 | break; |
---|
1122 | } |
---|
1123 | |
---|
1124 | /* Check DM9801 or DM9802 present or not */ |
---|
1125 | db->HPNA_present = 0; |
---|
1126 | update_cr6(db->cr6_data | 0x40000, BASE); |
---|
1127 | tmp_reg = phy_read(BASE, db->phy_addr, 3, db->chip_id); |
---|
1128 | if ((tmp_reg & 0xfff0) == 0xb900) { |
---|
1129 | /* DM9801 or DM9802 present */ |
---|
1130 | db->HPNA_timer = 8; |
---|
1131 | if (phy_read(BASE, db->phy_addr, 31, db->chip_id) == |
---|
1132 | 0x4404) { |
---|
1133 | /* DM9801 HomeRun */ |
---|
1134 | db->HPNA_present = 1; |
---|
1135 | dmfe_program_DM9801(nic, tmp_reg); |
---|
1136 | } else { |
---|
1137 | /* DM9802 LongRun */ |
---|
1138 | db->HPNA_present = 2; |
---|
1139 | dmfe_program_DM9802(nic); |
---|
1140 | } |
---|
1141 | } |
---|
1142 | |
---|
1143 | } |
---|
1144 | |
---|
1145 | /* |
---|
1146 | * Init HomeRun DM9801 |
---|
1147 | */ |
---|
1148 | |
---|
1149 | static void dmfe_program_DM9801(struct nic *nic __unused, int HPNA_rev) |
---|
1150 | { |
---|
1151 | u32 reg17, reg25; |
---|
1152 | |
---|
1153 | if (!HPNA_NoiseFloor) |
---|
1154 | HPNA_NoiseFloor = DM9801_NOISE_FLOOR; |
---|
1155 | switch (HPNA_rev) { |
---|
1156 | case 0xb900: /* DM9801 E3 */ |
---|
1157 | db->HPNA_command |= 0x1000; |
---|
1158 | reg25 = phy_read(BASE, db->phy_addr, 24, db->chip_id); |
---|
1159 | reg25 = ((reg25 + HPNA_NoiseFloor) & 0xff) | 0xf000; |
---|
1160 | reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id); |
---|
1161 | break; |
---|
1162 | case 0xb901: /* DM9801 E4 */ |
---|
1163 | reg25 = phy_read(BASE, db->phy_addr, 25, db->chip_id); |
---|
1164 | reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor; |
---|
1165 | reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id); |
---|
1166 | reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor + 3; |
---|
1167 | break; |
---|
1168 | case 0xb902: /* DM9801 E5 */ |
---|
1169 | case 0xb903: /* DM9801 E6 */ |
---|
1170 | default: |
---|
1171 | db->HPNA_command |= 0x1000; |
---|
1172 | reg25 = phy_read(BASE, db->phy_addr, 25, db->chip_id); |
---|
1173 | reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor - 5; |
---|
1174 | reg17 = phy_read(BASE, db->phy_addr, 17, db->chip_id); |
---|
1175 | reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor; |
---|
1176 | break; |
---|
1177 | } |
---|
1178 | phy_write(BASE, db->phy_addr, 16, db->HPNA_command, db->chip_id); |
---|
1179 | phy_write(BASE, db->phy_addr, 17, reg17, db->chip_id); |
---|
1180 | phy_write(BASE, db->phy_addr, 25, reg25, db->chip_id); |
---|
1181 | } |
---|
1182 | |
---|
1183 | |
---|
1184 | /* |
---|
1185 | * Init HomeRun DM9802 |
---|
1186 | */ |
---|
1187 | |
---|
1188 | static void dmfe_program_DM9802(struct nic *nic __unused) |
---|
1189 | { |
---|
1190 | u32 phy_reg; |
---|
1191 | |
---|
1192 | if (!HPNA_NoiseFloor) |
---|
1193 | HPNA_NoiseFloor = DM9802_NOISE_FLOOR; |
---|
1194 | phy_write(BASE, db->phy_addr, 16, db->HPNA_command, db->chip_id); |
---|
1195 | phy_reg = phy_read(BASE, db->phy_addr, 25, db->chip_id); |
---|
1196 | phy_reg = (phy_reg & 0xff00) + HPNA_NoiseFloor; |
---|
1197 | phy_write(BASE, db->phy_addr, 25, phy_reg, db->chip_id); |
---|
1198 | } |
---|
1199 | |
---|
1200 | static struct nic_operations dmfe_operations = { |
---|
1201 | .connect = dummy_connect, |
---|
1202 | .poll = dmfe_poll, |
---|
1203 | .transmit = dmfe_transmit, |
---|
1204 | .irq = dmfe_irq, |
---|
1205 | |
---|
1206 | }; |
---|
1207 | |
---|
1208 | static struct pci_device_id dmfe_nics[] = { |
---|
1209 | PCI_ROM(0x1282, 0x9100, "dmfe9100", "Davicom 9100", 0), |
---|
1210 | PCI_ROM(0x1282, 0x9102, "dmfe9102", "Davicom 9102", 0), |
---|
1211 | PCI_ROM(0x1282, 0x9009, "dmfe9009", "Davicom 9009", 0), |
---|
1212 | PCI_ROM(0x1282, 0x9132, "dmfe9132", "Davicom 9132", 0), /* Needs probably some fixing */ |
---|
1213 | }; |
---|
1214 | |
---|
1215 | PCI_DRIVER ( dmfe_driver, dmfe_nics, PCI_NO_CLASS ); |
---|
1216 | |
---|
1217 | DRIVER ( "DMFE/PCI", nic_driver, pci_driver, dmfe_driver, |
---|
1218 | dmfe_probe, dmfe_disable ); |
---|
1219 | |
---|
1220 | /* |
---|
1221 | * Local variables: |
---|
1222 | * c-basic-offset: 8 |
---|
1223 | * c-indent-level: 8 |
---|
1224 | * tab-width: 8 |
---|
1225 | * End: |
---|
1226 | */ |
---|