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

Commit c9517e58 authored by Dhananjay Phadke's avatar Dhananjay Phadke Committed by David S. Miller
Browse files

netxen: implement generic pcie semaphore functions



Implement common function for locking/unlocking 8 hardware
semaphores used for serializing access to shared resouces
on a NIC board by different PCI functions.

As by definition, callers of these semaphore API can be
put to sleep till the semaphore is locked.

Signed-off-by: default avatarDhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cb7e4b6e
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -1207,6 +1207,30 @@ int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
#define NXWR32(adapter, off, val) \
	(adapter->hw_write_wx(adapter, off, val))

int netxen_pcie_sem_lock(struct netxen_adapter *, int, u32);
void netxen_pcie_sem_unlock(struct netxen_adapter *, int);

#define netxen_rom_lock(a)	\
	netxen_pcie_sem_lock((a), 2, NETXEN_ROM_LOCK_ID)
#define netxen_rom_unlock(a)	\
	netxen_pcie_sem_unlock((a), 2)
#define netxen_phy_lock(a)	\
	netxen_pcie_sem_lock((a), 3, NETXEN_PHY_LOCK_ID)
#define netxen_phy_unlock(a)	\
	netxen_pcie_sem_unlock((a), 3)
#define netxen_api_lock(a)	\
	netxen_pcie_sem_lock((a), 5, 0)
#define netxen_api_unlock(a)	\
	netxen_pcie_sem_unlock((a), 5)
#define netxen_sw_lock(a)	\
	netxen_pcie_sem_lock((a), 6, 0)
#define netxen_sw_unlock(a)	\
	netxen_pcie_sem_unlock((a), 6)
#define crb_win_lock(a)	\
	netxen_pcie_sem_lock((a), 7, NETXEN_CRB_WIN_LOCK_ID)
#define crb_win_unlock(a)	\
	netxen_pcie_sem_unlock((a), 7)

int netxen_nic_get_board_info(struct netxen_adapter *adapter);
void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
int netxen_nic_wol_supported(struct netxen_adapter *adapter);
+0 −35
Original line number Diff line number Diff line
@@ -33,41 +33,6 @@

#define NXHAL_VERSION	1

static int
netxen_api_lock(struct netxen_adapter *adapter)
{
	u32 done = 0, timeout = 0;

	for (;;) {
		/* Acquire PCIE HW semaphore5 */
		done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_LOCK));

		if (done == 1)
			break;

		if (++timeout >= NX_OS_CRB_RETRY_COUNT) {
			printk(KERN_ERR "%s: lock timeout.\n", __func__);
			return -1;
		}

		msleep(1);
	}

#if 0
	NXWR32(adapter,
		NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
#endif
	return 0;
}

static int
netxen_api_unlock(struct netxen_adapter *adapter)
{
	/* Release PCIE HW semaphore5 */
	NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK));
	return 0;
}

static u32
netxen_poll_rsp(struct netxen_adapter *adapter)
{
+8 −0
Original line number Diff line number Diff line
@@ -899,16 +899,24 @@ enum {

#define PCIE_DCR		0x00d8

#define PCIE_SEM0_LOCK		(0x1c000)
#define PCIE_SEM0_UNLOCK	(0x1c004)
#define PCIE_SEM1_LOCK		(0x1c008)
#define PCIE_SEM1_UNLOCK	(0x1c00c)
#define PCIE_SEM2_LOCK		(0x1c010)	/* Flash lock   */
#define PCIE_SEM2_UNLOCK	(0x1c014)	/* Flash unlock */
#define PCIE_SEM3_LOCK	  	(0x1c018)	/* Phy lock     */
#define PCIE_SEM3_UNLOCK	(0x1c01c)	/* Phy unlock   */
#define PCIE_SEM4_LOCK	  	(0x1c020)
#define PCIE_SEM4_UNLOCK	(0x1c024)
#define PCIE_SEM5_LOCK		(0x1c028)	/* API lock     */
#define PCIE_SEM5_UNLOCK	(0x1c02c)	/* API unlock   */
#define PCIE_SEM6_LOCK		(0x1c030)	/* sw lock      */
#define PCIE_SEM6_UNLOCK	(0x1c034)	/* sw unlock    */
#define PCIE_SEM7_LOCK		(0x1c038)	/* crb win lock */
#define PCIE_SEM7_UNLOCK	(0x1c03c)	/* crbwin unlock*/
#define PCIE_SEM_LOCK(N)	(PCIE_SEM0_LOCK + 8*(N))
#define PCIE_SEM_UNLOCK(N)	(PCIE_SEM0_UNLOCK + 8*(N))

#define PCIE_SETUP_FUNCTION	(0x12040)
#define PCIE_SETUP_FUNCTION2	(0x12048)
+29 −28
Original line number Diff line number Diff line
@@ -86,7 +86,6 @@ static void __iomem *pci_base_offset(struct netxen_adapter *adapter,
	return NULL;
}

#define CRB_WIN_LOCK_TIMEOUT 100000000
static crb_128M_2M_block_map_t
crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
    {{{0, 0,         0,         0} } },		/* 0: PCI */
@@ -320,6 +319,35 @@ static unsigned crb_hub_agt[64] =

#define NETXEN_WINDOW_ONE 	0x2000000 /*CRB Window: bit 25 of CRB address */

#define NETXEN_PCIE_SEM_TIMEOUT	10000

int
netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg)
{
	int done = 0, timeout = 0;

	while (!done) {
		done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_LOCK(sem)));
		if (done == 1)
			break;
		if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT)
			return -1;
		msleep(1);
	}

	if (id_reg)
		NXWR32(adapter, id_reg, adapter->portnum);

	return 0;
}

