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