aboutsummaryrefslogtreecommitdiff
path: root/src/southbridge/nvidia/ck804/ck804_nic.c
blob: 3ce3041abace326d0ae01782f8f7d1599caba373 (plain)
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,
};