Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f4d4a7e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
  [SPARC64]: Avoid JBUS errors on some Niagara systems.
  [FUSION]: Fix mptspi.c build with CONFIG_PM not set.
  [TG3]: Handle Sun onboard tg3 chips more correctly.
  [SPARC64]: Dump local cpu registers in sun4v_log_error()
parents 938473b2 46b30493
Loading
Loading
Loading
Loading
+118 −6
Original line number Diff line number Diff line
@@ -599,18 +599,128 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = {

/* SUN4V PCI configuration space accessors. */

static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func)
struct pdev_entry {
	struct pdev_entry	*next;
	u32			devhandle;
	unsigned int		bus;
	unsigned int		device;
	unsigned int		func;
};

#define PDEV_HTAB_SIZE	16
#define PDEV_HTAB_MASK	(PDEV_HTAB_SIZE - 1)
static struct pdev_entry *pdev_htab[PDEV_HTAB_SIZE];

static inline unsigned int pdev_hashfn(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func)
{
	unsigned int val;

	val = (devhandle ^ (devhandle >> 4));
	val ^= bus;
	val ^= device;
	val ^= func;

	return val & PDEV_HTAB_MASK;
}

static int pdev_htab_add(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func)
{
	if (bus == pbm->pci_first_busno) {
		if (device == 0 && func == 0)
	struct pdev_entry *p = kmalloc(sizeof(*p), GFP_KERNEL);
	struct pdev_entry **slot;

	if (!p)
		return -ENOMEM;

	slot = &pdev_htab[pdev_hashfn(devhandle, bus, device, func)];
	p->next = *slot;
	*slot = p;

	p->devhandle = devhandle;
	p->bus = bus;
	p->device = device;
	p->func = func;

	return 0;
		return 1;
}

/* Recursively descend into the OBP device tree, rooted at toplevel_node,
 * looking for a PCI device matching bus and devfn.
 */
static int obp_find(struct linux_prom_pci_registers *pregs, int toplevel_node, unsigned int bus, unsigned int devfn)
{
	toplevel_node = prom_getchild(toplevel_node);

	while (toplevel_node != 0) {
		int ret = obp_find(pregs, toplevel_node, bus, devfn);

		if (ret != 0)
			return ret;

		ret = prom_getproperty(toplevel_node, "reg", (char *) pregs,
				       sizeof(*pregs) * PROMREG_MAX);
		if (ret == 0 || ret == -1)
			goto next_sibling;

		if (((pregs[0].phys_hi >> 16) & 0xff) == bus &&
		    ((pregs[0].phys_hi >> 8) & 0xff) == devfn)
			break;

	next_sibling:
		toplevel_node = prom_getsibling(toplevel_node);
	}

	return toplevel_node;
}

static int pdev_htab_populate(struct pci_pbm_info *pbm)
{
	struct linux_prom_pci_registers pr[PROMREG_MAX];
	u32 devhandle = pbm->devhandle;
	unsigned int bus;

	for (bus = pbm->pci_first_busno; bus <= pbm->pci_last_busno; bus++) {
		unsigned int devfn;

		for (devfn = 0; devfn < 256; devfn++) {
			unsigned int device = PCI_SLOT(devfn);
			unsigned int func = PCI_FUNC(devfn);

			if (obp_find(pr, pbm->prom_node, bus, devfn)) {
				int err = pdev_htab_add(devhandle, bus,
							device, func);
				if (err)
					return err;
			}
		}
	}

	return 0;
}

static struct pdev_entry *pdev_find(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func)
{
	struct pdev_entry *p;

	p = pdev_htab[pdev_hashfn(devhandle, bus, device, func)];
	while (p) {
		if (p->devhandle == devhandle &&
		    p->bus == bus &&
		    p->device == device &&
		    p->func == func)
			break;

		p = p->next;
	}

	return p;
}

static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func)
{
	if (bus < pbm->pci_first_busno ||
	    bus > pbm->pci_last_busno)
		return 1;
	return 0;
	return pdev_find(pbm->devhandle, bus, device, func) == NULL;
}

static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
@@ -1063,6 +1173,8 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32

	pci_sun4v_get_bus_range(pbm);
	pci_sun4v_iommu_init(pbm);

	pdev_htab_populate(pbm);
}

void sun4v_pci_init(int node, char *model_name)
+7 −4
Original line number Diff line number Diff line
@@ -1797,7 +1797,9 @@ static const char *sun4v_err_type_to_str(u32 type)
	};
}

static void sun4v_log_error(struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt)
extern void __show_regs(struct pt_regs * regs);

