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