1 | /********************************************************************** |
2 | * Author: Cavium, Inc. |
3 | * |
4 | * Contact: support@cavium.com |
5 | * Please include "LiquidIO" in the subject. |
6 | * |
7 | * Copyright (c) 2003-2016 Cavium, Inc. |
8 | * |
9 | * This file is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License, Version 2, as |
11 | * published by the Free Software Foundation. |
12 | * |
13 | * This file is distributed in the hope that it will be useful, but |
14 | * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty |
15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or |
16 | * NONINFRINGEMENT. See the GNU General Public License for more details. |
17 | ***********************************************************************/ |
18 | /*! \file octeon_main.h |
19 | * \brief Host Driver: This file is included by all host driver source files |
20 | * to include common definitions. |
21 | */ |
22 | |
23 | #ifndef _OCTEON_MAIN_H_ |
24 | #define _OCTEON_MAIN_H_ |
25 | |
26 | #include <linux/sched/signal.h> |
27 | |
28 | #if BITS_PER_LONG == 32 |
29 | #define CVM_CAST64(v) ((long long)(v)) |
30 | #elif BITS_PER_LONG == 64 |
31 | #define CVM_CAST64(v) ((long long)(long)(v)) |
32 | #else |
33 | #error "Unknown system architecture" |
34 | #endif |
35 | |
36 | #define DRV_NAME "LiquidIO" |
37 | |
38 | struct octeon_device_priv { |
39 | /** Tasklet structures for this device. */ |
40 | struct tasklet_struct droq_tasklet; |
41 | unsigned long napi_mask; |
42 | struct octeon_device *dev; |
43 | }; |
44 | |
45 | /** This structure is used by NIC driver to store information required |
46 | * to free the sk_buff when the packet has been fetched by Octeon. |
47 | * Bytes offset below assume worst-case of a 64-bit system. |
48 | */ |
49 | struct octnet_buf_free_info { |
50 | /** Bytes 1-8. Pointer to network device private structure. */ |
51 | struct lio *lio; |
52 | |
53 | /** Bytes 9-16. Pointer to sk_buff. */ |
54 | struct sk_buff *skb; |
55 | |
56 | /** Bytes 17-24. Pointer to gather list. */ |
57 | struct octnic_gather *g; |
58 | |
59 | /** Bytes 25-32. Physical address of skb->data or gather list. */ |
60 | u64 dptr; |
61 | |
62 | /** Bytes 33-47. Piggybacked soft command, if any */ |
63 | struct octeon_soft_command *sc; |
64 | }; |
65 | |
66 | /* BQL-related functions */ |
67 | int octeon_report_sent_bytes_to_bql(void *buf, int reqtype); |
68 | void octeon_update_tx_completion_counters(void *buf, int reqtype, |
69 | unsigned int *pkts_compl, |
70 | unsigned int *bytes_compl); |
71 | void octeon_report_tx_completion_to_bql(void *txq, unsigned int pkts_compl, |
72 | unsigned int bytes_compl); |
73 | void octeon_pf_changed_vf_macaddr(struct octeon_device *oct, u8 *mac); |
74 | |
75 | void octeon_schedule_rxq_oom_work(struct octeon_device *oct, |
76 | struct octeon_droq *droq); |
77 | |
78 | /** Swap 8B blocks */ |
79 | static inline void octeon_swap_8B_data(u64 *data, u32 blocks) |
80 | { |
81 | while (blocks) { |
82 | cpu_to_be64s(data); |
83 | blocks--; |
84 | data++; |
85 | } |
86 | } |
87 | |
88 | /** |
89 | * \brief unmaps a PCI BAR |
90 | * @param oct Pointer to Octeon device |
91 | * @param baridx bar index |
92 | */ |
93 | static inline void octeon_unmap_pci_barx(struct octeon_device *oct, int baridx) |
94 | { |
95 | dev_dbg(&oct->pci_dev->dev, "Freeing PCI mapped regions for Bar%d\n" , |
96 | baridx); |
97 | |
98 | if (oct->mmio[baridx].done) |
99 | iounmap(addr: oct->mmio[baridx].hw_addr); |
100 | |
101 | if (oct->mmio[baridx].start) |
102 | pci_release_region(oct->pci_dev, baridx * 2); |
103 | } |
104 | |
105 | /** |
106 | * \brief maps a PCI BAR |
107 | * @param oct Pointer to Octeon device |
108 | * @param baridx bar index |
109 | * @param max_map_len maximum length of mapped memory |
110 | */ |
111 | static inline int octeon_map_pci_barx(struct octeon_device *oct, |
112 | int baridx, int max_map_len) |
113 | { |
114 | u32 mapped_len = 0; |
115 | |
116 | if (pci_request_region(oct->pci_dev, baridx * 2, DRV_NAME)) { |
117 | dev_err(&oct->pci_dev->dev, "pci_request_region failed for bar %d\n" , |
118 | baridx); |
119 | return 1; |
120 | } |
121 | |
122 | oct->mmio[baridx].start = pci_resource_start(oct->pci_dev, baridx * 2); |
123 | oct->mmio[baridx].len = pci_resource_len(oct->pci_dev, baridx * 2); |
124 | |
125 | mapped_len = oct->mmio[baridx].len; |
126 | if (!mapped_len) |
127 | goto err_release_region; |
128 | |
129 | if (max_map_len && (mapped_len > max_map_len)) |
130 | mapped_len = max_map_len; |
131 | |
132 | oct->mmio[baridx].hw_addr = |
133 | ioremap(offset: oct->mmio[baridx].start, size: mapped_len); |
134 | oct->mmio[baridx].mapped_len = mapped_len; |
135 | |
136 | dev_dbg(&oct->pci_dev->dev, "BAR%d start: 0x%llx mapped %u of %u bytes\n" , |
137 | baridx, oct->mmio[baridx].start, mapped_len, |
138 | oct->mmio[baridx].len); |
139 | |
140 | if (!oct->mmio[baridx].hw_addr) { |
141 | dev_err(&oct->pci_dev->dev, "error ioremap for bar %d\n" , |
142 | baridx); |
143 | goto err_release_region; |
144 | } |
145 | oct->mmio[baridx].done = 1; |
146 | |
147 | return 0; |
148 | |
149 | err_release_region: |
150 | pci_release_region(oct->pci_dev, baridx * 2); |
151 | return 1; |
152 | } |
153 | |
154 | /* input parameter: |
155 | * sc: pointer to a soft request |
156 | * timeout: milli sec which an application wants to wait for the |
157 | response of the request. |
158 | * 0: the request will wait until its response gets back |
159 | * from the firmware within LIO_SC_MAX_TMO_MS milli sec. |
160 | * It the response does not return within |
161 | * LIO_SC_MAX_TMO_MS milli sec, lio_process_ordered_list() |
162 | * will move the request to zombie response list. |
163 | * |
164 | * return value: |
165 | * 0: got the response from firmware for the sc request. |
166 | * errno -EINTR: user abort the command. |
167 | * errno -ETIME: user spefified timeout value has been expired. |
168 | * errno -EBUSY: the response of the request does not return in |
169 | * resonable time (LIO_SC_MAX_TMO_MS). |
170 | * the sc wll be move to zombie response list by |
171 | * lio_process_ordered_list() |
172 | * |
173 | * A request with non-zero return value, the sc->caller_is_done |
174 | * will be marked 1. |
175 | * When getting a request with zero return value, the requestor |
176 | * should mark sc->caller_is_done with 1 after examing the |
177 | * response of sc. |
178 | * lio_process_ordered_list() will free the soft command on behalf |
179 | * of the soft command requestor. |
180 | * This is to fix the possible race condition of both timeout process |
181 | * and lio_process_ordered_list()/callback function to free a |
182 | * sc strucutre. |
183 | */ |
184 | static inline int |
185 | wait_for_sc_completion_timeout(struct octeon_device *oct_dev, |
186 | struct octeon_soft_command *sc, |
187 | unsigned long timeout) |
188 | { |
189 | int errno = 0; |
190 | long timeout_jiff; |
191 | |
192 | if (timeout) |
193 | timeout_jiff = msecs_to_jiffies(m: timeout); |
194 | else |
195 | timeout_jiff = MAX_SCHEDULE_TIMEOUT; |
196 | |
197 | timeout_jiff = |
198 | wait_for_completion_interruptible_timeout(x: &sc->complete, |
199 | timeout: timeout_jiff); |
200 | if (timeout_jiff == 0) { |
201 | dev_err(&oct_dev->pci_dev->dev, "%s: sc is timeout\n" , |
202 | __func__); |
203 | WRITE_ONCE(sc->caller_is_done, true); |
204 | errno = -ETIME; |
205 | } else if (timeout_jiff == -ERESTARTSYS) { |
206 | dev_err(&oct_dev->pci_dev->dev, "%s: sc is interrupted\n" , |
207 | __func__); |
208 | WRITE_ONCE(sc->caller_is_done, true); |
209 | errno = -EINTR; |
210 | } else if (sc->sc_status == OCTEON_REQUEST_TIMEOUT) { |
211 | dev_err(&oct_dev->pci_dev->dev, "%s: sc has fatal timeout\n" , |
212 | __func__); |
213 | WRITE_ONCE(sc->caller_is_done, true); |
214 | errno = -EBUSY; |
215 | } |
216 | |
217 | return errno; |
218 | } |
219 | |
220 | #ifndef ROUNDUP4 |
221 | #define ROUNDUP4(val) (((val) + 3) & 0xfffffffc) |
222 | #endif |
223 | |
224 | #ifndef ROUNDUP8 |
225 | #define ROUNDUP8(val) (((val) + 7) & 0xfffffff8) |
226 | #endif |
227 | |
228 | #ifndef ROUNDUP16 |
229 | #define ROUNDUP16(val) (((val) + 15) & 0xfffffff0) |
230 | #endif |
231 | |
232 | #ifndef ROUNDUP128 |
233 | #define ROUNDUP128(val) (((val) + 127) & 0xffffff80) |
234 | #endif |
235 | |
236 | #endif /* _OCTEON_MAIN_H_ */ |
237 | |