static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt)
{
	int cnt;

@@ -1830,6 +1832,8 @@ static void sun4v_log_error(struct sun4v_error_entry *ent, int cpu, const char *
	       pfx,
	       ent->err_raddr, ent->err_size, ent->err_cpu);

	__show_regs(regs);

	if ((cnt = atomic_read(ocnt)) != 0) {
		atomic_set(ocnt, 0);
		wmb();
@@ -1862,7 +1866,7 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset)

	put_cpu();

	sun4v_log_error(&local_copy, cpu,
	sun4v_log_error(regs, &local_copy, cpu,
			KERN_ERR "RESUMABLE ERROR",
			&sun4v_resum_oflow_cnt);
}
@@ -1910,7 +1914,7 @@ void sun4v_nonresum_error(struct pt_regs *regs, unsigned long offset)
	}
#endif

	sun4v_log_error(&local_copy, cpu,
	sun4v_log_error(regs, &local_copy, cpu,
			KERN_EMERG "NON-RESUMABLE ERROR",
			&sun4v_nonresum_oflow_cnt);

@@ -2200,7 +2204,6 @@ static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
void die_if_kernel(char *str, struct pt_regs *regs)
{
	static int die_counter;
	extern void __show_regs(struct pt_regs * regs);
	extern void smp_report_regs(void);
	int count = 0;
	
+2 −0
Original line number Diff line number Diff line
@@ -831,6 +831,7 @@ mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
	return rc;
}

#ifdef CONFIG_PM
/*
 * spi module resume handler
 */
@@ -846,6 +847,7 @@ mptspi_resume(struct pci_dev *pdev)

	return rc;
}
#endif

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+48 −96
Original line number Diff line number Diff line
@@ -69,8 +69,8 @@

#define DRV_MODULE_NAME		"tg3"
#define PFX DRV_MODULE_NAME	": "
#define DRV_MODULE_VERSION	"3.58"
#define DRV_MODULE_RELDATE	"May 22, 2006"
#define DRV_MODULE_VERSION	"3.59"
#define DRV_MODULE_RELDATE	"June 8, 2006"

#define TG3_DEF_MAC_MODE	0
#define TG3_DEF_RX_MODE		0
@@ -4485,7 +4485,6 @@ static void tg3_disable_nvram_access(struct tg3 *tp)
/* tp->lock is held. */
static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind)
{
	if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X))
	tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX,
		      NIC_SRAM_FIRMWARE_MBOX_MAGIC1);

@@ -4568,13 +4567,12 @@ static int tg3_chip_reset(struct tg3 *tp)
	void (*write_op)(struct tg3 *, u32, u32);
	int i;

	if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) {
	tg3_nvram_lock(tp);

	/* No matching tg3_nvram_unlock() after this because
	 * chip reset below will undo the nvram lock.
	 */
	tp->nvram_lock_cnt = 0;
	}

	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
@@ -4727,7 +4725,6 @@ static int tg3_chip_reset(struct tg3 *tp)
		tw32_f(MAC_MODE, 0);
	udelay(40);

	if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) {
	/* Wait for firmware initialization to complete. */
	for (i = 0; i < 100000; i++) {
		tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
@@ -4735,12 +4732,18 @@ static int tg3_chip_reset(struct tg3 *tp)
			break;
		udelay(10);
	}
		if (i >= 100000) {
			printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, "
			       "firmware will not restart magic=%08x\n",
			       tp->dev->name, val);
			return -ENODEV;
		}

	/* Chip might not be fitted with firmare.  Some Sun onboard
	 * parts are configured like that.  So don't signal the timeout
	 * of the above loop as an error, but do report the lack of
	 * running firmware once.
	 */
	if (i >= 100000 &&
	    !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) {
		tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED;

		printk(KERN_INFO PFX "%s: No firmware running.\n",
		       tp->dev->name);
	}

	if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
@@ -9075,9 +9078,6 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
{
	int j;

	if (tp->tg3_flags2 & TG3_FLG2_SUN_570X)
		return;

	tw32_f(GRC_EEPROM_ADDR,
	     (EEPROM_ADDR_FSM_RESET |
	      (EEPROM_DEFAULT_CLOCK_PERIOD <<
@@ -9210,11 +9210,6 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
{
	int ret;

	if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
		printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 570X\n");
		return -EINVAL;
	}

	if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
		return tg3_nvram_read_using_eeprom(tp, offset, val);

@@ -9447,11 +9442,6 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
{
	int ret;

	if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
		printk(KERN_ERR PFX "Attempt to do nvram_write on Sun 570X\n");
		return -EINVAL;
	}

	if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
		tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl &
		       ~GRC_LCLCTRL_GPIO_OUTPUT1);
@@ -9578,15 +9568,19 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
	pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
			       tp->misc_host_ctrl);

	/* The memory arbiter has to be enabled in order for SRAM accesses
	 * to succeed.  Normally on powerup the tg3 chip firmware will make
	 * sure it is enabled, but other entities such as system netboot
	 * code might disable it.
	 */
	val = tr32(MEMARB_MODE);
	tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);

	tp->phy_id = PHY_ID_INVALID;
	tp->led_ctrl = LED_CTRL_MODE_PHY_1;

	/* Do not even try poking around in here on Sun parts.  */
	if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
		/* All SUN chips are built-in LOMs. */
	/* Assume an onboard device by default.  */
	tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
		return;
	}

	tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
	if (val == NIC_SRAM_DATA_SIG_MAGIC) {
@@ -9686,6 +9680,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)

		if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)
			tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
		else
			tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;

		if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
			tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