void
netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem)
{
	int val;
	val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
}

#define NETXEN_UNICAST_ADDR(port, index) \
	(NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8))
#define NETXEN_MCAST_ADDR(port, index) \
@@ -906,33 +934,6 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
	return 0;
}

#define CRB_WIN_LOCK_TIMEOUT 100000000

static int crb_win_lock(struct netxen_adapter *adapter)
{
	int done = 0, timeout = 0;

	while (!done) {
		/* acquire semaphore3 from PCI HW block */
		done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_LOCK));
		if (done == 1)
			break;
		if (timeout >= CRB_WIN_LOCK_TIMEOUT)
			return -1;
		timeout++;
		udelay(1);
	}
	NXWR32(adapter, NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
	return 0;
}

static void crb_win_unlock(struct netxen_adapter *adapter)
{
	int val;

	val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK));
}

/*
 * Changes the CRB window to the specified window.
 */
+8 −44
Original line number Diff line number Diff line
@@ -369,37 +369,7 @@ static u32 netxen_decode_crb_addr(u32 addr)
		return (pci_base + offset);
}

static long rom_max_timeout = 100;
static long rom_lock_timeout = 10000;

static int rom_lock(struct netxen_adapter *adapter)
{
	int iter;
	u32 done = 0;
	int timeout = 0;

	while (!done) {
		/* acquire semaphore2 from PCI HW block */
		done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK));
		if (done == 1)
			break;
		if (timeout >= rom_lock_timeout)
			return -EIO;

		timeout++;
		/*
		 * Yield CPU
		 */
		if (!in_atomic())
			schedule();
		else {
			for (iter = 0; iter < 20; iter++)
				cpu_relax();	/*This a nop instr on i386 */
		}
	}
	NXWR32(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
	return 0;
}
#define NETXEN_MAX_ROM_WAIT_USEC	100

static int netxen_wait_rom_done(struct netxen_adapter *adapter)
{
@@ -411,22 +381,16 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
	while (done == 0) {
		done = NXRD32(adapter, NETXEN_ROMUSB_GLB_STATUS);
		done &= 2;
		timeout++;
		if (timeout >= rom_max_timeout) {
			printk("Timeout reached  waiting for rom done");
		if (++timeout >= NETXEN_MAX_ROM_WAIT_USEC) {
			dev_err(&adapter->pdev->dev,
				"Timeout reached  waiting for rom done");
			return -EIO;
		}
		udelay(1);
	}
	return 0;
}

static void netxen_rom_unlock(struct netxen_adapter *adapter)
{
	/* release semaphore2 */
	NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK));

}

static int do_rom_fast_read(struct netxen_adapter *adapter,
			    int addr, int *valp)
{
@@ -471,7 +435,7 @@ netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
{
	int ret;

	ret = rom_lock(adapter);
	ret = netxen_rom_lock(adapter);
	if (ret < 0)
		return ret;

@@ -485,7 +449,7 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
{
	int ret;

	if (rom_lock(adapter) != 0)
	if (netxen_rom_lock(adapter) != 0)
		return -EIO;

	ret = do_rom_fast_read(adapter, addr, valp);
@@ -506,7 +470,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
	u32 off;

	/* resetall */
	rom_lock(adapter);
	netxen_rom_lock(adapter);
	NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff);
	netxen_rom_unlock(adapter);

Loading