Revision: linuxbios@linuxbios.org--devel/freebios--devel--2.0--patch-30
[coreboot.git] / src / southbridge / nvidia / ck804 / ck804_nic.c
1 /*
2  * Copyright 2004 Tyan Computer
3  *  by yhlu@tyan.com
4  */
5 #include <console/console.h>
6 #include <device/device.h>
7 #include <device/smbus.h>
8 #include <device/pci.h>
9 #include <device/pci_ids.h>
10 #include <device/pci_ops.h>
11 #include <arch/io.h>
12 #include "ck804.h"
13
14
15 static void nic_init(struct device *dev)
16 {
17         uint32_t dword, old;
18         uint32_t mac_h, mac_l;
19         int eeprom_valid = 0;
20         struct southbridge_nvidia_ck804_config *conf;
21
22         static uint32_t nic_index = 0;
23
24
25         old = dword = pci_read_config32(dev, 0x30);
26         dword &= ~(0xf);
27         dword |= 0xf;
28         if(old != dword) {
29                 pci_write_config32(dev, 0x30 , dword);
30         }
31
32         conf = dev->chip_info;
33        
34         if(conf->mac_eeprom_smbus != 0) { 
35 //      read MAC address from EEPROM at first
36                 struct device *dev_eeprom;
37                 dev_eeprom = dev_find_slot_on_smbus(conf->mac_eeprom_smbus, conf->mac_eeprom_addr);
38
39                 if(dev_eeprom) {
40                 //      if that is valid we will use that
41                         unsigned char dat[6];
42                         int status;
43                         int i;
44                         for(i=0;i<6;i++) {
45                                 status = smbus_read_byte(dev_eeprom, i);
46                                 if(status < 0) break;
47                                 dat[i] = status & 0xff;
48                         }
49                         if(status >= 0) {
50                                 mac_l = 0;
51                                 for(i=3;i>=0;i--) {
52                                         mac_l <<= 8;
53                                         mac_l += dat[i];
54                                 }
55                                 if(mac_l != 0xffffffff) {
56                                         mac_l += nic_index;
57                                         mac_h = 0;
58                                         for(i=5;i>=4;i--) {
59                                                 mac_h <<= 8;
60                                                 mac_h += dat[i];
61                                         }
62                                         eeprom_valid = 1;       
63                                 }
64                         }
65                 }
66         }
67 //      if that is invalid we will read that from romstrap
68         if(!eeprom_valid) {
69                 unsigned long mac_pos;
70                 mac_pos = 0xffffffd0; // refer to romstrap.inc and romstrap.lds
71                 mac_l = readl(mac_pos) + nic_index;
72                 mac_h = readl(mac_pos + 4);
73         }
74
75 //      set that into NIC
76         pci_write_config32(dev, 0xa8, mac_l);
77         pci_write_config32(dev, 0xac, mac_h);
78
79         nic_index++;
80
81 #if CONFIG_PCI_ROM_RUN == 1
82         pci_dev_init(dev);// it will init option rom
83 #endif
84
85 }
86
87 static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
88 {
89         pci_write_config32(dev, 0x40,
90                 ((device & 0xffff) << 16) | (vendor & 0xffff));
91 }
92
93 static struct pci_operations lops_pci = {
94         .set_subsystem = lpci_set_subsystem,
95 };
96
97 static struct device_operations nic_ops  = {
98         .read_resources   = pci_dev_read_resources,
99         .set_resources    = pci_dev_set_resources,
100         .enable_resources = pci_dev_enable_resources,
101         .init             = nic_init,
102         .scan_bus         = 0,
103 //      .enable           = ck804_enable,
104         .ops_pci          = &lops_pci,
105 };
106 static struct pci_driver nic_driver __pci_driver = {
107         .ops    = &nic_ops,
108         .vendor = PCI_VENDOR_ID_NVIDIA,
109         .device = PCI_DEVICE_ID_NVIDIA_CK804_NIC,
110 };
111 static struct pci_driver nic_bridge_driver __pci_driver = {
112         .ops    = &nic_ops,
113         .vendor = PCI_VENDOR_ID_NVIDIA,
114         .device = PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE,
115 };