1eef4f27bSRobert Mustacchi /*
2eef4f27bSRobert Mustacchi * Copyright 2014-2017 Cavium, Inc.
3eef4f27bSRobert Mustacchi * The contents of this file are subject to the terms of the Common Development
4eef4f27bSRobert Mustacchi * and Distribution License, v.1, (the "License").
5eef4f27bSRobert Mustacchi *
6eef4f27bSRobert Mustacchi * You may not use this file except in compliance with the License.
7eef4f27bSRobert Mustacchi *
8eef4f27bSRobert Mustacchi * You can obtain a copy of the License at available
9eef4f27bSRobert Mustacchi * at http://opensource.org/licenses/CDDL-1.0
10eef4f27bSRobert Mustacchi *
11eef4f27bSRobert Mustacchi * See the License for the specific language governing permissions and
12eef4f27bSRobert Mustacchi * limitations under the License.
13eef4f27bSRobert Mustacchi */
14eef4f27bSRobert Mustacchi
15eef4f27bSRobert Mustacchi #include "lm5706.h"
16eef4f27bSRobert Mustacchi
17eef4f27bSRobert Mustacchi
18eef4f27bSRobert Mustacchi
19eef4f27bSRobert Mustacchi /*******************************************************************************
20eef4f27bSRobert Mustacchi * Description:
21*55fea89dSDan Cross *
22eef4f27bSRobert Mustacchi * Return:
23eef4f27bSRobert Mustacchi ******************************************************************************/
24eef4f27bSRobert Mustacchi lm_status_t
lm_set_mac_addr(lm_device_t * pdev,u32_t addr_idx,u8_t * mac_addr)25eef4f27bSRobert Mustacchi lm_set_mac_addr(
26eef4f27bSRobert Mustacchi lm_device_t *pdev,
27eef4f27bSRobert Mustacchi u32_t addr_idx,
28*55fea89dSDan Cross u8_t *mac_addr)
29eef4f27bSRobert Mustacchi {
30eef4f27bSRobert Mustacchi u32_t val;
31eef4f27bSRobert Mustacchi
32eef4f27bSRobert Mustacchi if(addr_idx >= 16)
33eef4f27bSRobert Mustacchi {
34eef4f27bSRobert Mustacchi DbgBreakMsg("Invalid mac address index.\n");
35eef4f27bSRobert Mustacchi
36eef4f27bSRobert Mustacchi return LM_STATUS_FAILURE;
37eef4f27bSRobert Mustacchi }
38eef4f27bSRobert Mustacchi
39eef4f27bSRobert Mustacchi val = (mac_addr[0]<<8) | mac_addr[1];
40eef4f27bSRobert Mustacchi REG_WR(pdev, emac.emac_mac_match[addr_idx*2], val);
41eef4f27bSRobert Mustacchi
42*55fea89dSDan Cross val = (mac_addr[2]<<24) | (mac_addr[3]<<16) |
43eef4f27bSRobert Mustacchi (mac_addr[4]<<8) | mac_addr[5];
44eef4f27bSRobert Mustacchi REG_WR(pdev, emac.emac_mac_match[addr_idx*2+1], val);
45eef4f27bSRobert Mustacchi
46eef4f27bSRobert Mustacchi return LM_STATUS_SUCCESS;
47eef4f27bSRobert Mustacchi } /* lm_set_mac_addr */
48eef4f27bSRobert Mustacchi
49eef4f27bSRobert Mustacchi
50eef4f27bSRobert Mustacchi
51eef4f27bSRobert Mustacchi /*******************************************************************************
52eef4f27bSRobert Mustacchi * Description:
53eef4f27bSRobert Mustacchi *
54eef4f27bSRobert Mustacchi * Return:
55eef4f27bSRobert Mustacchi * None.
56eef4f27bSRobert Mustacchi *
57eef4f27bSRobert Mustacchi * Note:
58*55fea89dSDan Cross * The caller is responsible for synchronizing calls to lm_reg_rd_ind and
59eef4f27bSRobert Mustacchi * lm_reg_wr_ind.
60eef4f27bSRobert Mustacchi ******************************************************************************/
61eef4f27bSRobert Mustacchi void
lm_reg_rd_ind(lm_device_t * pdev,u32_t offset,u32_t * ret)62eef4f27bSRobert Mustacchi lm_reg_rd_ind(
63eef4f27bSRobert Mustacchi lm_device_t *pdev,
64eef4f27bSRobert Mustacchi u32_t offset,
65eef4f27bSRobert Mustacchi u32_t *ret)
66eef4f27bSRobert Mustacchi {
67eef4f27bSRobert Mustacchi /* DbgBreakIf(offset & 0x3); // this can occur for some shmem accesses */
68eef4f27bSRobert Mustacchi
69eef4f27bSRobert Mustacchi mm_acquire_ind_reg_lock(pdev);
70eef4f27bSRobert Mustacchi
71eef4f27bSRobert Mustacchi REG_WR(pdev, pci_config.pcicfg_reg_window_address, offset);
72eef4f27bSRobert Mustacchi REG_RD(pdev, pci_config.pcicfg_reg_window, ret);
73eef4f27bSRobert Mustacchi
74eef4f27bSRobert Mustacchi mm_release_ind_reg_lock(pdev);
75eef4f27bSRobert Mustacchi } /* lm_reg_rd_ind */
76eef4f27bSRobert Mustacchi
77eef4f27bSRobert Mustacchi
78eef4f27bSRobert Mustacchi
79eef4f27bSRobert Mustacchi /*******************************************************************************
80eef4f27bSRobert Mustacchi * Description:
81eef4f27bSRobert Mustacchi *
82eef4f27bSRobert Mustacchi * Return:
83eef4f27bSRobert Mustacchi * None.
84eef4f27bSRobert Mustacchi *
85eef4f27bSRobert Mustacchi * Note:
86*55fea89dSDan Cross * The caller is responsible for synchronizing calls to lm_reg_rd_ind and
87eef4f27bSRobert Mustacchi * lm_reg_wr_ind.
88eef4f27bSRobert Mustacchi ******************************************************************************/
89eef4f27bSRobert Mustacchi void
lm_reg_wr_ind(lm_device_t * pdev,u32_t offset,u32_t val)90eef4f27bSRobert Mustacchi lm_reg_wr_ind(
91eef4f27bSRobert Mustacchi lm_device_t *pdev,
92eef4f27bSRobert Mustacchi u32_t offset,
93eef4f27bSRobert Mustacchi u32_t val)
94eef4f27bSRobert Mustacchi {
95eef4f27bSRobert Mustacchi DbgBreakIf(offset & 0x3);
96eef4f27bSRobert Mustacchi
97eef4f27bSRobert Mustacchi mm_acquire_ind_reg_lock(pdev);
98eef4f27bSRobert Mustacchi
99eef4f27bSRobert Mustacchi REG_WR(pdev, pci_config.pcicfg_reg_window_address, offset);
100eef4f27bSRobert Mustacchi REG_WR(pdev, pci_config.pcicfg_reg_window, val);
101eef4f27bSRobert Mustacchi
102eef4f27bSRobert Mustacchi mm_release_ind_reg_lock(pdev);
103eef4f27bSRobert Mustacchi } /* lm_reg_wr_ind */
104eef4f27bSRobert Mustacchi
105eef4f27bSRobert Mustacchi
106eef4f27bSRobert Mustacchi
107eef4f27bSRobert Mustacchi /*******************************************************************************
108eef4f27bSRobert Mustacchi * Description:
109*55fea89dSDan Cross *
110eef4f27bSRobert Mustacchi * Return:
111eef4f27bSRobert Mustacchi ******************************************************************************/
112eef4f27bSRobert Mustacchi void
lm_ctx_wr(lm_device_t * pdev,u32_t cid_addr,u32_t offset,u32_t val)113eef4f27bSRobert Mustacchi lm_ctx_wr(
114eef4f27bSRobert Mustacchi lm_device_t *pdev,
115eef4f27bSRobert Mustacchi u32_t cid_addr,
116eef4f27bSRobert Mustacchi u32_t offset,
117eef4f27bSRobert Mustacchi u32_t val)
118eef4f27bSRobert Mustacchi {
119eef4f27bSRobert Mustacchi u32_t retry_cnt;
120eef4f27bSRobert Mustacchi u32_t idx;
121eef4f27bSRobert Mustacchi
122eef4f27bSRobert Mustacchi DbgBreakIf(cid_addr > MAX_CID_ADDR || offset & 0x3 || cid_addr & CTX_MASK);
123eef4f27bSRobert Mustacchi
124eef4f27bSRobert Mustacchi offset += cid_addr;
125eef4f27bSRobert Mustacchi
126eef4f27bSRobert Mustacchi if(CHIP_NUM(pdev) == CHIP_NUM_5709)
127eef4f27bSRobert Mustacchi {
128eef4f27bSRobert Mustacchi if (CHIP_REV(pdev) == CHIP_REV_IKOS)
129eef4f27bSRobert Mustacchi {
130eef4f27bSRobert Mustacchi retry_cnt = 2000;
131eef4f27bSRobert Mustacchi }
132eef4f27bSRobert Mustacchi else
133eef4f27bSRobert Mustacchi {
134eef4f27bSRobert Mustacchi retry_cnt = 250;
135eef4f27bSRobert Mustacchi }
136eef4f27bSRobert Mustacchi
137eef4f27bSRobert Mustacchi REG_WR(pdev, context.ctx_ctx_data, val);
138eef4f27bSRobert Mustacchi REG_WR(pdev, context.ctx_ctx_ctrl, offset | CTX_CTX_CTRL_WRITE_REQ);
139eef4f27bSRobert Mustacchi
140eef4f27bSRobert Mustacchi for(idx=0; idx < retry_cnt; idx++)
141eef4f27bSRobert Mustacchi {
142eef4f27bSRobert Mustacchi REG_RD(pdev, context.ctx_ctx_ctrl, &val);
143eef4f27bSRobert Mustacchi
144eef4f27bSRobert Mustacchi if((val & CTX_CTX_CTRL_WRITE_REQ) == 0)
145eef4f27bSRobert Mustacchi {
146eef4f27bSRobert Mustacchi break;
147eef4f27bSRobert Mustacchi }
148eef4f27bSRobert Mustacchi
149eef4f27bSRobert Mustacchi mm_wait(pdev, 10);
150eef4f27bSRobert Mustacchi }
151eef4f27bSRobert Mustacchi
152eef4f27bSRobert Mustacchi DbgBreakIf(idx == retry_cnt);
153eef4f27bSRobert Mustacchi }
154eef4f27bSRobert Mustacchi else
155eef4f27bSRobert Mustacchi {
156eef4f27bSRobert Mustacchi REG_WR(pdev, context.ctx_data_adr, offset);
157eef4f27bSRobert Mustacchi REG_WR(pdev, context.ctx_data, val);
158eef4f27bSRobert Mustacchi }
159eef4f27bSRobert Mustacchi } /* lm_ctx_wr */
160eef4f27bSRobert Mustacchi
161eef4f27bSRobert Mustacchi
162eef4f27bSRobert Mustacchi
163eef4f27bSRobert Mustacchi /*******************************************************************************
164eef4f27bSRobert Mustacchi * Description:
165*55fea89dSDan Cross *
166eef4f27bSRobert Mustacchi * Return:
167eef4f27bSRobert Mustacchi ******************************************************************************/
168eef4f27bSRobert Mustacchi u32_t
lm_ctx_rd(lm_device_t * pdev,u32_t cid_addr,u32_t offset)169eef4f27bSRobert Mustacchi lm_ctx_rd(
170eef4f27bSRobert Mustacchi lm_device_t *pdev,
171eef4f27bSRobert Mustacchi u32_t cid_addr,
172eef4f27bSRobert Mustacchi u32_t offset)
173eef4f27bSRobert Mustacchi {
174eef4f27bSRobert Mustacchi u32_t retry_cnt;
175eef4f27bSRobert Mustacchi u32_t val;
176eef4f27bSRobert Mustacchi u32_t idx;
177eef4f27bSRobert Mustacchi
178eef4f27bSRobert Mustacchi DbgBreakIf(cid_addr > MAX_CID_ADDR || offset & 0x3 || cid_addr & CTX_MASK);
179eef4f27bSRobert Mustacchi
180eef4f27bSRobert Mustacchi offset += cid_addr;
181eef4f27bSRobert Mustacchi
182eef4f27bSRobert Mustacchi if(CHIP_NUM(pdev) == CHIP_NUM_5709)
183eef4f27bSRobert Mustacchi {
184eef4f27bSRobert Mustacchi if(CHIP_REV(pdev) == CHIP_REV_IKOS)
185eef4f27bSRobert Mustacchi {
186eef4f27bSRobert Mustacchi retry_cnt = 1000;
187eef4f27bSRobert Mustacchi }
188eef4f27bSRobert Mustacchi else
189eef4f27bSRobert Mustacchi {
190eef4f27bSRobert Mustacchi retry_cnt = 25;
191eef4f27bSRobert Mustacchi }
192eef4f27bSRobert Mustacchi
193eef4f27bSRobert Mustacchi REG_WR(pdev, context.ctx_ctx_ctrl, offset | CTX_CTX_CTRL_READ_REQ);
194eef4f27bSRobert Mustacchi
195eef4f27bSRobert Mustacchi for(idx = 0; idx < retry_cnt; idx++)
196eef4f27bSRobert Mustacchi {
197eef4f27bSRobert Mustacchi REG_RD(pdev, context.ctx_ctx_ctrl, &val);
198eef4f27bSRobert Mustacchi
199eef4f27bSRobert Mustacchi if((val & CTX_CTX_CTRL_READ_REQ) == 0)
200eef4f27bSRobert Mustacchi {
201eef4f27bSRobert Mustacchi break;
202eef4f27bSRobert Mustacchi }
203eef4f27bSRobert Mustacchi
204eef4f27bSRobert Mustacchi mm_wait(pdev, 5);
205eef4f27bSRobert Mustacchi }
206eef4f27bSRobert Mustacchi
207eef4f27bSRobert Mustacchi DbgBreakIf(idx == retry_cnt);
208eef4f27bSRobert Mustacchi
209eef4f27bSRobert Mustacchi REG_RD(pdev, context.ctx_ctx_data, &val);
210eef4f27bSRobert Mustacchi }
211eef4f27bSRobert Mustacchi else
212eef4f27bSRobert Mustacchi {
213eef4f27bSRobert Mustacchi REG_WR(pdev, context.ctx_data_adr, offset);
214eef4f27bSRobert Mustacchi REG_RD(pdev, context.ctx_data, &val);
215eef4f27bSRobert Mustacchi }
216eef4f27bSRobert Mustacchi
217eef4f27bSRobert Mustacchi return val;
218eef4f27bSRobert Mustacchi } /* lm_ctx_rd */
219eef4f27bSRobert Mustacchi
220eef4f27bSRobert Mustacchi
221eef4f27bSRobert Mustacchi
222eef4f27bSRobert Mustacchi /*******************************************************************************
223eef4f27bSRobert Mustacchi * Description:
224eef4f27bSRobert Mustacchi *
225eef4f27bSRobert Mustacchi * Return:
226eef4f27bSRobert Mustacchi ******************************************************************************/
227eef4f27bSRobert Mustacchi void
lm_disable_int(lm_device_t * pdev)228eef4f27bSRobert Mustacchi lm_disable_int(
229eef4f27bSRobert Mustacchi lm_device_t *pdev)
230eef4f27bSRobert Mustacchi {
231eef4f27bSRobert Mustacchi u32_t sb_idx;
232eef4f27bSRobert Mustacchi u32_t val;
233eef4f27bSRobert Mustacchi
234eef4f27bSRobert Mustacchi switch(CHIP_NUM(pdev))
235eef4f27bSRobert Mustacchi {
236eef4f27bSRobert Mustacchi case CHIP_NUM_5706:
237eef4f27bSRobert Mustacchi case CHIP_NUM_5708:
238eef4f27bSRobert Mustacchi REG_RD(pdev, pci_config.pcicfg_int_ack_cmd, &val);
239eef4f27bSRobert Mustacchi val |= PCICFG_INT_ACK_CMD_MASK_INT;
240eef4f27bSRobert Mustacchi REG_WR(pdev, pci_config.pcicfg_int_ack_cmd, val);
241eef4f27bSRobert Mustacchi break;
242eef4f27bSRobert Mustacchi
243eef4f27bSRobert Mustacchi case CHIP_NUM_5709:
244eef4f27bSRobert Mustacchi for(sb_idx = 0; sb_idx < 9; sb_idx++)
245eef4f27bSRobert Mustacchi {
246eef4f27bSRobert Mustacchi val = PCICFG_INT_ACK_CMD_MASK_INT | (sb_idx << 24);
247eef4f27bSRobert Mustacchi REG_WR(pdev, pci_config.pcicfg_int_ack_cmd, val);
248eef4f27bSRobert Mustacchi }
249eef4f27bSRobert Mustacchi break;
250eef4f27bSRobert Mustacchi
251eef4f27bSRobert Mustacchi default:
252eef4f27bSRobert Mustacchi DbgBreakMsg("Unsupported chip.\n");
253eef4f27bSRobert Mustacchi break;
254eef4f27bSRobert Mustacchi }
255eef4f27bSRobert Mustacchi } /* lm_disable_int */
256eef4f27bSRobert Mustacchi
257eef4f27bSRobert Mustacchi
258eef4f27bSRobert Mustacchi
259eef4f27bSRobert Mustacchi /*******************************************************************************
260eef4f27bSRobert Mustacchi * Description:
261eef4f27bSRobert Mustacchi *
262eef4f27bSRobert Mustacchi * Return:
263eef4f27bSRobert Mustacchi ******************************************************************************/
264eef4f27bSRobert Mustacchi void
lm_enable_int(lm_device_t * pdev)265eef4f27bSRobert Mustacchi lm_enable_int(
266eef4f27bSRobert Mustacchi lm_device_t *pdev)
267eef4f27bSRobert Mustacchi {
268eef4f27bSRobert Mustacchi u32_t val;
269eef4f27bSRobert Mustacchi
270eef4f27bSRobert Mustacchi switch(CHIP_NUM(pdev))
271eef4f27bSRobert Mustacchi {
272eef4f27bSRobert Mustacchi case CHIP_NUM_5706:
273eef4f27bSRobert Mustacchi case CHIP_NUM_5708:
274eef4f27bSRobert Mustacchi REG_RD(pdev, pci_config.pcicfg_int_ack_cmd, &val);
275eef4f27bSRobert Mustacchi val &= ~PCICFG_INT_ACK_CMD_MASK_INT;
276eef4f27bSRobert Mustacchi REG_WR(pdev, pci_config.pcicfg_int_ack_cmd, val);
277eef4f27bSRobert Mustacchi break;
278eef4f27bSRobert Mustacchi
279eef4f27bSRobert Mustacchi case CHIP_NUM_5709:
280eef4f27bSRobert Mustacchi REG_RD(pdev, hc.hc_config, &val);
281eef4f27bSRobert Mustacchi val |= HC_CONFIG_UNMASK_ALL;
282eef4f27bSRobert Mustacchi REG_WR(pdev, hc.hc_config, val);
283eef4f27bSRobert Mustacchi break;
284eef4f27bSRobert Mustacchi
285eef4f27bSRobert Mustacchi default:
286eef4f27bSRobert Mustacchi DbgBreakMsg("Unsupported chip.\n");
287eef4f27bSRobert Mustacchi break;
288eef4f27bSRobert Mustacchi }
289eef4f27bSRobert Mustacchi } /* lm_enable_int */
290eef4f27bSRobert Mustacchi
291eef4f27bSRobert Mustacchi
292eef4f27bSRobert Mustacchi
293eef4f27bSRobert Mustacchi /*******************************************************************************
294eef4f27bSRobert Mustacchi * Description:
295eef4f27bSRobert Mustacchi *
296eef4f27bSRobert Mustacchi * Return:
297eef4f27bSRobert Mustacchi ******************************************************************************/
298eef4f27bSRobert Mustacchi void
lm_reg_rd_blk(lm_device_t * pdev,u32_t reg_offset,u32_t * buf_ptr,u32_t u32t_cnt)299eef4f27bSRobert Mustacchi lm_reg_rd_blk(
300eef4f27bSRobert Mustacchi lm_device_t *pdev,
301eef4f27bSRobert Mustacchi u32_t reg_offset,
302eef4f27bSRobert Mustacchi u32_t *buf_ptr,
303eef4f27bSRobert Mustacchi u32_t u32t_cnt)
304eef4f27bSRobert Mustacchi {
305eef4f27bSRobert Mustacchi u32_t grc_win_offset;
306eef4f27bSRobert Mustacchi u32_t grc_win_base;
307eef4f27bSRobert Mustacchi
308eef4f27bSRobert Mustacchi DbgBreakIf(reg_offset & 0x3);
309eef4f27bSRobert Mustacchi
310eef4f27bSRobert Mustacchi grc_win_offset = reg_offset & (GRC_WINDOW_SIZE - 1);
311eef4f27bSRobert Mustacchi grc_win_base = reg_offset & ~(GRC_WINDOW_SIZE - 1);
312eef4f27bSRobert Mustacchi
313eef4f27bSRobert Mustacchi REG_WR(pdev, pci.pci_grc_window_addr, grc_win_base);
314eef4f27bSRobert Mustacchi
315eef4f27bSRobert Mustacchi while(u32t_cnt)
316eef4f27bSRobert Mustacchi {
317eef4f27bSRobert Mustacchi if(grc_win_offset >= GRC_WINDOW_SIZE)
318eef4f27bSRobert Mustacchi {
319eef4f27bSRobert Mustacchi grc_win_offset = 0;
320eef4f27bSRobert Mustacchi grc_win_base += GRC_WINDOW_SIZE;
321eef4f27bSRobert Mustacchi
322eef4f27bSRobert Mustacchi REG_WR(pdev, pci.pci_grc_window_addr, grc_win_base);
323eef4f27bSRobert Mustacchi }
324eef4f27bSRobert Mustacchi
325eef4f27bSRobert Mustacchi REG_RD_OFFSET(pdev, GRC_WINDOW_BASE + grc_win_offset, buf_ptr);
326eef4f27bSRobert Mustacchi
327eef4f27bSRobert Mustacchi buf_ptr++;
328eef4f27bSRobert Mustacchi u32t_cnt--;
329eef4f27bSRobert Mustacchi grc_win_offset += 4;
330eef4f27bSRobert Mustacchi }
331eef4f27bSRobert Mustacchi
332eef4f27bSRobert Mustacchi REG_WR(pdev, pci.pci_grc_window_addr, pdev->hw_info.shmem_base & ~0x7fff);
333eef4f27bSRobert Mustacchi } /* lm_reg_rd_blk */
334eef4f27bSRobert Mustacchi
335eef4f27bSRobert Mustacchi
336eef4f27bSRobert Mustacchi
337eef4f27bSRobert Mustacchi /*******************************************************************************
338eef4f27bSRobert Mustacchi * Description:
339eef4f27bSRobert Mustacchi *
340eef4f27bSRobert Mustacchi * Return:
341eef4f27bSRobert Mustacchi ******************************************************************************/
342eef4f27bSRobert Mustacchi void
lm_reg_rd_blk_ind(lm_device_t * pdev,u32_t reg_offset,u32_t * buf_ptr,u32_t u32t_cnt)343eef4f27bSRobert Mustacchi lm_reg_rd_blk_ind(
344eef4f27bSRobert Mustacchi lm_device_t *pdev,
345eef4f27bSRobert Mustacchi u32_t reg_offset,
346eef4f27bSRobert Mustacchi u32_t *buf_ptr,
347eef4f27bSRobert Mustacchi u32_t u32t_cnt)
348eef4f27bSRobert Mustacchi {
349eef4f27bSRobert Mustacchi DbgBreakIf(reg_offset & 0x3);
350eef4f27bSRobert Mustacchi
351eef4f27bSRobert Mustacchi mm_acquire_ind_reg_lock(pdev);
352eef4f27bSRobert Mustacchi
353eef4f27bSRobert Mustacchi while(u32t_cnt)
354eef4f27bSRobert Mustacchi {
355eef4f27bSRobert Mustacchi REG_WR(pdev, pci_config.pcicfg_reg_window_address, reg_offset);
356eef4f27bSRobert Mustacchi REG_RD(pdev, pci_config.pcicfg_reg_window, buf_ptr);
357eef4f27bSRobert Mustacchi
358eef4f27bSRobert Mustacchi buf_ptr++;
359eef4f27bSRobert Mustacchi u32t_cnt--;
360eef4f27bSRobert Mustacchi reg_offset += 4;
361eef4f27bSRobert Mustacchi }
362eef4f27bSRobert Mustacchi
363eef4f27bSRobert Mustacchi mm_release_ind_reg_lock(pdev);
364eef4f27bSRobert Mustacchi } /* lm_reg_rd_blk_ind */
365eef4f27bSRobert Mustacchi
366eef4f27bSRobert Mustacchi
367eef4f27bSRobert Mustacchi
368eef4f27bSRobert Mustacchi /*******************************************************************************
369eef4f27bSRobert Mustacchi * Description:
370eef4f27bSRobert Mustacchi *
371eef4f27bSRobert Mustacchi * Return:
372eef4f27bSRobert Mustacchi ******************************************************************************/
373eef4f27bSRobert Mustacchi void
lm_reg_wr_blk(lm_device_t * pdev,u32_t reg_offset,u32_t * data_ptr,u32_t u32t_cnt)374eef4f27bSRobert Mustacchi lm_reg_wr_blk(
375eef4f27bSRobert Mustacchi lm_device_t *pdev,
376eef4f27bSRobert Mustacchi u32_t reg_offset,
377eef4f27bSRobert Mustacchi u32_t *data_ptr,
378eef4f27bSRobert Mustacchi u32_t u32t_cnt)
379eef4f27bSRobert Mustacchi {
380eef4f27bSRobert Mustacchi u32_t grc_win_offset;
381eef4f27bSRobert Mustacchi u32_t grc_win_base;
382eef4f27bSRobert Mustacchi u32_t grc_win_size;
383eef4f27bSRobert Mustacchi
384eef4f27bSRobert Mustacchi DbgBreakIf(reg_offset & 0x3);
385eef4f27bSRobert Mustacchi
386eef4f27bSRobert Mustacchi if (CHIP_NUM(pdev) == CHIP_NUM_5709)
387eef4f27bSRobert Mustacchi {
388eef4f27bSRobert Mustacchi grc_win_size = GRC_WINDOW_SIZE / 4;
389eef4f27bSRobert Mustacchi }
390eef4f27bSRobert Mustacchi else
391eef4f27bSRobert Mustacchi {
392eef4f27bSRobert Mustacchi grc_win_size = GRC_WINDOW_SIZE;
393eef4f27bSRobert Mustacchi }
394eef4f27bSRobert Mustacchi
395eef4f27bSRobert Mustacchi grc_win_offset = reg_offset & (grc_win_size - 1);
396eef4f27bSRobert Mustacchi grc_win_base = reg_offset & ~(grc_win_size - 1);
397eef4f27bSRobert Mustacchi
398eef4f27bSRobert Mustacchi REG_WR(pdev, pci.pci_grc_window_addr, grc_win_base);
399eef4f27bSRobert Mustacchi
400eef4f27bSRobert Mustacchi while(u32t_cnt)
401eef4f27bSRobert Mustacchi {
402eef4f27bSRobert Mustacchi if(grc_win_offset >= grc_win_size)
403eef4f27bSRobert Mustacchi {
404eef4f27bSRobert Mustacchi grc_win_offset = 0;
405eef4f27bSRobert Mustacchi grc_win_base += grc_win_size;
406eef4f27bSRobert Mustacchi
407eef4f27bSRobert Mustacchi REG_WR(pdev, pci.pci_grc_window_addr, grc_win_base);
408eef4f27bSRobert Mustacchi }
409eef4f27bSRobert Mustacchi
410eef4f27bSRobert Mustacchi REG_WR_OFFSET(pdev, GRC_WINDOW_BASE + grc_win_offset, *data_ptr);
411eef4f27bSRobert Mustacchi
412eef4f27bSRobert Mustacchi data_ptr++;
413eef4f27bSRobert Mustacchi u32t_cnt--;
414eef4f27bSRobert Mustacchi grc_win_offset += 4;
415eef4f27bSRobert Mustacchi }
416eef4f27bSRobert Mustacchi
417eef4f27bSRobert Mustacchi REG_WR(pdev, pci.pci_grc_window_addr, pdev->hw_info.shmem_base & ~0x7fff);
418eef4f27bSRobert Mustacchi } /* lm_reg_wr_blk */
419eef4f27bSRobert Mustacchi
420eef4f27bSRobert Mustacchi
421eef4f27bSRobert Mustacchi
422eef4f27bSRobert Mustacchi /*******************************************************************************
423eef4f27bSRobert Mustacchi * Description:
424eef4f27bSRobert Mustacchi *
425eef4f27bSRobert Mustacchi * Return:
426eef4f27bSRobert Mustacchi ******************************************************************************/
427eef4f27bSRobert Mustacchi void
lm_reg_wr_blk_ind(lm_device_t * pdev,u32_t reg_offset,u32_t * data_ptr,u32_t u32t_cnt)428eef4f27bSRobert Mustacchi lm_reg_wr_blk_ind(
429eef4f27bSRobert Mustacchi lm_device_t *pdev,
430eef4f27bSRobert Mustacchi u32_t reg_offset,
431eef4f27bSRobert Mustacchi u32_t *data_ptr,
432eef4f27bSRobert Mustacchi u32_t u32t_cnt)
433eef4f27bSRobert Mustacchi {
434eef4f27bSRobert Mustacchi DbgBreakIf(reg_offset & 0x3);
435eef4f27bSRobert Mustacchi
436eef4f27bSRobert Mustacchi mm_acquire_ind_reg_lock(pdev);
437eef4f27bSRobert Mustacchi
438eef4f27bSRobert Mustacchi while(u32t_cnt)
439eef4f27bSRobert Mustacchi {
440eef4f27bSRobert Mustacchi REG_WR(pdev, pci_config.pcicfg_reg_window_address, reg_offset);
441eef4f27bSRobert Mustacchi REG_WR(pdev, pci_config.pcicfg_reg_window, *data_ptr);
442eef4f27bSRobert Mustacchi
443eef4f27bSRobert Mustacchi data_ptr++;
444eef4f27bSRobert Mustacchi u32t_cnt--;
445eef4f27bSRobert Mustacchi reg_offset += 4;
446eef4f27bSRobert Mustacchi }
447eef4f27bSRobert Mustacchi
448eef4f27bSRobert Mustacchi mm_release_ind_reg_lock(pdev);
449eef4f27bSRobert Mustacchi } /* lm_reg_wr_blk_ind */
450eef4f27bSRobert Mustacchi
451eef4f27bSRobert Mustacchi
452eef4f27bSRobert Mustacchi
453eef4f27bSRobert Mustacchi /*******************************************************************************
454eef4f27bSRobert Mustacchi * Description:
455eef4f27bSRobert Mustacchi *
456eef4f27bSRobert Mustacchi * Return:
457eef4f27bSRobert Mustacchi ******************************************************************************/
458eef4f27bSRobert Mustacchi lm_status_t
lm_submit_fw_cmd(lm_device_t * pdev,u32_t drv_msg)459eef4f27bSRobert Mustacchi lm_submit_fw_cmd(
460eef4f27bSRobert Mustacchi lm_device_t *pdev,
461eef4f27bSRobert Mustacchi u32_t drv_msg)
462eef4f27bSRobert Mustacchi {
463eef4f27bSRobert Mustacchi u32_t val;
464eef4f27bSRobert Mustacchi
465eef4f27bSRobert Mustacchi if(pdev->vars.fw_timed_out)
466eef4f27bSRobert Mustacchi {
467eef4f27bSRobert Mustacchi DbgMessage(pdev, WARN, "fw timed out.\n");
468eef4f27bSRobert Mustacchi
469eef4f27bSRobert Mustacchi return LM_STATUS_FAILURE;
470eef4f27bSRobert Mustacchi }
471eef4f27bSRobert Mustacchi
472eef4f27bSRobert Mustacchi DbgBreakIf(drv_msg & 0xffff);
473eef4f27bSRobert Mustacchi
474eef4f27bSRobert Mustacchi REG_RD_IND(
475eef4f27bSRobert Mustacchi pdev,
476eef4f27bSRobert Mustacchi pdev->hw_info.shmem_base + OFFSETOF(shmem_region_t, drv_fw_mb.fw_mb),
477eef4f27bSRobert Mustacchi &val);
478eef4f27bSRobert Mustacchi if((val & FW_MSG_ACK) != (pdev->vars.fw_wr_seq & DRV_MSG_SEQ))
479eef4f27bSRobert Mustacchi {
480eef4f27bSRobert Mustacchi DbgMessage(pdev, WARN, "command pending.\n");
481*55fea89dSDan Cross
482eef4f27bSRobert Mustacchi return LM_STATUS_FAILURE;
483eef4f27bSRobert Mustacchi }
484eef4f27bSRobert Mustacchi
485eef4f27bSRobert Mustacchi pdev->vars.fw_wr_seq++;
486eef4f27bSRobert Mustacchi
487eef4f27bSRobert Mustacchi drv_msg |= (pdev->vars.fw_wr_seq & DRV_MSG_SEQ);
488eef4f27bSRobert Mustacchi
489eef4f27bSRobert Mustacchi REG_WR_IND(
490eef4f27bSRobert Mustacchi pdev,
491eef4f27bSRobert Mustacchi pdev->hw_info.shmem_base +
492eef4f27bSRobert Mustacchi OFFSETOF(shmem_region_t, drv_fw_mb.drv_mb),
493eef4f27bSRobert Mustacchi drv_msg);
494eef4f27bSRobert Mustacchi
495eef4f27bSRobert Mustacchi return LM_STATUS_SUCCESS;
496eef4f27bSRobert Mustacchi } /* lm_submit_fw_cmd */
497eef4f27bSRobert Mustacchi
498eef4f27bSRobert Mustacchi
499eef4f27bSRobert Mustacchi
500eef4f27bSRobert Mustacchi /*******************************************************************************
501eef4f27bSRobert Mustacchi * Description:
502eef4f27bSRobert Mustacchi *
503eef4f27bSRobert Mustacchi * Return:
504eef4f27bSRobert Mustacchi ******************************************************************************/
505eef4f27bSRobert Mustacchi lm_status_t
lm_last_fw_cmd_status(lm_device_t * pdev)506eef4f27bSRobert Mustacchi lm_last_fw_cmd_status(
507eef4f27bSRobert Mustacchi lm_device_t *pdev)
508eef4f27bSRobert Mustacchi {
509eef4f27bSRobert Mustacchi u32_t val;
510eef4f27bSRobert Mustacchi
511eef4f27bSRobert Mustacchi if(pdev->vars.fw_timed_out)
512eef4f27bSRobert Mustacchi {
513eef4f27bSRobert Mustacchi DbgMessage(pdev, WARN, "fw timed out.\n");
514eef4f27bSRobert Mustacchi
515eef4f27bSRobert Mustacchi return LM_STATUS_TIMEOUT;
516eef4f27bSRobert Mustacchi }
517eef4f27bSRobert Mustacchi
518eef4f27bSRobert Mustacchi REG_RD_IND(
519eef4f27bSRobert Mustacchi pdev,
520eef4f27bSRobert Mustacchi pdev->hw_info.shmem_base +
521eef4f27bSRobert Mustacchi OFFSETOF(shmem_region_t, drv_fw_mb.fw_mb),
522eef4f27bSRobert Mustacchi &val);
523eef4f27bSRobert Mustacchi if((val & FW_MSG_ACK) != (pdev->vars.fw_wr_seq & DRV_MSG_SEQ))
524eef4f27bSRobert Mustacchi {
525eef4f27bSRobert Mustacchi return LM_STATUS_BUSY;
526eef4f27bSRobert Mustacchi }
527eef4f27bSRobert Mustacchi
528eef4f27bSRobert Mustacchi if((val & FW_MSG_STATUS_MASK) != FW_MSG_STATUS_OK)
529eef4f27bSRobert Mustacchi {
530eef4f27bSRobert Mustacchi return LM_STATUS_FAILURE;
531eef4f27bSRobert Mustacchi }
532eef4f27bSRobert Mustacchi
533eef4f27bSRobert Mustacchi return LM_STATUS_SUCCESS;
534eef4f27bSRobert Mustacchi } /* lm_last_fw_cmd_status */
535eef4f27bSRobert Mustacchi
536eef4f27bSRobert Mustacchi
537eef4f27bSRobert Mustacchi
538eef4f27bSRobert Mustacchi /*******************************************************************************
539eef4f27bSRobert Mustacchi * Description:
540eef4f27bSRobert Mustacchi *
541eef4f27bSRobert Mustacchi * Return:
542eef4f27bSRobert Mustacchi ******************************************************************************/
543eef4f27bSRobert Mustacchi u32_t
lm_mb_get_cid_addr(lm_device_t * pdev,u32_t cid)544eef4f27bSRobert Mustacchi lm_mb_get_cid_addr(
545eef4f27bSRobert Mustacchi lm_device_t *pdev,
546eef4f27bSRobert Mustacchi u32_t cid)
547eef4f27bSRobert Mustacchi {
548eef4f27bSRobert Mustacchi u32_t mq_offset;
549eef4f27bSRobert Mustacchi
550eef4f27bSRobert Mustacchi DbgBreakIf(pdev->params.bin_mq_mode && CHIP_NUM(pdev) != CHIP_NUM_5709);
551eef4f27bSRobert Mustacchi
552eef4f27bSRobert Mustacchi if(cid < 256 || pdev->params.bin_mq_mode == FALSE)
553eef4f27bSRobert Mustacchi {
554eef4f27bSRobert Mustacchi mq_offset = 0x10000 + (cid << MB_KERNEL_CTX_SHIFT);
555eef4f27bSRobert Mustacchi }
556eef4f27bSRobert Mustacchi else
557eef4f27bSRobert Mustacchi {
558eef4f27bSRobert Mustacchi DbgBreakIf(cid < pdev->hw_info.first_l4_l5_bin);
559eef4f27bSRobert Mustacchi
560*55fea89dSDan Cross mq_offset = 0x10000 +
561eef4f27bSRobert Mustacchi ((((cid - pdev->hw_info.first_l4_l5_bin) /
562eef4f27bSRobert Mustacchi pdev->hw_info.bin_size) + 256) << MB_KERNEL_CTX_SHIFT);
563eef4f27bSRobert Mustacchi }
564eef4f27bSRobert Mustacchi
565eef4f27bSRobert Mustacchi DbgBreakIf(mq_offset > pdev->hw_info.bar_size);
566eef4f27bSRobert Mustacchi
567eef4f27bSRobert Mustacchi return mq_offset;
568eef4f27bSRobert Mustacchi } /* lm_mb_get_cid_addr */
569eef4f27bSRobert Mustacchi
570eef4f27bSRobert Mustacchi
571eef4f27bSRobert Mustacchi
572eef4f27bSRobert Mustacchi /*******************************************************************************
573eef4f27bSRobert Mustacchi * Description:
574eef4f27bSRobert Mustacchi *
575eef4f27bSRobert Mustacchi * Return:
576eef4f27bSRobert Mustacchi ******************************************************************************/
577eef4f27bSRobert Mustacchi u32_t
lm_mb_get_bypass_addr(lm_device_t * pdev,u32_t cid)578eef4f27bSRobert Mustacchi lm_mb_get_bypass_addr(
579eef4f27bSRobert Mustacchi lm_device_t *pdev,
580eef4f27bSRobert Mustacchi u32_t cid)
581eef4f27bSRobert Mustacchi {
582eef4f27bSRobert Mustacchi u32_t mq_offset;
583eef4f27bSRobert Mustacchi
584eef4f27bSRobert Mustacchi DbgBreakIf(pdev->params.bin_mq_mode && CHIP_NUM(pdev) != CHIP_NUM_5709);
585eef4f27bSRobert Mustacchi
586eef4f27bSRobert Mustacchi if(cid < 256 || pdev->params.bin_mq_mode == FALSE)
587eef4f27bSRobert Mustacchi {
588*55fea89dSDan Cross mq_offset = 0x10000 +
589eef4f27bSRobert Mustacchi MB_KERNEL_CTX_SIZE * MAX_CID_CNT +
590eef4f27bSRobert Mustacchi cid * LM_PAGE_SIZE;
591eef4f27bSRobert Mustacchi }
592eef4f27bSRobert Mustacchi else
593eef4f27bSRobert Mustacchi {
594eef4f27bSRobert Mustacchi DbgBreakIf(cid < pdev->hw_info.first_l4_l5_bin);
595eef4f27bSRobert Mustacchi
596*55fea89dSDan Cross mq_offset = 0x10000 +
597eef4f27bSRobert Mustacchi MB_KERNEL_CTX_SIZE * MAX_CID_CNT +
598eef4f27bSRobert Mustacchi (((cid - pdev->hw_info.first_l4_l5_bin) /
599eef4f27bSRobert Mustacchi pdev->hw_info.bin_size) + 256) * LM_PAGE_SIZE;
600eef4f27bSRobert Mustacchi }
601eef4f27bSRobert Mustacchi
602eef4f27bSRobert Mustacchi DbgBreakIf(mq_offset > pdev->hw_info.bar_size);
603eef4f27bSRobert Mustacchi
604eef4f27bSRobert Mustacchi return mq_offset;
605eef4f27bSRobert Mustacchi } /* lm_mb_get_bypass_addr */
606eef4f27bSRobert Mustacchi
607