@@ -9834,16 +9830,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
	int i;
	u32 magic;

	if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) {
		/* Sun decided not to put the necessary bits in the
		 * NVRAM of their onboard tg3 parts :(
		 */
		strcpy(tp->board_part_number, "Sun 570X");
		return;
	}

	if (tg3_nvram_read_swab(tp, 0x0, &magic))
		return;
		goto out_not_found;

	if (magic == TG3_EEPROM_MAGIC) {
		for (i = 0; i < 256; i += 4) {
@@ -9874,6 +9862,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
					break;
				msleep(1);
			}
			if (!(tmp16 & 0x8000))
				goto out_not_found;

			pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA,
					      &tmp);
			tmp = cpu_to_le32(tmp);
@@ -9965,37 +9956,6 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
	}
}

#ifdef CONFIG_SPARC64
static int __devinit tg3_is_sun_570X(struct tg3 *tp)
{
	struct pci_dev *pdev = tp->pdev;
	struct pcidev_cookie *pcp = pdev->sysdata;

	if (pcp != NULL) {
		int node = pcp->prom_node;
		u32 venid;
		int err;

		err = prom_getproperty(node, "subsystem-vendor-id",
				       (char *) &venid, sizeof(venid));
		if (err == 0 || err == -1)
			return 0;
		if (venid == PCI_VENDOR_ID_SUN)
			return 1;

		/* TG3 chips onboard the SunBlade-2500 don't have the
		 * subsystem-vendor-id set to PCI_VENDOR_ID_SUN but they
		 * are distinguishable from non-Sun variants by being
		 * named "network" by the firmware.  Non-Sun cards will
		 * show up as being named "ethernet".
		 */
		if (!strcmp(pcp->prom_name, "network"))
			return 1;
	}
	return 0;
}
#endif

static int __devinit tg3_get_invariants(struct tg3 *tp)
{
	static struct pci_device_id write_reorder_chipsets[] = {
@@ -10012,11 +9972,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
	u16 pci_cmd;
	int err;

#ifdef CONFIG_SPARC64
	if (tg3_is_sun_570X(tp))
		tp->tg3_flags2 |= TG3_FLG2_SUN_570X;
#endif

	/* Force memory write invalidate off.  If we leave it on,
	 * then on 5700_BX chips we have to enable a workaround.
	 * The workaround is to set the TG3PCI_DMA_RW_CTRL boundary
@@ -10312,8 +10267,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
	if (tp->write32 == tg3_write_indirect_reg32 ||
	    ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
	     (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
	      GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) ||
	    (tp->tg3_flags2 & TG3_FLG2_SUN_570X))
	      GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)))
		tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG;

	/* Get eeprom hw config before calling tg3_set_power_state().
@@ -10594,8 +10548,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
#endif

	mac_offset = 0x7c;
	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
	     !(tp->tg3_flags & TG3_FLG2_SUN_570X)) ||
	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
		if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
			mac_offset = 0xcc;
@@ -10622,8 +10575,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
	}
	if (!addr_ok) {
		/* Next, try NVRAM. */
		if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) &&
		    !tg3_nvram_read(tp, mac_offset + 0, &hi) &&
		if (!tg3_nvram_read(tp, mac_offset + 0, &hi) &&
		    !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
			dev->dev_addr[0] = ((hi >> 16) & 0xff);
			dev->dev_addr[1] = ((hi >> 24) & 0xff);
+2 −1
Original line number Diff line number Diff line
@@ -2184,7 +2184,7 @@ struct tg3 {
#define TG3_FLAG_INIT_COMPLETE		0x80000000
	u32				tg3_flags2;
#define TG3_FLG2_RESTART_TIMER		0x00000001
#define TG3_FLG2_SUN_570X		0x00000002
/*					0x00000002 available */
#define TG3_FLG2_NO_ETH_WIRE_SPEED	0x00000004
#define TG3_FLG2_IS_5788		0x00000008
#define TG3_FLG2_MAX_RXPEND_64		0x00000010
@@ -2216,6 +2216,7 @@ struct tg3 {
#define TG3_FLG2_HW_TSO			(TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2)
#define TG3_FLG2_1SHOT_MSI		0x10000000
#define TG3_FLG2_PHY_JITTER_BUG		0x20000000
#define TG3_FLG2_NO_FWARE_REPORTED	0x40000000

	u32				split_mode_max_reqs;
#define SPLIT_MODE_5704_MAX_REQ		3