aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorJack Steiner <steiner@sgi.com>2005-08-11 13:27:00 -0400
committerTony Luck <tony.luck@intel.com>2005-08-17 18:31:14 -0400
commit7e95b9d6e21eda23bac1ff024d465d2072c8996d (patch)
tree42b21d53fe8f1f4b1edf32c2509fd69e7a0a7a2a /arch/ia64
parent1007d02160974a46cc4fd3b1737c183c0471b88f (diff)
[IA64-SGI] - New SN hardware support - bte_fixes
Change the BTE driver so that it works for both shub1 and shub2. Most of the changes are related to the number of cores that use the BTE engine, to the MMR addresses of various shub registers, and to using the correct processor or network physical address. Signed-off-by: Russ Anderson <rja@sgi.com> Signed-off-by: Jack Steiner <steiner@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/sn/kernel/bte.c82
1 files changed, 51 insertions, 31 deletions
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
index 647deae9bfcd..7adef84190db 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -29,16 +29,30 @@
29 29
30/* two interfaces on two btes */ 30/* two interfaces on two btes */
31#define MAX_INTERFACES_TO_TRY 4 31#define MAX_INTERFACES_TO_TRY 4
32#define MAX_NODES_TO_TRY 2
32 33
33static struct bteinfo_s *bte_if_on_node(nasid_t nasid, int interface) 34static struct bteinfo_s *bte_if_on_node(nasid_t nasid, int interface)
34{ 35{
35 nodepda_t *tmp_nodepda; 36 nodepda_t *tmp_nodepda;
36 37
38 if (nasid_to_cnodeid(nasid) == -1)
39 return (struct bteinfo_s *)NULL;;
40
37 tmp_nodepda = NODEPDA(nasid_to_cnodeid(nasid)); 41 tmp_nodepda = NODEPDA(nasid_to_cnodeid(nasid));
38 return &tmp_nodepda->bte_if[interface]; 42 return &tmp_nodepda->bte_if[interface];
39 43
40} 44}
41 45
46static inline void bte_start_transfer(struct bteinfo_s *bte, u64 len, u64 mode)
47{
48 if (is_shub2()) {
49 BTE_CTRL_STORE(bte, (IBLS_BUSY | ((len) | (mode) << 24)));
50 } else {
51 BTE_LNSTAT_STORE(bte, len);
52 BTE_CTRL_STORE(bte, mode);
53 }
54}
55
42/************************************************************************ 56/************************************************************************
43 * Block Transfer Engine copy related functions. 57 * Block Transfer Engine copy related functions.
44 * 58 *
@@ -67,13 +81,15 @@ bte_result_t bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
67{ 81{
68 u64 transfer_size; 82 u64 transfer_size;
69 u64 transfer_stat; 83 u64 transfer_stat;
84 u64 notif_phys_addr;
70 struct bteinfo_s *bte; 85 struct bteinfo_s *bte;
71 bte_result_t bte_status; 86 bte_result_t bte_status;
72 unsigned long irq_flags; 87 unsigned long irq_flags;
73 unsigned long itc_end = 0; 88 unsigned long itc_end = 0;
74 struct bteinfo_s *btes_to_try[MAX_INTERFACES_TO_TRY]; 89 int nasid_to_try[MAX_NODES_TO_TRY];
75 int bte_if_index; 90 int my_nasid = get_nasid();
76 int bte_pri, bte_sec; 91 int bte_if_index, nasid_index;
92 int bte_first, btes_per_node = BTES_PER_NODE;
77 93
78 BTE_PRINTK(("bte_copy(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%p)\n", 94 BTE_PRINTK(("bte_copy(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%p)\n",
79 src, dest, len, mode, notification)); 95 src, dest, len, mode, notification));
@@ -86,36 +102,26 @@ bte_result_t bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
86 (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK)); 102 (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK));
87 BUG_ON(!(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT))); 103 BUG_ON(!(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT)));
88 104
89 /* CPU 0 (per node) tries bte0 first, CPU 1 try bte1 first */ 105 /*
90 if (cpuid_to_subnode(smp_processor_id()) == 0) { 106 * Start with interface corresponding to cpu number
91 bte_pri = 0; 107 */
92 bte_sec = 1; 108 bte_first = get_cpu() % btes_per_node;
93 } else {
94 bte_pri = 1;
95 bte_sec = 0;
96 }
97 109
98 if (mode & BTE_USE_DEST) { 110 if (mode & BTE_USE_DEST) {
99 /* try remote then local */ 111 /* try remote then local */
100 btes_to_try[0] = bte_if_on_node(NASID_GET(dest), bte_pri); 112 nasid_to_try[0] = NASID_GET(dest);
101 btes_to_try[1] = bte_if_on_node(NASID_GET(dest), bte_sec);
102 if (mode & BTE_USE_ANY) { 113 if (mode & BTE_USE_ANY) {
103 btes_to_try[2] = bte_if_on_node(get_nasid(), bte_pri); 114 nasid_to_try[1] = my_nasid;
104 btes_to_try[3] = bte_if_on_node(get_nasid(), bte_sec);
105 } else { 115 } else {
106 btes_to_try[2] = NULL; 116 nasid_to_try[1] = (int)NULL;
107 btes_to_try[3] = NULL;
108 } 117 }
109 } else { 118 } else {
110 /* try local then remote */ 119 /* try local then remote */
111 btes_to_try[0] = bte_if_on_node(get_nasid(), bte_pri); 120 nasid_to_try[0] = my_nasid;
112 btes_to_try[1] = bte_if_on_node(get_nasid(), bte_sec);
113 if (mode & BTE_USE_ANY) { 121 if (mode & BTE_USE_ANY) {
114 btes_to_try[2] = bte_if_on_node(NASID_GET(dest), bte_pri); 122 nasid_to_try[1] = NASID_GET(dest);
115 btes_to_try[3] = bte_if_on_node(NASID_GET(dest), bte_sec);
116 } else { 123 } else {
117 btes_to_try[2] = NULL; 124 nasid_to_try[1] = (int)NULL;
118 btes_to_try[3] = NULL;
119 } 125 }
120 } 126 }
121 127
@@ -123,11 +129,12 @@ retry_bteop:
123 do { 129 do {
124 local_irq_save(irq_flags); 130 local_irq_save(irq_flags);
125 131
126 bte_if_index = 0; 132 bte_if_index = bte_first;
133 nasid_index = 0;
127 134
128 /* Attempt to lock one of the BTE interfaces. */ 135 /* Attempt to lock one of the BTE interfaces. */
129 while (bte_if_index < MAX_INTERFACES_TO_TRY) { 136 while (nasid_index < MAX_NODES_TO_TRY) {
130 bte = btes_to_try[bte_if_index++]; 137 bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index);
131 138
132 if (bte == NULL) { 139 if (bte == NULL) {
133 continue; 140 continue;
@@ -143,6 +150,15 @@ retry_bteop:
143 break; 150 break;
144 } 151 }
145 } 152 }
153
154 bte_if_index = (bte_if_index + 1) % btes_per_node; /* Next interface */
155 if (bte_if_index == bte_first) {
156 /*
157 * We've tried all interfaces on this node
158 */
159 nasid_index++;
160 }
161
146 bte = NULL; 162 bte = NULL;
147 } 163 }
148 164
@@ -169,7 +185,13 @@ retry_bteop:
169 185
170 /* Initialize the notification to a known value. */ 186 /* Initialize the notification to a known value. */
171 *bte->most_rcnt_na = BTE_WORD_BUSY; 187 *bte->most_rcnt_na = BTE_WORD_BUSY;
188 notif_phys_addr = TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na));
172 189
190 if (is_shub2()) {
191 src = SH2_TIO_PHYS_TO_DMA(src);
192 dest = SH2_TIO_PHYS_TO_DMA(dest);
193 notif_phys_addr = SH2_TIO_PHYS_TO_DMA(notif_phys_addr);
194 }
173 /* Set the source and destination registers */ 195 /* Set the source and destination registers */
174 BTE_PRINTKV(("IBSA = 0x%lx)\n", (TO_PHYS(src)))); 196 BTE_PRINTKV(("IBSA = 0x%lx)\n", (TO_PHYS(src))));
175 BTE_SRC_STORE(bte, TO_PHYS(src)); 197 BTE_SRC_STORE(bte, TO_PHYS(src));
@@ -177,14 +199,12 @@ retry_bteop:
177 BTE_DEST_STORE(bte, TO_PHYS(dest)); 199 BTE_DEST_STORE(bte, TO_PHYS(dest));
178 200
179 /* Set the notification register */ 201 /* Set the notification register */
180 BTE_PRINTKV(("IBNA = 0x%lx)\n", 202 BTE_PRINTKV(("IBNA = 0x%lx)\n", notif_phys_addr));
181 TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na)))); 203 BTE_NOTIF_STORE(bte, notif_phys_addr);
182 BTE_NOTIF_STORE(bte,
183 TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na)));
184 204
185 /* Initiate the transfer */ 205 /* Initiate the transfer */
186 BTE_PRINTK(("IBCT = 0x%lx)\n", BTE_VALID_MODE(mode))); 206 BTE_PRINTK(("IBCT = 0x%lx)\n", BTE_VALID_MODE(mode)));
187 BTE_START_TRANSFER(bte, transfer_size, BTE_VALID_MODE(mode)); 207 bte_start_transfer(bte, transfer_size, BTE_VALID_MODE(mode));
188 208
189 itc_end = ia64_get_itc() + (40000000 * local_cpu_data->cyc_per_usec); 209 itc_end = ia64_get_itc() + (40000000 * local_cpu_data->cyc_per_usec);
190 210