diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2009-08-24 15:23:26 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-08-26 18:29:17 -0400 |
commit | c9517e5893db03ca8bd32b8783b39af58176947c (patch) | |
tree | 5ae4d26af6f38e70a868e634d0576056c326027e /drivers/net/netxen | |
parent | cb7e4b6e37144f5d131ee09296be3c21c41f28d8 (diff) |
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: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 24 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ctx.c | 35 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hdr.h | 8 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 57 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 52 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_niu.c | 39 |
6 files changed, 71 insertions, 144 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 74ccef5a5c97..061e8aa419b0 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -1207,6 +1207,30 @@ int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr); | |||
1207 | #define NXWR32(adapter, off, val) \ | 1207 | #define NXWR32(adapter, off, val) \ |
1208 | (adapter->hw_write_wx(adapter, off, val)) | 1208 | (adapter->hw_write_wx(adapter, off, val)) |
1209 | 1209 | ||
1210 | int netxen_pcie_sem_lock(struct netxen_adapter *, int, u32); | ||
1211 | void netxen_pcie_sem_unlock(struct netxen_adapter *, int); | ||
1212 | |||
1213 | #define netxen_rom_lock(a) \ | ||
1214 | netxen_pcie_sem_lock((a), 2, NETXEN_ROM_LOCK_ID) | ||
1215 | #define netxen_rom_unlock(a) \ | ||
1216 | netxen_pcie_sem_unlock((a), 2) | ||
1217 | #define netxen_phy_lock(a) \ | ||
1218 | netxen_pcie_sem_lock((a), 3, NETXEN_PHY_LOCK_ID) | ||
1219 | #define netxen_phy_unlock(a) \ | ||
1220 | netxen_pcie_sem_unlock((a), 3) | ||
1221 | #define netxen_api_lock(a) \ | ||
1222 | netxen_pcie_sem_lock((a), 5, 0) | ||
1223 | #define netxen_api_unlock(a) \ | ||
1224 | netxen_pcie_sem_unlock((a), 5) | ||
1225 | #define netxen_sw_lock(a) \ | ||
1226 | netxen_pcie_sem_lock((a), 6, 0) | ||
1227 | #define netxen_sw_unlock(a) \ | ||
1228 | netxen_pcie_sem_unlock((a), 6) | ||
1229 | #define crb_win_lock(a) \ | ||
1230 | netxen_pcie_sem_lock((a), 7, NETXEN_CRB_WIN_LOCK_ID) | ||
1231 | #define crb_win_unlock(a) \ | ||
1232 | netxen_pcie_sem_unlock((a), 7) | ||
1233 | |||
1210 | int netxen_nic_get_board_info(struct netxen_adapter *adapter); | 1234 | int netxen_nic_get_board_info(struct netxen_adapter *adapter); |
1211 | void netxen_nic_get_firmware_info(struct netxen_adapter *adapter); | 1235 | void netxen_nic_get_firmware_info(struct netxen_adapter *adapter); |
1212 | int netxen_nic_wol_supported(struct netxen_adapter *adapter); | 1236 | int netxen_nic_wol_supported(struct netxen_adapter *adapter); |
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 3d676fecb0a7..ef846b43390a 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c | |||
@@ -33,41 +33,6 @@ | |||
33 | 33 | ||
34 | #define NXHAL_VERSION 1 | 34 | #define NXHAL_VERSION 1 |
35 | 35 | ||
36 | static int | ||
37 | netxen_api_lock(struct netxen_adapter *adapter) | ||
38 | { | ||
39 | u32 done = 0, timeout = 0; | ||
40 | |||
41 | for (;;) { | ||
42 | /* Acquire PCIE HW semaphore5 */ | ||
43 | done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_LOCK)); | ||
44 | |||
45 | if (done == 1) | ||
46 | break; | ||
47 | |||
48 | if (++timeout >= NX_OS_CRB_RETRY_COUNT) { | ||
49 | printk(KERN_ERR "%s: lock timeout.\n", __func__); | ||
50 | return -1; | ||
51 | } | ||
52 | |||
53 | msleep(1); | ||
54 | } | ||
55 | |||
56 | #if 0 | ||
57 | NXWR32(adapter, | ||
58 | NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER); | ||
59 | #endif | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static int | ||
64 | netxen_api_unlock(struct netxen_adapter *adapter) | ||
65 | { | ||
66 | /* Release PCIE HW semaphore5 */ | ||
67 | NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK)); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static u32 | 36 | static u32 |
72 | netxen_poll_rsp(struct netxen_adapter *adapter) | 37 | netxen_poll_rsp(struct netxen_adapter *adapter) |
73 | { | 38 | { |
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index c4a4a8ba14f4..92f5970c9aa9 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -899,16 +899,24 @@ enum { | |||
899 | 899 | ||
900 | #define PCIE_DCR 0x00d8 | 900 | #define PCIE_DCR 0x00d8 |
901 | 901 | ||
902 | #define PCIE_SEM0_LOCK (0x1c000) | ||
903 | #define PCIE_SEM0_UNLOCK (0x1c004) | ||
904 | #define PCIE_SEM1_LOCK (0x1c008) | ||
905 | #define PCIE_SEM1_UNLOCK (0x1c00c) | ||
902 | #define PCIE_SEM2_LOCK (0x1c010) /* Flash lock */ | 906 | #define PCIE_SEM2_LOCK (0x1c010) /* Flash lock */ |
903 | #define PCIE_SEM2_UNLOCK (0x1c014) /* Flash unlock */ | 907 | #define PCIE_SEM2_UNLOCK (0x1c014) /* Flash unlock */ |
904 | #define PCIE_SEM3_LOCK (0x1c018) /* Phy lock */ | 908 | #define PCIE_SEM3_LOCK (0x1c018) /* Phy lock */ |
905 | #define PCIE_SEM3_UNLOCK (0x1c01c) /* Phy unlock */ | 909 | #define PCIE_SEM3_UNLOCK (0x1c01c) /* Phy unlock */ |
910 | #define PCIE_SEM4_LOCK (0x1c020) | ||
911 | #define PCIE_SEM4_UNLOCK (0x1c024) | ||
906 | #define PCIE_SEM5_LOCK (0x1c028) /* API lock */ | 912 | #define PCIE_SEM5_LOCK (0x1c028) /* API lock */ |
907 | #define PCIE_SEM5_UNLOCK (0x1c02c) /* API unlock */ | 913 | #define PCIE_SEM5_UNLOCK (0x1c02c) /* API unlock */ |
908 | #define PCIE_SEM6_LOCK (0x1c030) /* sw lock */ | 914 | #define PCIE_SEM6_LOCK (0x1c030) /* sw lock */ |
909 | #define PCIE_SEM6_UNLOCK (0x1c034) /* sw unlock */ | 915 | #define PCIE_SEM6_UNLOCK (0x1c034) /* sw unlock */ |
910 | #define PCIE_SEM7_LOCK (0x1c038) /* crb win lock */ | 916 | #define PCIE_SEM7_LOCK (0x1c038) /* crb win lock */ |
911 | #define PCIE_SEM7_UNLOCK (0x1c03c) /* crbwin unlock*/ | 917 | #define PCIE_SEM7_UNLOCK (0x1c03c) /* crbwin unlock*/ |
918 | #define PCIE_SEM_LOCK(N) (PCIE_SEM0_LOCK + 8*(N)) | ||
919 | #define PCIE_SEM_UNLOCK(N) (PCIE_SEM0_UNLOCK + 8*(N)) | ||
912 | 920 | ||
913 | #define PCIE_SETUP_FUNCTION (0x12040) | 921 | #define PCIE_SETUP_FUNCTION (0x12040) |
914 | #define PCIE_SETUP_FUNCTION2 (0x12048) | 922 | #define PCIE_SETUP_FUNCTION2 (0x12048) |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 9138bbcbb80a..cbfe44c8a7fd 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -86,7 +86,6 @@ static void __iomem *pci_base_offset(struct netxen_adapter *adapter, | |||
86 | return NULL; | 86 | return NULL; |
87 | } | 87 | } |
88 | 88 | ||
89 | #define CRB_WIN_LOCK_TIMEOUT 100000000 | ||
90 | static crb_128M_2M_block_map_t | 89 | static crb_128M_2M_block_map_t |
91 | crb_128M_2M_map[64] __cacheline_aligned_in_smp = { | 90 | crb_128M_2M_map[64] __cacheline_aligned_in_smp = { |
92 | {{{0, 0, 0, 0} } }, /* 0: PCI */ | 91 | {{{0, 0, 0, 0} } }, /* 0: PCI */ |
@@ -320,6 +319,35 @@ static unsigned crb_hub_agt[64] = | |||
320 | 319 | ||
321 | #define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ | 320 | #define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ |
322 | 321 | ||
322 | #define NETXEN_PCIE_SEM_TIMEOUT 10000 | ||
323 | |||
324 | int | ||
325 | netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg) | ||
326 | { | ||
327 | int done = 0, timeout = 0; | ||
328 | |||
329 | while (!done) { | ||
330 | done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_LOCK(sem))); | ||
331 | if (done == 1) | ||
332 | break; | ||
333 | if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT) | ||
334 | return -1; | ||
335 | msleep(1); | ||
336 | } | ||
337 | |||
338 | if (id_reg) | ||
339 | NXWR32(adapter, id_reg, adapter->portnum); | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | void | ||
345 | netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem) | ||
346 | { | ||
347 | int val; | ||
348 | val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem))); | ||
349 | } | ||
350 | |||
323 | #define NETXEN_UNICAST_ADDR(port, index) \ | 351 | #define NETXEN_UNICAST_ADDR(port, index) \ |
324 | (NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8)) | 352 | (NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8)) |
325 | #define NETXEN_MCAST_ADDR(port, index) \ | 353 | #define NETXEN_MCAST_ADDR(port, index) \ |
@@ -906,33 +934,6 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) | |||
906 | return 0; | 934 | return 0; |
907 | } | 935 | } |
908 | 936 | ||
909 | #define CRB_WIN_LOCK_TIMEOUT 100000000 | ||
910 | |||
911 | static int crb_win_lock(struct netxen_adapter *adapter) | ||
912 | { | ||
913 | int done = 0, timeout = 0; | ||
914 | |||
915 | while (!done) { | ||
916 | /* acquire semaphore3 from PCI HW block */ | ||
917 | done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_LOCK)); | ||
918 | if (done == 1) | ||
919 | break; | ||
920 | if (timeout >= CRB_WIN_LOCK_TIMEOUT) | ||
921 | return -1; | ||
922 | timeout++; | ||
923 | udelay(1); | ||
924 | } | ||
925 | NXWR32(adapter, NETXEN_CRB_WIN_LOCK_ID, adapter->portnum); | ||
926 | return 0; | ||
927 | } | ||
928 | |||
929 | static void crb_win_unlock(struct netxen_adapter *adapter) | ||
930 | { | ||
931 | int val; | ||
932 | |||
933 | val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK)); | ||
934 | } | ||
935 | |||
936 | /* | 937 | /* |
937 | * Changes the CRB window to the specified window. | 938 | * Changes the CRB window to the specified window. |
938 | */ | 939 | */ |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index f5807dae09e9..313cd261b2b0 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -369,37 +369,7 @@ static u32 netxen_decode_crb_addr(u32 addr) | |||
369 | return (pci_base + offset); | 369 | return (pci_base + offset); |
370 | } | 370 | } |
371 | 371 | ||
372 | static long rom_max_timeout = 100; | 372 | #define NETXEN_MAX_ROM_WAIT_USEC 100 |
373 | static long rom_lock_timeout = 10000; | ||
374 | |||
375 | static int rom_lock(struct netxen_adapter *adapter) | ||
376 | { | ||
377 | int iter; | ||
378 | u32 done = 0; | ||
379 | int timeout = 0; | ||
380 | |||
381 | while (!done) { | ||
382 | /* acquire semaphore2 from PCI HW block */ | ||
383 | done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK)); | ||
384 | if (done == 1) | ||
385 | break; | ||
386 | if (timeout >= rom_lock_timeout) | ||
387 | return -EIO; | ||
388 | |||
389 | timeout++; | ||
390 | /* | ||
391 | * Yield CPU | ||
392 | */ | ||
393 | if (!in_atomic()) | ||
394 | schedule(); | ||
395 | else { | ||
396 | for (iter = 0; iter < 20; iter++) | ||
397 | cpu_relax(); /*This a nop instr on i386 */ | ||
398 | } | ||
399 | } | ||
400 | NXWR32(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER); | ||
401 | return 0; | ||
402 | } | ||
403 | 373 | ||
404 | static int netxen_wait_rom_done(struct netxen_adapter *adapter) | 374 | static int netxen_wait_rom_done(struct netxen_adapter *adapter) |
405 | { | 375 | { |
@@ -411,22 +381,16 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter) | |||
411 | while (done == 0) { | 381 | while (done == 0) { |
412 | done = NXRD32(adapter, NETXEN_ROMUSB_GLB_STATUS); | 382 | done = NXRD32(adapter, NETXEN_ROMUSB_GLB_STATUS); |
413 | done &= 2; | 383 | done &= 2; |
414 | timeout++; | 384 | if (++timeout >= NETXEN_MAX_ROM_WAIT_USEC) { |
415 | if (timeout >= rom_max_timeout) { | 385 | dev_err(&adapter->pdev->dev, |
416 | printk("Timeout reached waiting for rom done"); | 386 | "Timeout reached waiting for rom done"); |
417 | return -EIO; | 387 | return -EIO; |
418 | } | 388 | } |
389 | udelay(1); | ||
419 | } | 390 | } |
420 | return 0; | 391 | return 0; |
421 | } | 392 | } |
422 | 393 | ||
423 | static void netxen_rom_unlock(struct netxen_adapter *adapter) | ||
424 | { | ||
425 | /* release semaphore2 */ | ||
426 | NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK)); | ||
427 | |||
428 | } | ||
429 | |||
430 | static int do_rom_fast_read(struct netxen_adapter *adapter, | 394 | static int do_rom_fast_read(struct netxen_adapter *adapter, |
431 | int addr, int *valp) | 395 | int addr, int *valp) |
432 | { | 396 | { |
@@ -471,7 +435,7 @@ netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, | |||
471 | { | 435 | { |
472 | int ret; | 436 | int ret; |
473 | 437 | ||
474 | ret = rom_lock(adapter); | 438 | ret = netxen_rom_lock(adapter); |
475 | if (ret < 0) | 439 | if (ret < 0) |
476 | return ret; | 440 | return ret; |
477 | 441 | ||
@@ -485,7 +449,7 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) | |||
485 | { | 449 | { |
486 | int ret; | 450 | int ret; |
487 | 451 | ||
488 | if (rom_lock(adapter) != 0) | 452 | if (netxen_rom_lock(adapter) != 0) |
489 | return -EIO; | 453 | return -EIO; |
490 | 454 | ||
491 | ret = do_rom_fast_read(adapter, addr, valp); | 455 | ret = do_rom_fast_read(adapter, addr, valp); |
@@ -506,7 +470,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
506 | u32 off; | 470 | u32 off; |
507 | 471 | ||
508 | /* resetall */ | 472 | /* resetall */ |
509 | rom_lock(adapter); | 473 | netxen_rom_lock(adapter); |
510 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); | 474 | NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); |
511 | netxen_rom_unlock(adapter); | 475 | netxen_rom_unlock(adapter); |
512 | 476 | ||
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 8b7cd9e1851a..1392e8994f2c 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c | |||
@@ -30,40 +30,6 @@ | |||
30 | 30 | ||
31 | #include "netxen_nic.h" | 31 | #include "netxen_nic.h" |
32 | 32 | ||
33 | static long phy_lock_timeout = 100000000; | ||
34 | |||
35 | static int phy_lock(struct netxen_adapter *adapter) | ||
36 | { | ||
37 | int i; | ||
38 | int done = 0, timeout = 0; | ||
39 | |||
40 | while (!done) { | ||
41 | done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK)); | ||
42 | if (done == 1) | ||
43 | break; | ||
44 | if (timeout >= phy_lock_timeout) { | ||
45 | return -1; | ||
46 | } | ||
47 | timeout++; | ||
48 | if (!in_atomic()) | ||
49 | schedule(); | ||
50 | else { | ||
51 | for (i = 0; i < 20; i++) | ||
52 | cpu_relax(); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | NXWR32(adapter, NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER); | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int phy_unlock(struct netxen_adapter *adapter) | ||
61 | { | ||
62 | adapter->pci_read_immediate(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK)); | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | /* | 33 | /* |
68 | * netxen_niu_gbe_phy_read - read a register from the GbE PHY via | 34 | * netxen_niu_gbe_phy_read - read a register from the GbE PHY via |
69 | * mii management interface. | 35 | * mii management interface. |
@@ -89,9 +55,8 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, | |||
89 | __u32 status; | 55 | __u32 status; |
90 | __u32 mac_cfg0; | 56 | __u32 mac_cfg0; |
91 | 57 | ||
92 | if (phy_lock(adapter) != 0) { | 58 | if (netxen_phy_lock(adapter) != 0) |
93 | return -1; | 59 | return -1; |
94 | } | ||
95 | 60 | ||
96 | /* | 61 | /* |
97 | * MII mgmt all goes through port 0 MAC interface, | 62 | * MII mgmt all goes through port 0 MAC interface, |
@@ -141,7 +106,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, | |||
141 | if (restore) | 106 | if (restore) |
142 | if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0)) | 107 | if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0)) |
143 | return -EIO; | 108 | return -EIO; |
144 | phy_unlock(adapter); | 109 | netxen_phy_unlock(adapter); |
145 | return result; | 110 | return result; |
146 | } | 111 | } |
147 | 112 | ||