[LinuxBIOS] CK804 suggestions

Peter.VanEchaute at bench.com Peter.VanEchaute at bench.com
Wed May 18 14:08:59 CEST 2005


I too have done a few boards where the MAC address has been stored in the flash device.  The idea was to save on cost, the same as yours Ron.  This matter of board design is exactly that, board specific.  The CK804 has a specific place in flash that the MAC(s) should be placed anyways, in the ROMSTRAP+0x30.  I noticed you knew that YH.  As the CK804 area is chipset specific, it shouldn't be board specific.  So what I did is placed a define for your TYAN board, at least until you take your stuff out.  In the code, it reads the ROMSTRAP offset + 0x30.  Each MAC address is an +0x8 from there if you have more than one.  This is exactly how the CK804 BIOS Porting guides state to do it.  Now do you have to listen to me or the guide, no.  It's just my $0.02.

On a side note YH, you have a bug in the ck804_nic.c.  I hope it's OK to point this out.  But the MAC address is supposed to be placed into the Memmory Mapped IO (MMIO) area at offset 0xA8, and not in the device configuration space...

My recommendation...
        // set that into NIC MMIO
        write32(mac_l, base + 0xA8);
        write32(mac_h, base + 0xAC);

your code...
        // set that into NIC
        pci_write_config32(dev, 0xa8, mac_l);
        pci_write_config32(dev, 0xac, mac_h);




Here is the code I recommend(or at least something close to it)...


#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"

#define MAC_DBG      1
#define TYANs2895    0



uint8_t read8(unsigned long addr)
{
        return *((volatile uint8_t *)(addr));
}

uint16_t read16(unsigned long addr)
{
        return *((volatile uint16_t *)(addr));
}

uint32_t read32(unsigned long addr)
{
        return *((volatile uint32_t *)(addr));
}

void write8(unsigned long addr, uint8_t value)
{
        *((volatile uint8_t *)(addr)) = value;
}

void write16(unsigned long addr, uint16_t value)
{
        *((volatile uint16_t *)(addr)) = value;
}

void write32(unsigned long addr, uint32_t value)
{
        *((volatile uint32_t *)(addr)) = value;
}



static void nic_init(struct device *dev)
{
        uint32_t dword, old;
        uint32_t mac_h, mac_l;
        static uint32_t nic_index = 0;
        unsigned long mac_pos;
        uint32_t base;
        struct resource *res;
#define NvRegPhyInterface  0xC0
#define PHY_RGMII          0x10000000

        res = find_resource(dev, 0x10);
        base = res->base;
        write32(base + NvRegPhyInterface, PHY_RGMII);

        old = dword = pci_read_config32(dev, 0x30);
        dword &= ~(0xf);
        dword |= 0xf;
        if(old != dword) {
                pci_write_config32(dev, 0x30 , dword);
        }

#if TYAN
        int eeprom_valid = 0;
        struct southbridge_nvidia_ck804_config *conf;

        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) {
                mac_pos = 0xffffffd0; // refer to romstrap.inc and romstrap.lds
                mac_l = read32(mac_pos) + nic_index;
                mac_h = read32(mac_pos + 4);
        }
#else
        // read directly from rom_strap
        mac_pos = read8(0xffffffe0); // refer to romstrap.inc
        mac_pos |= (read8(0xffffffe1)<<8);
        mac_pos |= (read8(0xffffffe2)<<16);
        mac_pos |= (read8(0xffffffe3)<<24);

        mac_pos += 0x30;
        for ( dword = nic_index ; dword > 0 ; dword-- )
        {
                mac_pos += 8;
        }

        mac_l = read32(mac_pos);
        mac_h = read32(mac_pos + 4);
#endif

        // set that into NIC MMIO
        write32(mac_l, base + 0xA8);
        write32(mac_h, base + 0xAC);

#if MAC_DBG
        printk_info("MAC:\tMAC Address is: %02x:%02x:%02x:%02x:%02x:%02x\n",
                        read8(base + 0xAD), read8(base + 0xAC),
                        read8(base + 0xAB), read8(base + 0xAA),
                        read8(base + 0xA9), read8(base + 0xA8));
#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,
};









More information about the coreboot mailing list