netxen: fix race in tx ring acccess
[safe/jmp/linux-2.6] / drivers / net / netxen / netxen_nic_hw.c
1 /*
2  * Copyright (C) 2003 - 2009 NetXen, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18  * MA  02111-1307, USA.
19  *
20  * The full GNU General Public License is included in this distribution
21  * in the file called LICENSE.
22  *
23  * Contact Information:
24  *    info@netxen.com
25  * NetXen Inc,
26  * 18922 Forge Drive
27  * Cupertino, CA 95014-0701
28  *
29  */
30
31 #include "netxen_nic.h"
32 #include "netxen_nic_hw.h"
33 #include "netxen_nic_phan_reg.h"
34
35 #include <net/ip.h>
36
37 #define MASK(n) ((1ULL<<(n))-1)
38 #define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
39 #define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
40 #define MS_WIN(addr) (addr & 0x0ffc0000)
41
42 #define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
43
44 #define CRB_BLK(off)    ((off >> 20) & 0x3f)
45 #define CRB_SUBBLK(off) ((off >> 16) & 0xf)
46 #define CRB_WINDOW_2M   (0x130060)
47 #define CRB_HI(off)     ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
48 #define CRB_INDIRECT_2M (0x1e0000UL)
49
50 #ifndef readq
51 static inline u64 readq(void __iomem *addr)
52 {
53         return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
54 }
55 #endif
56
57 #ifndef writeq
58 static inline void writeq(u64 val, void __iomem *addr)
59 {
60         writel(((u32) (val)), (addr));
61         writel(((u32) (val >> 32)), (addr + 4));
62 }
63 #endif
64
65 #define ADDR_IN_RANGE(addr, low, high)  \
66         (((addr) < (high)) && ((addr) >= (low)))
67
68 #define PCI_OFFSET_FIRST_RANGE(adapter, off)    \
69         ((adapter)->ahw.pci_base0 + (off))
70 #define PCI_OFFSET_SECOND_RANGE(adapter, off)   \
71         ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START)
72 #define PCI_OFFSET_THIRD_RANGE(adapter, off)    \
73         ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START)
74
75 static void __iomem *pci_base_offset(struct netxen_adapter *adapter,
76                                             unsigned long off)
77 {
78         if (ADDR_IN_RANGE(off, FIRST_PAGE_GROUP_START, FIRST_PAGE_GROUP_END))
79                 return PCI_OFFSET_FIRST_RANGE(adapter, off);
80
81         if (ADDR_IN_RANGE(off, SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_END))
82                 return PCI_OFFSET_SECOND_RANGE(adapter, off);
83
84         if (ADDR_IN_RANGE(off, THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_END))
85                 return PCI_OFFSET_THIRD_RANGE(adapter, off);
86
87         return NULL;
88 }
89
90 #define CRB_WIN_LOCK_TIMEOUT 100000000
91 static crb_128M_2M_block_map_t
92 crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
93     {{{0, 0,         0,         0} } },         /* 0: PCI */
94     {{{1, 0x0100000, 0x0102000, 0x120000},      /* 1: PCIE */
95           {1, 0x0110000, 0x0120000, 0x130000},
96           {1, 0x0120000, 0x0122000, 0x124000},
97           {1, 0x0130000, 0x0132000, 0x126000},
98           {1, 0x0140000, 0x0142000, 0x128000},
99           {1, 0x0150000, 0x0152000, 0x12a000},
100           {1, 0x0160000, 0x0170000, 0x110000},
101           {1, 0x0170000, 0x0172000, 0x12e000},
102           {0, 0x0000000, 0x0000000, 0x000000},
103           {0, 0x0000000, 0x0000000, 0x000000},
104           {0, 0x0000000, 0x0000000, 0x000000},
105           {0, 0x0000000, 0x0000000, 0x000000},
106           {0, 0x0000000, 0x0000000, 0x000000},
107           {0, 0x0000000, 0x0000000, 0x000000},
108           {1, 0x01e0000, 0x01e0800, 0x122000},
109           {0, 0x0000000, 0x0000000, 0x000000} } },
110         {{{1, 0x0200000, 0x0210000, 0x180000} } },/* 2: MN */
111     {{{0, 0,         0,         0} } },     /* 3: */
112     {{{1, 0x0400000, 0x0401000, 0x169000} } },/* 4: P2NR1 */
113     {{{1, 0x0500000, 0x0510000, 0x140000} } },/* 5: SRE   */
114     {{{1, 0x0600000, 0x0610000, 0x1c0000} } },/* 6: NIU   */
115     {{{1, 0x0700000, 0x0704000, 0x1b8000} } },/* 7: QM    */
116     {{{1, 0x0800000, 0x0802000, 0x170000},  /* 8: SQM0  */
117       {0, 0x0000000, 0x0000000, 0x000000},
118       {0, 0x0000000, 0x0000000, 0x000000},
119       {0, 0x0000000, 0x0000000, 0x000000},
120       {0, 0x0000000, 0x0000000, 0x000000},
121       {0, 0x0000000, 0x0000000, 0x000000},
122       {0, 0x0000000, 0x0000000, 0x000000},
123       {0, 0x0000000, 0x0000000, 0x000000},
124       {0, 0x0000000, 0x0000000, 0x000000},
125       {0, 0x0000000, 0x0000000, 0x000000},
126       {0, 0x0000000, 0x0000000, 0x000000},
127       {0, 0x0000000, 0x0000000, 0x000000},
128       {0, 0x0000000, 0x0000000, 0x000000},
129       {0, 0x0000000, 0x0000000, 0x000000},
130       {0, 0x0000000, 0x0000000, 0x000000},
131       {1, 0x08f0000, 0x08f2000, 0x172000} } },
132     {{{1, 0x0900000, 0x0902000, 0x174000},      /* 9: SQM1*/
133       {0, 0x0000000, 0x0000000, 0x000000},
134       {0, 0x0000000, 0x0000000, 0x000000},
135       {0, 0x0000000, 0x0000000, 0x000000},
136       {0, 0x0000000, 0x0000000, 0x000000},
137       {0, 0x0000000, 0x0000000, 0x000000},
138       {0, 0x0000000, 0x0000000, 0x000000},
139       {0, 0x0000000, 0x0000000, 0x000000},
140       {0, 0x0000000, 0x0000000, 0x000000},
141       {0, 0x0000000, 0x0000000, 0x000000},
142       {0, 0x0000000, 0x0000000, 0x000000},
143       {0, 0x0000000, 0x0000000, 0x000000},
144       {0, 0x0000000, 0x0000000, 0x000000},
145       {0, 0x0000000, 0x0000000, 0x000000},
146       {0, 0x0000000, 0x0000000, 0x000000},
147       {1, 0x09f0000, 0x09f2000, 0x176000} } },
148     {{{0, 0x0a00000, 0x0a02000, 0x178000},      /* 10: SQM2*/
149       {0, 0x0000000, 0x0000000, 0x000000},
150       {0, 0x0000000, 0x0000000, 0x000000},
151       {0, 0x0000000, 0x0000000, 0x000000},
152       {0, 0x0000000, 0x0000000, 0x000000},
153       {0, 0x0000000, 0x0000000, 0x000000},
154       {0, 0x0000000, 0x0000000, 0x000000},
155       {0, 0x0000000, 0x0000000, 0x000000},
156       {0, 0x0000000, 0x0000000, 0x000000},
157       {0, 0x0000000, 0x0000000, 0x000000},
158       {0, 0x0000000, 0x0000000, 0x000000},
159       {0, 0x0000000, 0x0000000, 0x000000},
160       {0, 0x0000000, 0x0000000, 0x000000},
161       {0, 0x0000000, 0x0000000, 0x000000},
162       {0, 0x0000000, 0x0000000, 0x000000},
163       {1, 0x0af0000, 0x0af2000, 0x17a000} } },
164     {{{0, 0x0b00000, 0x0b02000, 0x17c000},      /* 11: SQM3*/
165       {0, 0x0000000, 0x0000000, 0x000000},
166       {0, 0x0000000, 0x0000000, 0x000000},
167       {0, 0x0000000, 0x0000000, 0x000000},
168       {0, 0x0000000, 0x0000000, 0x000000},
169       {0, 0x0000000, 0x0000000, 0x000000},
170       {0, 0x0000000, 0x0000000, 0x000000},
171       {0, 0x0000000, 0x0000000, 0x000000},
172       {0, 0x0000000, 0x0000000, 0x000000},
173       {0, 0x0000000, 0x0000000, 0x000000},
174       {0, 0x0000000, 0x0000000, 0x000000},
175       {0, 0x0000000, 0x0000000, 0x000000},
176       {0, 0x0000000, 0x0000000, 0x000000},
177       {0, 0x0000000, 0x0000000, 0x000000},
178       {0, 0x0000000, 0x0000000, 0x000000},
179       {1, 0x0bf0000, 0x0bf2000, 0x17e000} } },
180         {{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },/* 12: I2Q */
181         {{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },/* 13: TMR */
182         {{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },/* 14: ROMUSB */
183         {{{1, 0x0f00000, 0x0f01000, 0x164000} } },/* 15: PEG4 */
184         {{{0, 0x1000000, 0x1004000, 0x1a8000} } },/* 16: XDMA */
185         {{{1, 0x1100000, 0x1101000, 0x160000} } },/* 17: PEG0 */
186         {{{1, 0x1200000, 0x1201000, 0x161000} } },/* 18: PEG1 */
187         {{{1, 0x1300000, 0x1301000, 0x162000} } },/* 19: PEG2 */
188         {{{1, 0x1400000, 0x1401000, 0x163000} } },/* 20: PEG3 */
189         {{{1, 0x1500000, 0x1501000, 0x165000} } },/* 21: P2ND */
190         {{{1, 0x1600000, 0x1601000, 0x166000} } },/* 22: P2NI */
191         {{{0, 0,         0,         0} } },     /* 23: */
192         {{{0, 0,         0,         0} } },     /* 24: */
193         {{{0, 0,         0,         0} } },     /* 25: */
194         {{{0, 0,         0,         0} } },     /* 26: */
195         {{{0, 0,         0,         0} } },     /* 27: */
196         {{{0, 0,         0,         0} } },     /* 28: */
197         {{{1, 0x1d00000, 0x1d10000, 0x190000} } },/* 29: MS */
198     {{{1, 0x1e00000, 0x1e01000, 0x16a000} } },/* 30: P2NR2 */
199     {{{1, 0x1f00000, 0x1f10000, 0x150000} } },/* 31: EPG */
200         {{{0} } },                              /* 32: PCI */
201         {{{1, 0x2100000, 0x2102000, 0x120000},  /* 33: PCIE */
202           {1, 0x2110000, 0x2120000, 0x130000},
203           {1, 0x2120000, 0x2122000, 0x124000},
204           {1, 0x2130000, 0x2132000, 0x126000},
205           {1, 0x2140000, 0x2142000, 0x128000},
206           {1, 0x2150000, 0x2152000, 0x12a000},
207           {1, 0x2160000, 0x2170000, 0x110000},
208           {1, 0x2170000, 0x2172000, 0x12e000},
209           {0, 0x0000000, 0x0000000, 0x000000},
210           {0, 0x0000000, 0x0000000, 0x000000},
211           {0, 0x0000000, 0x0000000, 0x000000},
212           {0, 0x0000000, 0x0000000, 0x000000},
213           {0, 0x0000000, 0x0000000, 0x000000},
214           {0, 0x0000000, 0x0000000, 0x000000},
215           {0, 0x0000000, 0x0000000, 0x000000},
216           {0, 0x0000000, 0x0000000, 0x000000} } },
217         {{{1, 0x2200000, 0x2204000, 0x1b0000} } },/* 34: CAM */
218         {{{0} } },                              /* 35: */
219         {{{0} } },                              /* 36: */
220         {{{0} } },                              /* 37: */
221         {{{0} } },                              /* 38: */
222         {{{0} } },                              /* 39: */
223         {{{1, 0x2800000, 0x2804000, 0x1a4000} } },/* 40: TMR */
224         {{{1, 0x2900000, 0x2901000, 0x16b000} } },/* 41: P2NR3 */
225         {{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },/* 42: RPMX1 */
226         {{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },/* 43: RPMX2 */
227         {{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },/* 44: RPMX3 */
228         {{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },/* 45: RPMX4 */
229         {{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },/* 46: RPMX5 */
230         {{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },/* 47: RPMX6 */
231         {{{1, 0x3000000, 0x3000400, 0x1adc00} } },/* 48: RPMX7 */
232         {{{0, 0x3100000, 0x3104000, 0x1a8000} } },/* 49: XDMA */
233         {{{1, 0x3200000, 0x3204000, 0x1d4000} } },/* 50: I2Q */
234         {{{1, 0x3300000, 0x3304000, 0x1a0000} } },/* 51: ROMUSB */
235         {{{0} } },                              /* 52: */
236         {{{1, 0x3500000, 0x3500400, 0x1ac000} } },/* 53: RPMX0 */
237         {{{1, 0x3600000, 0x3600400, 0x1ae000} } },/* 54: RPMX8 */
238         {{{1, 0x3700000, 0x3700400, 0x1ae400} } },/* 55: RPMX9 */
239         {{{1, 0x3800000, 0x3804000, 0x1d0000} } },/* 56: OCM0 */
240         {{{1, 0x3900000, 0x3904000, 0x1b4000} } },/* 57: CRYPTO */
241         {{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },/* 58: SMB */
242         {{{0} } },                              /* 59: I2C0 */
243         {{{0} } },                              /* 60: I2C1 */
244         {{{1, 0x3d00000, 0x3d04000, 0x1d8000} } },/* 61: LPC */
245         {{{1, 0x3e00000, 0x3e01000, 0x167000} } },/* 62: P2NC */
246         {{{1, 0x3f00000, 0x3f01000, 0x168000} } }       /* 63: P2NR0 */
247 };
248
249 /*
250  * top 12 bits of crb internal address (hub, agent)
251  */
252 static unsigned crb_hub_agt[64] =
253 {
254         0,
255         NETXEN_HW_CRB_HUB_AGT_ADR_PS,
256         NETXEN_HW_CRB_HUB_AGT_ADR_MN,
257         NETXEN_HW_CRB_HUB_AGT_ADR_MS,
258         0,
259         NETXEN_HW_CRB_HUB_AGT_ADR_SRE,
260         NETXEN_HW_CRB_HUB_AGT_ADR_NIU,
261         NETXEN_HW_CRB_HUB_AGT_ADR_QMN,
262         NETXEN_HW_CRB_HUB_AGT_ADR_SQN0,
263         NETXEN_HW_CRB_HUB_AGT_ADR_SQN1,
264         NETXEN_HW_CRB_HUB_AGT_ADR_SQN2,
265         NETXEN_HW_CRB_HUB_AGT_ADR_SQN3,
266         NETXEN_HW_CRB_HUB_AGT_ADR_I2Q,
267         NETXEN_HW_CRB_HUB_AGT_ADR_TIMR,
268         NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB,
269         NETXEN_HW_CRB_HUB_AGT_ADR_PGN4,
270         NETXEN_HW_CRB_HUB_AGT_ADR_XDMA,
271         NETXEN_HW_CRB_HUB_AGT_ADR_PGN0,
272         NETXEN_HW_CRB_HUB_AGT_ADR_PGN1,
273         NETXEN_HW_CRB_HUB_AGT_ADR_PGN2,
274         NETXEN_HW_CRB_HUB_AGT_ADR_PGN3,
275         NETXEN_HW_CRB_HUB_AGT_ADR_PGND,
276         NETXEN_HW_CRB_HUB_AGT_ADR_PGNI,
277         NETXEN_HW_CRB_HUB_AGT_ADR_PGS0,
278         NETXEN_HW_CRB_HUB_AGT_ADR_PGS1,
279         NETXEN_HW_CRB_HUB_AGT_ADR_PGS2,
280         NETXEN_HW_CRB_HUB_AGT_ADR_PGS3,
281         0,
282         NETXEN_HW_CRB_HUB_AGT_ADR_PGSI,
283         NETXEN_HW_CRB_HUB_AGT_ADR_SN,
284         0,
285         NETXEN_HW_CRB_HUB_AGT_ADR_EG,
286         0,
287         NETXEN_HW_CRB_HUB_AGT_ADR_PS,
288         NETXEN_HW_CRB_HUB_AGT_ADR_CAM,
289         0,
290         0,
291         0,
292         0,
293         0,
294         NETXEN_HW_CRB_HUB_AGT_ADR_TIMR,
295         0,
296         NETXEN_HW_CRB_HUB_AGT_ADR_RPMX1,
297         NETXEN_HW_CRB_HUB_AGT_ADR_RPMX2,
298         NETXEN_HW_CRB_HUB_AGT_ADR_RPMX3,
299         NETXEN_HW_CRB_HUB_AGT_ADR_RPMX4,
300         NETXEN_HW_CRB_HUB_AGT_ADR_RPMX5,
301         NETXEN_HW_CRB_HUB_AGT_ADR_RPMX6,
302         NETXEN_HW_CRB_HUB_AGT_ADR_RPMX7,
303         NETXEN_HW_CRB_HUB_AGT_ADR_XDMA,
304         NETXEN_HW_CRB_HUB_AGT_ADR_I2Q,
305         NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB,
306         0,
307         NETXEN_HW_CRB_HUB_AGT_ADR_RPMX0,
308         NETXEN_HW_CRB_HUB_AGT_ADR_RPMX8,
309         NETXEN_HW_CRB_HUB_AGT_ADR_RPMX9,
310         NETXEN_HW_CRB_HUB_AGT_ADR_OCM0,
311         0,
312         NETXEN_HW_CRB_HUB_AGT_ADR_SMB,
313         NETXEN_HW_CRB_HUB_AGT_ADR_I2C0,
314         NETXEN_HW_CRB_HUB_AGT_ADR_I2C1,
315         0,
316         NETXEN_HW_CRB_HUB_AGT_ADR_PGNC,
317         0,
318 };
319
320 /*  PCI Windowing for DDR regions.  */
321
322 #define NETXEN_WINDOW_ONE       0x2000000 /*CRB Window: bit 25 of CRB address */
323
324 int netxen_nic_set_mac(struct net_device *netdev, void *p)
325 {
326         struct netxen_adapter *adapter = netdev_priv(netdev);
327         struct sockaddr *addr = p;
328
329         if (netif_running(netdev))
330                 return -EBUSY;
331
332         if (!is_valid_ether_addr(addr->sa_data))
333                 return -EADDRNOTAVAIL;
334
335         memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
336
337         /* For P3, MAC addr is not set in NIU */
338         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
339                 if (adapter->macaddr_set)
340                         adapter->macaddr_set(adapter, addr->sa_data);
341
342         return 0;
343 }
344
345 #define NETXEN_UNICAST_ADDR(port, index) \
346         (NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8))
347 #define NETXEN_MCAST_ADDR(port, index) \
348         (NETXEN_MULTICAST_ADDR_BASE+(port*0x80)+(index*8))
349 #define MAC_HI(addr) \
350         ((addr[2] << 16) | (addr[1] << 8) | (addr[0]))
351 #define MAC_LO(addr) \
352         ((addr[5] << 16) | (addr[4] << 8) | (addr[3]))
353
354 static int
355 netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
356 {
357         u32     val = 0;
358         u16 port = adapter->physical_port;
359         u8 *addr = adapter->netdev->dev_addr;
360
361         if (adapter->mc_enabled)
362                 return 0;
363
364         val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
365         val |= (1UL << (28+port));
366         NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
367
368         /* add broadcast addr to filter */
369         val = 0xffffff;
370         NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
371         NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
372
373         /* add station addr to filter */
374         val = MAC_HI(addr);
375         NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
376         val = MAC_LO(addr);
377         NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, val);
378
379         adapter->mc_enabled = 1;
380         return 0;
381 }
382
383 static int
384 netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter)
385 {
386         u32     val = 0;
387         u16 port = adapter->physical_port;
388         u8 *addr = adapter->netdev->dev_addr;
389
390         if (!adapter->mc_enabled)
391                 return 0;
392
393         val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
394         val &= ~(1UL << (28+port));
395         NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
396
397         val = MAC_HI(addr);
398         NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
399         val = MAC_LO(addr);
400         NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
401
402         NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
403         NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);
404
405         adapter->mc_enabled = 0;
406         return 0;
407 }
408
409 static int
410 netxen_nic_set_mcast_addr(struct netxen_adapter *adapter,
411                 int index, u8 *addr)
412 {
413         u32 hi = 0, lo = 0;
414         u16 port = adapter->physical_port;
415
416         lo = MAC_LO(addr);
417         hi = MAC_HI(addr);
418
419         NXWR32(adapter, NETXEN_MCAST_ADDR(port, index), hi);
420         NXWR32(adapter, NETXEN_MCAST_ADDR(port, index)+4, lo);
421
422         return 0;
423 }
424
425 void netxen_p2_nic_set_multi(struct net_device *netdev)
426 {
427         struct netxen_adapter *adapter = netdev_priv(netdev);
428         struct dev_mc_list *mc_ptr;
429         u8 null_addr[6];
430         int index = 0;
431
432         memset(null_addr, 0, 6);
433
434         if (netdev->flags & IFF_PROMISC) {
435
436                 adapter->set_promisc(adapter,
437                                 NETXEN_NIU_PROMISC_MODE);
438
439                 /* Full promiscuous mode */
440                 netxen_nic_disable_mcast_filter(adapter);
441
442                 return;
443         }
444
445         if (netdev->mc_count == 0) {
446                 adapter->set_promisc(adapter,
447                                 NETXEN_NIU_NON_PROMISC_MODE);
448                 netxen_nic_disable_mcast_filter(adapter);
449                 return;
450         }
451
452         adapter->set_promisc(adapter, NETXEN_NIU_ALLMULTI_MODE);
453         if (netdev->flags & IFF_ALLMULTI ||
454                         netdev->mc_count > adapter->max_mc_count) {
455                 netxen_nic_disable_mcast_filter(adapter);
456                 return;
457         }
458
459         netxen_nic_enable_mcast_filter(adapter);
460
461         for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next, index++)
462                 netxen_nic_set_mcast_addr(adapter, index, mc_ptr->dmi_addr);
463
464         if (index != netdev->mc_count)
465                 printk(KERN_WARNING "%s: %s multicast address count mismatch\n",
466                         netxen_nic_driver_name, netdev->name);
467
468         /* Clear out remaining addresses */
469         for (; index < adapter->max_mc_count; index++)
470                 netxen_nic_set_mcast_addr(adapter, index, null_addr);
471 }
472
473 static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
474                 u8 *addr, nx_mac_list_t **add_list, nx_mac_list_t **del_list)
475 {
476         nx_mac_list_t *cur, *prev;
477
478         /* if in del_list, move it to adapter->mac_list */
479         for (cur = *del_list, prev = NULL; cur;) {
480                 if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
481                         if (prev == NULL)
482                                 *del_list = cur->next;
483                         else
484                                 prev->next = cur->next;
485                         cur->next = adapter->mac_list;
486                         adapter->mac_list = cur;
487                         return 0;
488                 }
489                 prev = cur;
490                 cur = cur->next;
491         }
492
493         /* make sure to add each mac address only once */
494         for (cur = adapter->mac_list; cur; cur = cur->next) {
495                 if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
496                         return 0;
497         }
498         /* not in del_list, create new entry and add to add_list */
499         cur = kmalloc(sizeof(*cur), in_atomic()? GFP_ATOMIC : GFP_KERNEL);
500         if (cur == NULL) {
501                 printk(KERN_ERR "%s: cannot allocate memory. MAC filtering may"
502                                 "not work properly from now.\n", __func__);
503                 return -1;
504         }
505
506         memcpy(cur->mac_addr, addr, ETH_ALEN);
507         cur->next = *add_list;
508         *add_list = cur;
509         return 0;
510 }
511
512 static int
513 netxen_send_cmd_descs(struct netxen_adapter *adapter,
514                 struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
515 {
516         u32 i, producer, consumer;
517         struct netxen_cmd_buffer *pbuf;
518         struct cmd_desc_type0 *cmd_desc;
519         struct nx_host_tx_ring *tx_ring;
520
521         i = 0;
522
523         tx_ring = adapter->tx_ring;
524         netif_tx_lock_bh(adapter->netdev);
525
526         producer = tx_ring->producer;
527         consumer = tx_ring->sw_consumer;
528
529         if (nr_desc >= find_diff_among(producer, consumer, tx_ring->num_desc)) {
530                 netif_tx_unlock_bh(adapter->netdev);
531                 return -EBUSY;
532         }
533
534         do {
535                 cmd_desc = &cmd_desc_arr[i];
536
537                 pbuf = &tx_ring->cmd_buf_arr[producer];
538                 pbuf->skb = NULL;
539                 pbuf->frag_count = 0;
540
541                 memcpy(&tx_ring->desc_head[producer],
542                         &cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
543
544                 producer = get_next_index(producer, tx_ring->num_desc);
545                 i++;
546
547         } while (i != nr_desc);
548
549         tx_ring->producer = producer;
550
551         netxen_nic_update_cmd_producer(adapter, tx_ring, producer);
552
553         netif_tx_unlock_bh(adapter->netdev);
554
555         return 0;
556 }
557
558 static int nx_p3_sre_macaddr_change(struct net_device *dev,
559                 u8 *addr, unsigned op)
560 {
561         struct netxen_adapter *adapter = netdev_priv(dev);
562         nx_nic_req_t req;
563         nx_mac_req_t *mac_req;
564         u64 word;
565         int rv;
566
567         memset(&req, 0, sizeof(nx_nic_req_t));
568         req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);
569
570         word = NX_MAC_EVENT | ((u64)adapter->portnum << 16);
571         req.req_hdr = cpu_to_le64(word);
572
573         mac_req = (nx_mac_req_t *)&req.words[0];
574         mac_req->op = op;
575         memcpy(mac_req->mac_addr, addr, 6);
576
577         rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
578         if (rv != 0) {
579                 printk(KERN_ERR "ERROR. Could not send mac update\n");
580                 return rv;
581         }
582
583         return 0;
584 }
585
586 void netxen_p3_nic_set_multi(struct net_device *netdev)
587 {
588         struct netxen_adapter *adapter = netdev_priv(netdev);
589         nx_mac_list_t *cur, *next, *del_list, *add_list = NULL;
590         struct dev_mc_list *mc_ptr;
591         u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
592         u32 mode = VPORT_MISS_MODE_DROP;
593
594         del_list = adapter->mac_list;
595         adapter->mac_list = NULL;
596
597         nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list);
598         nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
599
600         if (netdev->flags & IFF_PROMISC) {
601                 mode = VPORT_MISS_MODE_ACCEPT_ALL;
602                 goto send_fw_cmd;
603         }
604
605         if ((netdev->flags & IFF_ALLMULTI) ||
606                         (netdev->mc_count > adapter->max_mc_count)) {
607                 mode = VPORT_MISS_MODE_ACCEPT_MULTI;
608                 goto send_fw_cmd;
609         }
610
611         if (netdev->mc_count > 0) {
612                 for (mc_ptr = netdev->mc_list; mc_ptr;
613                      mc_ptr = mc_ptr->next) {
614                         nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr,
615                                           &add_list, &del_list);
616                 }
617         }
618
619 send_fw_cmd:
620         adapter->set_promisc(adapter, mode);
621         for (cur = del_list; cur;) {
622                 nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL);
623                 next = cur->next;
624                 kfree(cur);
625                 cur = next;
626         }
627         for (cur = add_list; cur;) {
628                 nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_ADD);
629                 next = cur->next;
630                 cur->next = adapter->mac_list;
631                 adapter->mac_list = cur;
632                 cur = next;
633         }
634 }
635
636 int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
637 {
638         nx_nic_req_t req;
639         u64 word;
640
641         memset(&req, 0, sizeof(nx_nic_req_t));
642
643         req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
644
645         word = NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE |
646                         ((u64)adapter->portnum << 16);
647         req.req_hdr = cpu_to_le64(word);
648
649         req.words[0] = cpu_to_le64(mode);
650
651         return netxen_send_cmd_descs(adapter,
652                                 (struct cmd_desc_type0 *)&req, 1);
653 }
654
655 void netxen_p3_free_mac_list(struct netxen_adapter *adapter)
656 {
657         nx_mac_list_t *cur, *next;
658
659         cur = adapter->mac_list;
660
661         while (cur) {
662                 next = cur->next;
663                 kfree(cur);
664                 cur = next;
665         }
666 }
667
668 #define NETXEN_CONFIG_INTR_COALESCE     3
669
670 /*
671  * Send the interrupt coalescing parameter set by ethtool to the card.
672  */
673 int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
674 {
675         nx_nic_req_t req;
676         u64 word;
677         int rv;
678
679         memset(&req, 0, sizeof(nx_nic_req_t));
680
681         req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);
682
683         word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
684         req.req_hdr = cpu_to_le64(word);
685
686         memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal));
687
688         rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
689         if (rv != 0) {
690                 printk(KERN_ERR "ERROR. Could not send "
691                         "interrupt coalescing parameters\n");
692         }
693
694         return rv;
695 }
696
697 #define RSS_HASHTYPE_IP_TCP     0x3
698
699 int netxen_config_rss(struct netxen_adapter *adapter, int enable)
700 {
701         nx_nic_req_t req;
702         u64 word;
703         int i, rv;
704
705         u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
706                         0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
707                         0x255b0ec26d5a56daULL };
708
709
710         memset(&req, 0, sizeof(nx_nic_req_t));
711         req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
712
713         word = NX_NIC_H2C_OPCODE_CONFIG_RSS | ((u64)adapter->portnum << 16);
714         req.req_hdr = cpu_to_le64(word);
715
716         /*
717          * RSS request:
718          * bits 3-0: hash_method
719          *      5-4: hash_type_ipv4
720          *      7-6: hash_type_ipv6
721          *        8: enable
722          *        9: use indirection table
723          *    47-10: reserved
724          *    63-48: indirection table mask
725          */
726         word =  ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
727                 ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
728                 ((u64)(enable & 0x1) << 8) |
729                 ((0x7ULL) << 48);
730         req.words[0] = cpu_to_le64(word);
731         for (i = 0; i < 5; i++)
732                 req.words[i+1] = cpu_to_le64(key[i]);
733
734
735         rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
736         if (rv != 0) {
737                 printk(KERN_ERR "%s: could not configure RSS\n",
738                                 adapter->netdev->name);
739         }
740
741         return rv;
742 }
743
744 int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
745 {
746         nx_nic_req_t req;
747         u64 word;
748         int rv;
749
750         memset(&req, 0, sizeof(nx_nic_req_t));
751         req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
752
753         word = NX_NIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16);
754         req.req_hdr = cpu_to_le64(word);
755         req.words[0] = cpu_to_le64(enable | (enable << 8));
756
757         rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
758         if (rv != 0) {
759                 printk(KERN_ERR "%s: could not configure link notification\n",
760                                 adapter->netdev->name);
761         }
762
763         return rv;
764 }
765
766 /*
767  * netxen_nic_change_mtu - Change the Maximum Transfer Unit
768  * @returns 0 on success, negative on failure
769  */
770
771 #define MTU_FUDGE_FACTOR        100
772
773 int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
774 {
775         struct netxen_adapter *adapter = netdev_priv(netdev);
776         int max_mtu;
777         int rc = 0;
778
779         if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
780                 max_mtu = P3_MAX_MTU;
781         else
782                 max_mtu = P2_MAX_MTU;
783
784         if (mtu > max_mtu) {
785                 printk(KERN_ERR "%s: mtu > %d bytes unsupported\n",
786                                 netdev->name, max_mtu);
787                 return -EINVAL;
788         }
789
790         if (adapter->set_mtu)
791                 rc = adapter->set_mtu(adapter, mtu);
792
793         if (!rc)
794                 netdev->mtu = mtu;
795
796         return rc;
797 }
798
799 static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
800                                   int size, __le32 * buf)
801 {
802         int i, v, addr;
803         __le32 *ptr32;
804
805         addr = base;
806         ptr32 = buf;
807         for (i = 0; i < size / sizeof(u32); i++) {
808                 if (netxen_rom_fast_read(adapter, addr, &v) == -1)
809                         return -1;
810                 *ptr32 = cpu_to_le32(v);
811                 ptr32++;
812                 addr += sizeof(u32);
813         }
814         if ((char *)buf + size > (char *)ptr32) {
815                 __le32 local;
816                 if (netxen_rom_fast_read(adapter, addr, &v) == -1)
817                         return -1;
818                 local = cpu_to_le32(v);
819                 memcpy(ptr32, &local, (char *)buf + size - (char *)ptr32);
820         }
821
822         return 0;
823 }
824
825 int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
826 {
827         __le32 *pmac = (__le32 *) mac;
828         u32 offset;
829
830         offset = NETXEN_USER_START +
831                 offsetof(struct netxen_new_user_info, mac_addr) +
832                 adapter->portnum * sizeof(u64);
833
834         if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1)
835                 return -1;
836
837         if (*mac == cpu_to_le64(~0ULL)) {
838
839                 offset = NETXEN_USER_START_OLD +
840                         offsetof(struct netxen_user_old_info, mac_addr) +
841                         adapter->portnum * sizeof(u64);
842
843                 if (netxen_get_flash_block(adapter,
844                                         offset, sizeof(u64), pmac) == -1)
845                         return -1;
846
847                 if (*mac == cpu_to_le64(~0ULL))
848                         return -1;
849         }
850         return 0;
851 }
852
853 int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
854 {
855         uint32_t crbaddr, mac_hi, mac_lo;
856         int pci_func = adapter->ahw.pci_func;
857
858         crbaddr = CRB_MAC_BLOCK_START +
859                 (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
860
861         mac_lo = NXRD32(adapter, crbaddr);
862         mac_hi = NXRD32(adapter, crbaddr+4);
863
864         if (pci_func & 1)
865                 *mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16));
866         else
867                 *mac = le64_to_cpu((u64)mac_lo | ((u64)mac_hi << 32));
868
869         return 0;
870 }
871
872 #define CRB_WIN_LOCK_TIMEOUT 100000000
873
874 static int crb_win_lock(struct netxen_adapter *adapter)
875 {
876         int done = 0, timeout = 0;
877
878         while (!done) {
879                 /* acquire semaphore3 from PCI HW block */
880                 done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_LOCK));
881                 if (done == 1)
882                         break;
883                 if (timeout >= CRB_WIN_LOCK_TIMEOUT)
884                         return -1;
885                 timeout++;
886                 udelay(1);
887         }
888         NXWR32(adapter, NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
889         return 0;
890 }
891
892 static void crb_win_unlock(struct netxen_adapter *adapter)
893 {
894         int val;
895
896         val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK));
897 }
898
899 /*
900  * Changes the CRB window to the specified window.
901  */
902 void
903 netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw)
904 {
905         void __iomem *offset;
906         u32 tmp;
907         int count = 0;
908         uint8_t func = adapter->ahw.pci_func;
909
910         if (adapter->curr_window == wndw)
911                 return;
912         /*
913          * Move the CRB window.
914          * We need to write to the "direct access" region of PCI
915          * to avoid a race condition where the window register has
916          * not been successfully written across CRB before the target
917          * register address is received by PCI. The direct region bypasses
918          * the CRB bus.
919          */
920         offset = PCI_OFFSET_SECOND_RANGE(adapter,
921                         NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func)));
922
923         if (wndw & 0x1)
924                 wndw = NETXEN_WINDOW_ONE;
925
926         writel(wndw, offset);
927
928         /* MUST make sure window is set before we forge on... */
929         while ((tmp = readl(offset)) != wndw) {
930                 printk(KERN_WARNING "%s: %s WARNING: CRB window value not "
931                        "registered properly: 0x%08x.\n",
932                        netxen_nic_driver_name, __func__, tmp);
933                 mdelay(1);
934                 if (count >= 10)
935                         break;
936                 count++;
937         }
938
939         if (wndw == NETXEN_WINDOW_ONE)
940                 adapter->curr_window = 1;
941         else
942                 adapter->curr_window = 0;
943 }
944
945 /*
946  * Return -1 if off is not valid,
947  *       1 if window access is needed. 'off' is set to offset from
948  *         CRB space in 128M pci map
949  *       0 if no window access is needed. 'off' is set to 2M addr
950  * In: 'off' is offset from base in 128M pci map
951  */
952 static int
953 netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter,
954                 ulong *off, int len)
955 {
956         unsigned long end = *off + len;
957         crb_128M_2M_sub_block_map_t *m;
958
959
960         if (*off >= NETXEN_CRB_MAX)
961                 return -1;
962
963         if (*off >= NETXEN_PCI_CAMQM && (end <= NETXEN_PCI_CAMQM_2M_END)) {
964                 *off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE +
965                         (ulong)adapter->ahw.pci_base0;
966                 return 0;
967         }
968
969         if (*off < NETXEN_PCI_CRBSPACE)
970                 return -1;
971
972         *off -= NETXEN_PCI_CRBSPACE;
973         end = *off + len;
974
975         /*
976          * Try direct map
977          */
978         m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
979
980         if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) {
981                 *off = *off + m->start_2M - m->start_128M +
982                         (ulong)adapter->ahw.pci_base0;
983                 return 0;
984         }
985
986         /*
987          * Not in direct map, use crb window
988          */
989         return 1;
990 }
991
992 /*
993  * In: 'off' is offset from CRB space in 128M pci map
994  * Out: 'off' is 2M pci map addr
995  * side effect: lock crb window
996  */
997 static void
998 netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
999 {
1000         u32 win_read;
1001
1002         adapter->crb_win = CRB_HI(*off);
1003         writel(adapter->crb_win, (adapter->ahw.pci_base0 + CRB_WINDOW_2M));
1004         /*
1005          * Read back value to make sure write has gone through before trying
1006          * to use it.
1007          */
1008         win_read = readl(adapter->ahw.pci_base0 + CRB_WINDOW_2M);
1009         if (win_read != adapter->crb_win) {
1010                 printk(KERN_ERR "%s: Written crbwin (0x%x) != "
1011                                 "Read crbwin (0x%x), off=0x%lx\n",
1012                                 __func__, adapter->crb_win, win_read, *off);
1013         }
1014         *off = (*off & MASK(16)) + CRB_INDIRECT_2M +
1015                 (ulong)adapter->ahw.pci_base0;
1016 }
1017
1018 int
1019 netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
1020 {
1021         void __iomem *addr;
1022
1023         if (ADDR_IN_WINDOW1(off)) {
1024                 addr = NETXEN_CRB_NORMALIZE(adapter, off);
1025         } else {                /* Window 0 */
1026                 addr = pci_base_offset(adapter, off);
1027                 netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1028         }
1029
1030         if (!addr) {
1031                 netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1032                 return 1;
1033         }
1034
1035         writel(data, addr);
1036
1037         if (!ADDR_IN_WINDOW1(off))
1038                 netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1039
1040         return 0;
1041 }
1042
1043 u32
1044 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
1045 {
1046         void __iomem *addr;
1047         u32 data;
1048
1049         if (ADDR_IN_WINDOW1(off)) {     /* Window 1 */
1050                 addr = NETXEN_CRB_NORMALIZE(adapter, off);
1051         } else {                /* Window 0 */
1052                 addr = pci_base_offset(adapter, off);
1053                 netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1054         }
1055
1056         if (!addr) {
1057                 netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1058                 return 1;
1059         }
1060
1061         data = readl(addr);
1062
1063         if (!ADDR_IN_WINDOW1(off))
1064                 netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1065
1066         return data;
1067 }
1068
1069 int
1070 netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
1071 {
1072         unsigned long flags = 0;
1073         int rv;
1074
1075         rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, 4);
1076
1077         if (rv == -1) {
1078                 printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
1079                                 __func__, off);
1080                 dump_stack();
1081                 return -1;
1082         }
1083
1084         if (rv == 1) {
1085                 write_lock_irqsave(&adapter->adapter_lock, flags);
1086                 crb_win_lock(adapter);
1087                 netxen_nic_pci_set_crbwindow_2M(adapter, &off);
1088                 writel(data, (void __iomem *)off);
1089                 crb_win_unlock(adapter);
1090                 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1091         } else
1092                 writel(data, (void __iomem *)off);
1093
1094
1095         return 0;
1096 }
1097
1098 u32
1099 netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
1100 {
1101         unsigned long flags = 0;
1102         int rv;
1103         u32 data;
1104
1105         rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, 4);
1106
1107         if (rv == -1) {
1108                 printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
1109                                 __func__, off);
1110                 dump_stack();
1111                 return -1;
1112         }
1113
1114         if (rv == 1) {
1115                 write_lock_irqsave(&adapter->adapter_lock, flags);
1116                 crb_win_lock(adapter);
1117                 netxen_nic_pci_set_crbwindow_2M(adapter, &off);
1118                 data = readl((void __iomem *)off);
1119                 crb_win_unlock(adapter);
1120                 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1121         } else
1122                 data = readl((void __iomem *)off);
1123
1124         return data;
1125 }
1126
1127 /*
1128  * check memory access boundary.
1129  * used by test agent. support ddr access only for now
1130  */
1131 static unsigned long
1132 netxen_nic_pci_mem_bound_check(struct netxen_adapter *adapter,
1133                 unsigned long long addr, int size)
1134 {
1135         if (!ADDR_IN_RANGE(addr,
1136                         NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) ||
1137                 !ADDR_IN_RANGE(addr+size-1,
1138                         NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) ||
1139                 ((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
1140                 return 0;
1141         }
1142
1143         return 1;
1144 }
1145
1146 static int netxen_pci_set_window_warning_count;
1147
1148 unsigned long
1149 netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
1150                 unsigned long long addr)
1151 {
1152         void __iomem *offset;
1153         int window;
1154         unsigned long long      qdr_max;
1155         uint8_t func = adapter->ahw.pci_func;
1156
1157         if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1158                 qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
1159         } else {
1160                 qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
1161         }
1162
1163         if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1164                 /* DDR network side */
1165                 addr -= NETXEN_ADDR_DDR_NET;
1166                 window = (addr >> 25) & 0x3ff;
1167                 if (adapter->ahw.ddr_mn_window != window) {
1168                         adapter->ahw.ddr_mn_window = window;
1169                         offset = PCI_OFFSET_SECOND_RANGE(adapter,
1170                                 NETXEN_PCIX_PH_REG(PCIE_MN_WINDOW_REG(func)));
1171                         writel(window, offset);
1172                         /* MUST make sure window is set before we forge on... */
1173                         readl(offset);
1174                 }
1175                 addr -= (window * NETXEN_WINDOW_ONE);
1176                 addr += NETXEN_PCI_DDR_NET;
1177         } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
1178                 addr -= NETXEN_ADDR_OCM0;
1179                 addr += NETXEN_PCI_OCM0;
1180         } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
1181                 addr -= NETXEN_ADDR_OCM1;
1182                 addr += NETXEN_PCI_OCM1;
1183         } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
1184                 /* QDR network side */
1185                 addr -= NETXEN_ADDR_QDR_NET;
1186                 window = (addr >> 22) & 0x3f;
1187                 if (adapter->ahw.qdr_sn_window != window) {
1188                         adapter->ahw.qdr_sn_window = window;
1189                         offset = PCI_OFFSET_SECOND_RANGE(adapter,
1190                                 NETXEN_PCIX_PH_REG(PCIE_SN_WINDOW_REG(func)));
1191                         writel((window << 22), offset);
1192                         /* MUST make sure window is set before we forge on... */
1193                         readl(offset);
1194                 }
1195                 addr -= (window * 0x400000);
1196                 addr += NETXEN_PCI_QDR_NET;
1197         } else {
1198                 /*
1199                  * peg gdb frequently accesses memory that doesn't exist,
1200                  * this limits the chit chat so debugging isn't slowed down.
1201                  */
1202                 if ((netxen_pci_set_window_warning_count++ < 8)
1203                     || (netxen_pci_set_window_warning_count % 64 == 0))
1204                         printk("%s: Warning:netxen_nic_pci_set_window()"
1205                                " Unknown address range!\n",
1206                                netxen_nic_driver_name);
1207                 addr = -1UL;
1208         }
1209         return addr;
1210 }
1211
1212 /*
1213  * Note : only 32-bit writes!
1214  */
1215 int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter,
1216                 u64 off, u32 data)
1217 {
1218         writel(data, (void __iomem *)(PCI_OFFSET_SECOND_RANGE(adapter, off)));
1219         return 0;
1220 }
1221
1222 u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off)
1223 {
1224         return readl((void __iomem *)(pci_base_offset(adapter, off)));
1225 }
1226
1227 unsigned long
1228 netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
1229                 unsigned long long addr)
1230 {
1231         int window;
1232         u32 win_read;
1233
1234         if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1235                 /* DDR network side */
1236                 window = MN_WIN(addr);
1237                 adapter->ahw.ddr_mn_window = window;
1238                 NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
1239                                 window);
1240                 win_read = NXRD32(adapter,
1241                                 adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
1242                 if ((win_read << 17) != window) {
1243                         printk(KERN_INFO "Written MNwin (0x%x) != "
1244                                 "Read MNwin (0x%x)\n", window, win_read);
1245                 }
1246                 addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_DDR_NET;
1247         } else if (ADDR_IN_RANGE(addr,
1248                                 NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
1249                 if ((addr & 0x00ff800) == 0xff800) {
1250                         printk("%s: QM access not handled.\n", __func__);
1251                         addr = -1UL;
1252                 }
1253
1254                 window = OCM_WIN(addr);
1255                 adapter->ahw.ddr_mn_window = window;
1256                 NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
1257                                 window);
1258                 win_read = NXRD32(adapter,
1259                                 adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
1260                 if ((win_read >> 7) != window) {
1261                         printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
1262                                         "Read OCMwin (0x%x)\n",
1263                                         __func__, window, win_read);
1264                 }
1265                 addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_OCM0_2M;
1266
1267         } else if (ADDR_IN_RANGE(addr,
1268                         NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) {
1269                 /* QDR network side */
1270                 window = MS_WIN(addr);
1271                 adapter->ahw.qdr_sn_window = window;
1272                 NXWR32(adapter, adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
1273                                 window);
1274                 win_read = NXRD32(adapter,
1275                                 adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE);
1276                 if (win_read != window) {
1277                         printk(KERN_INFO "%s: Written MSwin (0x%x) != "
1278                                         "Read MSwin (0x%x)\n",
1279                                         __func__, window, win_read);
1280                 }
1281                 addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_QDR_NET;
1282
1283         } else {
1284                 /*
1285                  * peg gdb frequently accesses memory that doesn't exist,
1286                  * this limits the chit chat so debugging isn't slowed down.
1287                  */
1288                 if ((netxen_pci_set_window_warning_count++ < 8)
1289                         || (netxen_pci_set_window_warning_count%64 == 0)) {
1290                         printk("%s: Warning:%s Unknown address range!\n",
1291                                         __func__, netxen_nic_driver_name);
1292 }
1293                 addr = -1UL;
1294         }
1295         return addr;
1296 }
1297
1298 static int netxen_nic_pci_is_same_window(struct netxen_adapter *adapter,
1299                                       unsigned long long addr)
1300 {
1301         int window;
1302         unsigned long long qdr_max;
1303
1304         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
1305                 qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
1306         else
1307                 qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
1308
1309         if (ADDR_IN_RANGE(addr,
1310                         NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1311                 /* DDR network side */
1312                 BUG();  /* MN access can not come here */
1313         } else if (ADDR_IN_RANGE(addr,
1314                         NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
1315                 return 1;
1316         } else if (ADDR_IN_RANGE(addr,
1317                                 NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
1318                 return 1;
1319         } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
1320                 /* QDR network side */
1321                 window = ((addr - NETXEN_ADDR_QDR_NET) >> 22) & 0x3f;
1322                 if (adapter->ahw.qdr_sn_window == window)
1323                         return 1;
1324         }
1325
1326         return 0;
1327 }
1328
1329 static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
1330                         u64 off, void *data, int size)
1331 {
1332         unsigned long flags;
1333         void __iomem *addr, *mem_ptr = NULL;
1334         int ret = 0;
1335         u64 start;
1336         unsigned long mem_base;
1337         unsigned long mem_page;
1338
1339         write_lock_irqsave(&adapter->adapter_lock, flags);
1340
1341         /*
1342          * If attempting to access unknown address or straddle hw windows,
1343          * do not access.
1344          */
1345         start = adapter->pci_set_window(adapter, off);
1346         if ((start == -1UL) ||
1347                 (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
1348                 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1349                 printk(KERN_ERR "%s out of bound pci memory access. "
1350                         "offset is 0x%llx\n", netxen_nic_driver_name,
1351                         (unsigned long long)off);
1352                 return -1;
1353         }
1354
1355         addr = pci_base_offset(adapter, start);
1356         if (!addr) {
1357                 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1358                 mem_base = pci_resource_start(adapter->pdev, 0);
1359                 mem_page = start & PAGE_MASK;
1360                 /* Map two pages whenever user tries to access addresses in two
1361                 consecutive pages.
1362                 */
1363                 if (mem_page != ((start + size - 1) & PAGE_MASK))
1364                         mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
1365                 else
1366                         mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
1367                 if (mem_ptr == NULL) {
1368                         *(uint8_t  *)data = 0;
1369                         return -1;
1370                 }
1371                 addr = mem_ptr;
1372                 addr += start & (PAGE_SIZE - 1);
1373                 write_lock_irqsave(&adapter->adapter_lock, flags);
1374         }
1375
1376         switch (size) {
1377         case 1:
1378                 *(uint8_t  *)data = readb(addr);
1379                 break;
1380         case 2:
1381                 *(uint16_t *)data = readw(addr);
1382                 break;
1383         case 4:
1384                 *(uint32_t *)data = readl(addr);
1385                 break;
1386         case 8:
1387                 *(uint64_t *)data = readq(addr);
1388                 break;
1389         default:
1390                 ret = -1;
1391                 break;
1392         }
1393         write_unlock_irqrestore(&adapter->adapter_lock, flags);
1394
1395         if (mem_ptr)
1396                 iounmap(mem_ptr);
1397         return ret;
1398 }
1399
1400 static int
1401 netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
1402                 void *data, int size)
1403 {
1404         unsigned long flags;
1405         void __iomem *addr, *mem_ptr = NULL;
1406         int ret = 0;
1407         u64 start;
1408         unsigned long mem_base;
1409         unsigned long mem_page;
1410
1411         write_lock_irqsave(&adapter->adapter_lock, flags);
1412
1413         /*
1414          * If attempting to access unknown address or straddle hw windows,
1415          * do not access.
1416          */
1417         start = adapter->pci_set_window(adapter, off);
1418         if ((start == -1UL) ||
1419                 (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
1420                 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1421                 printk(KERN_ERR "%s out of bound pci memory access. "
1422                         "offset is 0x%llx\n", netxen_nic_driver_name,
1423                         (unsigned long long)off);
1424                 return -1;
1425         }
1426
1427         addr = pci_base_offset(adapter, start);
1428         if (!addr) {
1429                 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1430                 mem_base = pci_resource_start(adapter->pdev, 0);
1431                 mem_page = start & PAGE_MASK;
1432                 /* Map two pages whenever user tries to access addresses in two
1433                  * consecutive pages.
1434                  */
1435                 if (mem_page != ((start + size - 1) & PAGE_MASK))
1436                         mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2);
1437                 else
1438                         mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
1439                 if (mem_ptr == NULL)
1440                         return -1;
1441                 addr = mem_ptr;
1442                 addr += start & (PAGE_SIZE - 1);
1443                 write_lock_irqsave(&adapter->adapter_lock, flags);
1444         }
1445
1446         switch (size) {
1447         case 1:
1448                 writeb(*(uint8_t *)data, addr);
1449                 break;
1450         case 2:
1451                 writew(*(uint16_t *)data, addr);
1452                 break;
1453         case 4:
1454                 writel(*(uint32_t *)data, addr);
1455                 break;
1456         case 8:
1457                 writeq(*(uint64_t *)data, addr);
1458                 break;
1459         default:
1460                 ret = -1;
1461                 break;
1462         }
1463         write_unlock_irqrestore(&adapter->adapter_lock, flags);
1464         if (mem_ptr)
1465                 iounmap(mem_ptr);
1466         return ret;
1467 }
1468
1469 #define MAX_CTL_CHECK   1000
1470
1471 int
1472 netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
1473                 u64 off, void *data, int size)
1474 {
1475         unsigned long   flags;
1476         int          i, j, ret = 0, loop, sz[2], off0;
1477         uint32_t      temp;
1478         uint64_t      off8, tmpw, word[2] = {0, 0};
1479         void __iomem *mem_crb;
1480
1481         /*
1482          * If not MN, go check for MS or invalid.
1483          */
1484         if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
1485                 return netxen_nic_pci_mem_write_direct(adapter,
1486                                 off, data, size);
1487
1488         off8 = off & 0xfffffff8;
1489         off0 = off & 0x7;
1490         sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1491         sz[1] = size - sz[0];
1492         loop = ((off0 + size - 1) >> 3) + 1;
1493         mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
1494
1495         if ((size != 8) || (off0 != 0))  {
1496                 for (i = 0; i < loop; i++) {
1497                         if (adapter->pci_mem_read(adapter,
1498                                 off8 + (i << 3), &word[i], 8))
1499                                 return -1;
1500                 }
1501         }
1502
1503         switch (size) {
1504         case 1:
1505                 tmpw = *((uint8_t *)data);
1506                 break;
1507         case 2:
1508                 tmpw = *((uint16_t *)data);
1509                 break;
1510         case 4:
1511                 tmpw = *((uint32_t *)data);
1512                 break;
1513         case 8:
1514         default:
1515                 tmpw = *((uint64_t *)data);
1516                 break;
1517         }
1518         word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1519         word[0] |= tmpw << (off0 * 8);
1520
1521         if (loop == 2) {
1522                 word[1] &= ~(~0ULL << (sz[1] * 8));
1523                 word[1] |= tmpw >> (sz[0] * 8);
1524         }
1525
1526         write_lock_irqsave(&adapter->adapter_lock, flags);
1527         netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1528
1529         for (i = 0; i < loop; i++) {
1530                 writel((uint32_t)(off8 + (i << 3)),
1531                         (mem_crb+MIU_TEST_AGT_ADDR_LO));
1532                 writel(0,
1533                         (mem_crb+MIU_TEST_AGT_ADDR_HI));
1534                 writel(word[i] & 0xffffffff,
1535                         (mem_crb+MIU_TEST_AGT_WRDATA_LO));
1536                 writel((word[i] >> 32) & 0xffffffff,
1537                         (mem_crb+MIU_TEST_AGT_WRDATA_HI));
1538                 writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
1539                         (mem_crb+MIU_TEST_AGT_CTRL));
1540                 writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
1541                         (mem_crb+MIU_TEST_AGT_CTRL));
1542
1543                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1544                         temp = readl(
1545                              (mem_crb+MIU_TEST_AGT_CTRL));
1546                         if ((temp & MIU_TA_CTL_BUSY) == 0)
1547                                 break;
1548                 }
1549
1550                 if (j >= MAX_CTL_CHECK) {
1551                         if (printk_ratelimit())
1552                                 dev_err(&adapter->pdev->dev,
1553                                         "failed to write through agent\n");
1554                         ret = -1;
1555                         break;
1556                 }
1557         }
1558
1559         netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1560         write_unlock_irqrestore(&adapter->adapter_lock, flags);
1561         return ret;
1562 }
1563
1564 int
1565 netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
1566                 u64 off, void *data, int size)
1567 {
1568         unsigned long   flags;
1569         int          i, j = 0, k, start, end, loop, sz[2], off0[2];
1570         uint32_t      temp;
1571         uint64_t      off8, val, word[2] = {0, 0};
1572         void __iomem *mem_crb;
1573
1574
1575         /*
1576          * If not MN, go check for MS or invalid.
1577          */
1578         if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
1579                 return netxen_nic_pci_mem_read_direct(adapter, off, data, size);
1580
1581         off8 = off & 0xfffffff8;
1582         off0[0] = off & 0x7;
1583         off0[1] = 0;
1584         sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1585         sz[1] = size - sz[0];
1586         loop = ((off0[0] + size - 1) >> 3) + 1;
1587         mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
1588
1589         write_lock_irqsave(&adapter->adapter_lock, flags);
1590         netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1591
1592         for (i = 0; i < loop; i++) {
1593                 writel((uint32_t)(off8 + (i << 3)),
1594                         (mem_crb+MIU_TEST_AGT_ADDR_LO));
1595                 writel(0,
1596                         (mem_crb+MIU_TEST_AGT_ADDR_HI));
1597                 writel(MIU_TA_CTL_ENABLE,
1598                         (mem_crb+MIU_TEST_AGT_CTRL));
1599                 writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
1600                         (mem_crb+MIU_TEST_AGT_CTRL));
1601
1602                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1603                         temp = readl(
1604                               (mem_crb+MIU_TEST_AGT_CTRL));
1605                         if ((temp & MIU_TA_CTL_BUSY) == 0)
1606                                 break;
1607                 }
1608
1609                 if (j >= MAX_CTL_CHECK) {
1610                         if (printk_ratelimit())
1611                                 dev_err(&adapter->pdev->dev,
1612                                         "failed to read through agent\n");
1613                         break;
1614                 }
1615
1616                 start = off0[i] >> 2;
1617                 end   = (off0[i] + sz[i] - 1) >> 2;
1618                 for (k = start; k <= end; k++) {
1619                         word[i] |= ((uint64_t) readl(
1620                                     (mem_crb +
1621                                     MIU_TEST_AGT_RDDATA(k))) << (32*k));
1622                 }
1623         }
1624
1625         netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1626         write_unlock_irqrestore(&adapter->adapter_lock, flags);
1627
1628         if (j >= MAX_CTL_CHECK)
1629                 return -1;
1630
1631         if (sz[0] == 8) {
1632                 val = word[0];
1633         } else {
1634                 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1635                         ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1636         }
1637
1638         switch (size) {
1639         case 1:
1640                 *(uint8_t  *)data = val;
1641                 break;
1642         case 2:
1643                 *(uint16_t *)data = val;
1644                 break;
1645         case 4:
1646                 *(uint32_t *)data = val;
1647                 break;
1648         case 8:
1649                 *(uint64_t *)data = val;
1650                 break;
1651         }
1652         return 0;
1653 }
1654
1655 int
1656 netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
1657                 u64 off, void *data, int size)
1658 {
1659         int i, j, ret = 0, loop, sz[2], off0;
1660         uint32_t temp;
1661         uint64_t off8, mem_crb, tmpw, word[2] = {0, 0};
1662
1663         /*
1664          * If not MN, go check for MS or invalid.
1665          */
1666         if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3)
1667                 mem_crb = NETXEN_CRB_QDR_NET;
1668         else {
1669                 mem_crb = NETXEN_CRB_DDR_NET;
1670                 if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
1671                         return netxen_nic_pci_mem_write_direct(adapter,
1672                                         off, data, size);
1673         }
1674
1675         off8 = off & 0xfffffff8;
1676         off0 = off & 0x7;
1677         sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1678         sz[1] = size - sz[0];
1679         loop = ((off0 + size - 1) >> 3) + 1;
1680
1681         if ((size != 8) || (off0 != 0)) {
1682                 for (i = 0; i < loop; i++) {
1683                         if (adapter->pci_mem_read(adapter, off8 + (i << 3),
1684                                                 &word[i], 8))
1685                                 return -1;
1686                 }
1687         }
1688
1689         switch (size) {
1690         case 1:
1691                 tmpw = *((uint8_t *)data);
1692                 break;
1693         case 2:
1694                 tmpw = *((uint16_t *)data);
1695                 break;
1696         case 4:
1697                 tmpw = *((uint32_t *)data);
1698                 break;
1699         case 8:
1700         default:
1701                 tmpw = *((uint64_t *)data);
1702         break;
1703         }
1704
1705         word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1706         word[0] |= tmpw << (off0 * 8);
1707
1708         if (loop == 2) {
1709                 word[1] &= ~(~0ULL << (sz[1] * 8));
1710                 word[1] |= tmpw >> (sz[0] * 8);
1711         }
1712
1713         /*
1714          * don't lock here - write_wx gets the lock if each time
1715          * write_lock_irqsave(&adapter->adapter_lock, flags);
1716          * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1717          */
1718
1719         for (i = 0; i < loop; i++) {
1720                 temp = off8 + (i << 3);
1721                 NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
1722                 temp = 0;
1723                 NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
1724                 temp = word[i] & 0xffffffff;
1725                 NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
1726                 temp = (word[i] >> 32) & 0xffffffff;
1727                 NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
1728                 temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
1729                 NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
1730                 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
1731                 NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
1732
1733                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1734                         temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
1735                         if ((temp & MIU_TA_CTL_BUSY) == 0)
1736                                 break;
1737                 }
1738
1739                 if (j >= MAX_CTL_CHECK) {
1740                         if (printk_ratelimit())
1741                                 dev_err(&adapter->pdev->dev,
1742                                         "failed to write through agent\n");
1743                         ret = -1;
1744                         break;
1745                 }
1746         }
1747
1748         /*
1749          * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1750          * write_unlock_irqrestore(&adapter->adapter_lock, flags);
1751          */
1752         return ret;
1753 }
1754
1755 int
1756 netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
1757                 u64 off, void *data, int size)
1758 {
1759         int i, j = 0, k, start, end, loop, sz[2], off0[2];
1760         uint32_t      temp;
1761         uint64_t      off8, val, mem_crb, word[2] = {0, 0};
1762
1763         /*
1764          * If not MN, go check for MS or invalid.
1765          */
1766
1767         if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3)
1768                 mem_crb = NETXEN_CRB_QDR_NET;
1769         else {
1770                 mem_crb = NETXEN_CRB_DDR_NET;
1771                 if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
1772                         return netxen_nic_pci_mem_read_direct(adapter,
1773                                         off, data, size);
1774         }
1775
1776         off8 = off & 0xfffffff8;
1777         off0[0] = off & 0x7;
1778         off0[1] = 0;
1779         sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1780         sz[1] = size - sz[0];
1781         loop = ((off0[0] + size - 1) >> 3) + 1;
1782
1783         /*
1784          * don't lock here - write_wx gets the lock if each time
1785          * write_lock_irqsave(&adapter->adapter_lock, flags);
1786          * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1787          */
1788
1789         for (i = 0; i < loop; i++) {
1790                 temp = off8 + (i << 3);
1791                 NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
1792                 temp = 0;
1793                 NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
1794                 temp = MIU_TA_CTL_ENABLE;
1795                 NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
1796                 temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
1797                 NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
1798
1799                 for (j = 0; j < MAX_CTL_CHECK; j++) {
1800                         temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
1801                         if ((temp & MIU_TA_CTL_BUSY) == 0)
1802                                 break;
1803                 }
1804
1805                 if (j >= MAX_CTL_CHECK) {
1806                         if (printk_ratelimit())
1807                                 dev_err(&adapter->pdev->dev,
1808                                         "failed to read through agent\n");
1809                         break;
1810                 }
1811
1812                 start = off0[i] >> 2;
1813                 end   = (off0[i] + sz[i] - 1) >> 2;
1814                 for (k = start; k <= end; k++) {
1815                         temp = NXRD32(adapter,
1816                                 mem_crb + MIU_TEST_AGT_RDDATA(k));
1817                         word[i] |= ((uint64_t)temp << (32 * k));
1818                 }
1819         }
1820
1821         /*
1822          * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1823          * write_unlock_irqrestore(&adapter->adapter_lock, flags);
1824          */
1825
1826         if (j >= MAX_CTL_CHECK)
1827                 return -1;
1828
1829         if (sz[0] == 8) {
1830                 val = word[0];
1831         } else {
1832                 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1833                 ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1834         }
1835
1836         switch (size) {
1837         case 1:
1838                 *(uint8_t  *)data = val;
1839                 break;
1840         case 2:
1841                 *(uint16_t *)data = val;
1842                 break;
1843         case 4:
1844                 *(uint32_t *)data = val;
1845                 break;
1846         case 8:
1847                 *(uint64_t *)data = val;
1848                 break;
1849         }
1850         return 0;
1851 }
1852
1853 /*
1854  * Note : only 32-bit writes!
1855  */
1856 int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
1857                 u64 off, u32 data)
1858 {
1859         NXWR32(adapter, off, data);
1860
1861         return 0;
1862 }
1863
1864 u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off)
1865 {
1866         return NXRD32(adapter, off);
1867 }
1868
1869 int netxen_nic_get_board_info(struct netxen_adapter *adapter)
1870 {
1871         int offset, board_type, magic, header_version;
1872         struct pci_dev *pdev = adapter->pdev;
1873
1874         offset = NETXEN_BRDCFG_START +
1875                 offsetof(struct netxen_board_info, magic);
1876         if (netxen_rom_fast_read(adapter, offset, &magic))
1877                 return -EIO;
1878
1879         offset = NETXEN_BRDCFG_START +
1880                 offsetof(struct netxen_board_info, header_version);
1881         if (netxen_rom_fast_read(adapter, offset, &header_version))
1882                 return -EIO;
1883
1884         if (magic != NETXEN_BDINFO_MAGIC ||
1885                         header_version != NETXEN_BDINFO_VERSION) {
1886                 dev_err(&pdev->dev,
1887                         "invalid board config, magic=%08x, version=%08x\n",
1888                         magic, header_version);
1889                 return -EIO;
1890         }
1891
1892         offset = NETXEN_BRDCFG_START +
1893                 offsetof(struct netxen_board_info, board_type);
1894         if (netxen_rom_fast_read(adapter, offset, &board_type))
1895                 return -EIO;
1896
1897         adapter->ahw.board_type = board_type;
1898
1899         if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
1900                 u32 gpio = NXRD32(adapter, NETXEN_ROMUSB_GLB_PAD_GPIO_I);
1901                 if ((gpio & 0x8000) == 0)
1902                         board_type = NETXEN_BRDTYPE_P3_10G_TP;
1903         }
1904
1905         switch (board_type) {
1906         case NETXEN_BRDTYPE_P2_SB35_4G:
1907                 adapter->ahw.port_type = NETXEN_NIC_GBE;
1908                 break;
1909         case NETXEN_BRDTYPE_P2_SB31_10G:
1910         case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
1911         case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
1912         case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
1913         case NETXEN_BRDTYPE_P3_HMEZ:
1914         case NETXEN_BRDTYPE_P3_XG_LOM:
1915         case NETXEN_BRDTYPE_P3_10G_CX4:
1916         case NETXEN_BRDTYPE_P3_10G_CX4_LP:
1917         case NETXEN_BRDTYPE_P3_IMEZ:
1918         case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
1919         case NETXEN_BRDTYPE_P3_10G_SFP_CT:
1920         case NETXEN_BRDTYPE_P3_10G_SFP_QT:
1921         case NETXEN_BRDTYPE_P3_10G_XFP:
1922         case NETXEN_BRDTYPE_P3_10000_BASE_T:
1923                 adapter->ahw.port_type = NETXEN_NIC_XGBE;
1924                 break;
1925         case NETXEN_BRDTYPE_P1_BD:
1926         case NETXEN_BRDTYPE_P1_SB:
1927         case NETXEN_BRDTYPE_P1_SMAX:
1928         case NETXEN_BRDTYPE_P1_SOCK:
1929         case NETXEN_BRDTYPE_P3_REF_QG:
1930         case NETXEN_BRDTYPE_P3_4_GB:
1931         case NETXEN_BRDTYPE_P3_4_GB_MM:
1932                 adapter->ahw.port_type = NETXEN_NIC_GBE;
1933                 break;
1934         case NETXEN_BRDTYPE_P3_10G_TP:
1935                 adapter->ahw.port_type = (adapter->portnum < 2) ?
1936                         NETXEN_NIC_XGBE : NETXEN_NIC_GBE;
1937                 break;
1938         default:
1939                 dev_err(&pdev->dev, "unknown board type %x\n", board_type);
1940                 adapter->ahw.port_type = NETXEN_NIC_XGBE;
1941                 break;
1942         }
1943
1944         return 0;
1945 }
1946
1947 /* NIU access sections */
1948
1949 int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
1950 {
1951         new_mtu += MTU_FUDGE_FACTOR;
1952         NXWR32(adapter, NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
1953                 new_mtu);
1954         return 0;
1955 }
1956
1957 int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
1958 {
1959         new_mtu += MTU_FUDGE_FACTOR;
1960         if (adapter->physical_port == 0)
1961                 NXWR32(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
1962         else
1963                 NXWR32(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu);
1964         return 0;
1965 }
1966
1967 void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
1968 {
1969         __u32 status;
1970         __u32 autoneg;
1971         __u32 port_mode;
1972
1973         if (!netif_carrier_ok(adapter->netdev)) {
1974                 adapter->link_speed   = 0;
1975                 adapter->link_duplex  = -1;
1976                 adapter->link_autoneg = AUTONEG_ENABLE;
1977                 return;
1978         }
1979
1980         if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
1981                 port_mode = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
1982                 if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
1983                         adapter->link_speed   = SPEED_1000;
1984                         adapter->link_duplex  = DUPLEX_FULL;
1985                         adapter->link_autoneg = AUTONEG_DISABLE;
1986                         return;
1987                 }
1988
1989                 if (adapter->phy_read
1990                     && adapter->phy_read(adapter,
1991                              NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
1992                              &status) == 0) {
1993                         if (netxen_get_phy_link(status)) {
1994                                 switch (netxen_get_phy_speed(status)) {
1995                                 case 0:
1996                                         adapter->link_speed = SPEED_10;
1997                                         break;
1998                                 case 1:
1999                                         adapter->link_speed = SPEED_100;
2000                                         break;
2001                                 case 2:
2002                                         adapter->link_speed = SPEED_1000;
2003                                         break;
2004                                 default:
2005                                         adapter->link_speed = 0;
2006                                         break;
2007                                 }
2008                                 switch (netxen_get_phy_duplex(status)) {
2009                                 case 0:
2010                                         adapter->link_duplex = DUPLEX_HALF;
2011                                         break;
2012                                 case 1:
2013                                         adapter->link_duplex = DUPLEX_FULL;
2014                                         break;
2015                                 default:
2016                                         adapter->link_duplex = -1;
2017                                         break;
2018                                 }
2019                                 if (adapter->phy_read
2020                                     && adapter->phy_read(adapter,
2021                                              NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
2022                                              &autoneg) != 0)
2023                                         adapter->link_autoneg = autoneg;
2024                         } else
2025                                 goto link_down;
2026                 } else {
2027                       link_down:
2028                         adapter->link_speed = 0;
2029                         adapter->link_duplex = -1;
2030                 }
2031         }
2032 }
2033
2034 void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
2035 {
2036         u32 fw_major, fw_minor, fw_build;
2037         char brd_name[NETXEN_MAX_SHORT_NAME];
2038         char serial_num[32];
2039         int i, addr, val;
2040         int *ptr32;
2041         struct pci_dev *pdev = adapter->pdev;
2042
2043         adapter->driver_mismatch = 0;
2044
2045         ptr32 = (int *)&serial_num;
2046         addr = NETXEN_USER_START +
2047                offsetof(struct netxen_new_user_info, serial_num);
2048         for (i = 0; i < 8; i++) {
2049                 if (netxen_rom_fast_read(adapter, addr, &val) == -1) {
2050                         dev_err(&pdev->dev, "error reading board info\n");
2051                         adapter->driver_mismatch = 1;
2052                         return;
2053                 }
2054                 ptr32[i] = cpu_to_le32(val);
2055                 addr += sizeof(u32);
2056         }
2057
2058         fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
2059         fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
2060         fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
2061
2062         adapter->fw_major = fw_major;
2063         adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
2064
2065         if (adapter->portnum == 0) {
2066                 get_brd_name_by_type(adapter->ahw.board_type, brd_name);
2067
2068                 printk(KERN_INFO "NetXen %s Board S/N %s  Chip rev 0x%x\n",
2069                                 brd_name, serial_num, adapter->ahw.revision_id);
2070         }
2071
2072         if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
2073                 adapter->driver_mismatch = 1;
2074                 dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
2075                                 fw_major, fw_minor, fw_build);
2076                 return;
2077         }
2078
2079         dev_info(&pdev->dev, "firmware version %d.%d.%d\n",
2080                         fw_major, fw_minor, fw_build);
2081
2082         if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
2083                 i = NXRD32(adapter, NETXEN_MIU_MN_CONTROL);
2084                 adapter->ahw.cut_through = (i & 0x4) ? 1 : 0;
2085                 dev_info(&pdev->dev, "firmware running in %s mode\n",
2086                 adapter->ahw.cut_through ? "cut-through" : "legacy");
2087         }
2088 }
2089
2090 int
2091 netxen_nic_wol_supported(struct netxen_adapter *adapter)
2092 {
2093         u32 wol_cfg;
2094
2095         if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
2096                 return 0;
2097
2098         wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
2099         if (wol_cfg & (1UL << adapter->portnum)) {
2100                 wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
2101                 if (wol_cfg & (1 << adapter->portnum))
2102                         return 1;
2103         }
2104
2105         return 0;
2106 }