xref: /linux/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c (revision fab183d632628381b466a41479489541ac0e29a0)
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 #include <linux/pci.h>
19 #include <linux/netdevice.h>
20 #include "liquidio_common.h"
21 #include "octeon_droq.h"
22 #include "octeon_iq.h"
23 #include "response_manager.h"
24 #include "octeon_device.h"
25 #include "octeon_main.h"
26 #include "octeon_mailbox.h"
27 #include "cn23xx_pf_device.h"
28 
lio_vf_pci_dev_by_qno(struct octeon_device * oct,u32 q_no)29 static struct pci_dev *lio_vf_pci_dev_by_qno(struct octeon_device *oct, u32 q_no)
30 {
31 	struct pci_dev *vfdev = NULL;
32 	int vfidx;
33 
34 	if (!oct->sriov_info.rings_per_vf)
35 		return NULL;
36 
37 	if (q_no % oct->sriov_info.rings_per_vf)
38 		return NULL;
39 
40 	vfidx = q_no / oct->sriov_info.rings_per_vf;
41 	if (vfidx >= oct->sriov_info.num_vfs_alloced)
42 		return NULL;
43 
44 	while ((vfdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
45 				       OCTEON_CN23XX_VF_VID, vfdev))) {
46 		if (pci_physfn(vfdev) && pci_physfn(vfdev) == oct->pci_dev &&
47 		    pci_iov_vf_id(vfdev) == vfidx)
48 			return vfdev;
49 	}
50 
51 	return NULL;
52 }
53 
54 /**
55  * octeon_mbox_read:
56  * @mbox: Pointer mailbox
57  *
58  * Reads the 8-bytes of data from the mbox register
59  * Writes back the acknowldgement inidcating completion of read
60  */
octeon_mbox_read(struct octeon_mbox * mbox)61 int octeon_mbox_read(struct octeon_mbox *mbox)
62 {
63 	union octeon_mbox_message msg;
64 	int ret = 0;
65 
66 	spin_lock(&mbox->lock);
67 
68 	msg.u64 = readq(mbox->mbox_read_reg);
69 
70 	if ((msg.u64 == OCTEON_PFVFACK) || (msg.u64 == OCTEON_PFVFSIG)) {
71 		spin_unlock(&mbox->lock);
72 		return 0;
73 	}
74 
75 	if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVING) {
76 		mbox->mbox_req.data[mbox->mbox_req.recv_len - 1] = msg.u64;
77 		mbox->mbox_req.recv_len++;
78 	} else {
79 		if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVING) {
80 			mbox->mbox_resp.data[mbox->mbox_resp.recv_len - 1] =
81 				msg.u64;
82 			mbox->mbox_resp.recv_len++;
83 		} else {
84 			if ((mbox->state & OCTEON_MBOX_STATE_IDLE) &&
85 			    (msg.s.type == OCTEON_MBOX_REQUEST)) {
86 				mbox->state &= ~OCTEON_MBOX_STATE_IDLE;
87 				mbox->state |=
88 				    OCTEON_MBOX_STATE_REQUEST_RECEIVING;
89 				mbox->mbox_req.msg.u64 = msg.u64;
90 				mbox->mbox_req.q_no = mbox->q_no;
91 				mbox->mbox_req.recv_len = 1;
92 			} else {
93 				if ((mbox->state &
94 				     OCTEON_MBOX_STATE_RESPONSE_PENDING) &&
95 				    (msg.s.type == OCTEON_MBOX_RESPONSE)) {
96 					mbox->state &=
97 					    ~OCTEON_MBOX_STATE_RESPONSE_PENDING;
98 					mbox->state |=
99 					    OCTEON_MBOX_STATE_RESPONSE_RECEIVING
100 					    ;
101 					mbox->mbox_resp.msg.u64 = msg.u64;
102 					mbox->mbox_resp.q_no = mbox->q_no;
103 					mbox->mbox_resp.recv_len = 1;
104 				} else {
105 					writeq(OCTEON_PFVFERR,
106 					       mbox->mbox_read_reg);
107 					mbox->state |= OCTEON_MBOX_STATE_ERROR;
108 					spin_unlock(&mbox->lock);
109 					return 1;
110 				}
111 			}
112 		}
113 	}
114 
115 	if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVING) {
116 		if (mbox->mbox_req.recv_len < mbox->mbox_req.msg.s.len) {
117 			ret = 0;
118 		} else {
119 			mbox->state &= ~OCTEON_MBOX_STATE_REQUEST_RECEIVING;
120 			mbox->state |= OCTEON_MBOX_STATE_REQUEST_RECEIVED;
121 			ret = 1;
122 		}
123 	} else {
124 		if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVING) {
125 			if (mbox->mbox_resp.recv_len <
126 			    mbox->mbox_resp.msg.s.len) {
127 				ret = 0;
128 			} else {
129 				mbox->state &=
130 				    ~OCTEON_MBOX_STATE_RESPONSE_RECEIVING;
131 				mbox->state |=
132 				    OCTEON_MBOX_STATE_RESPONSE_RECEIVED;
133 				ret = 1;
134 			}
135 		} else {
136 			WARN_ON(1);
137 		}
138 	}
139 
140 	writeq(OCTEON_PFVFACK, mbox->mbox_read_reg);
141 
142 	spin_unlock(&mbox->lock);
143 
144 	return ret;
145 }
146 
147 /**
148  * octeon_mbox_write:
149  * @oct: Pointer Octeon Device
150  * @mbox_cmd: Cmd to send to mailbox.
151  *
152  * Populates the queue specific mbox structure
153  * with cmd information.
154  * Write the cmd to mbox register
155  */
octeon_mbox_write(struct octeon_device * oct,struct octeon_mbox_cmd * mbox_cmd)156 int octeon_mbox_write(struct octeon_device *oct,
157 		      struct octeon_mbox_cmd *mbox_cmd)
158 {
159 	struct octeon_mbox *mbox = oct->mbox[mbox_cmd->q_no];
160 	u32 count, i, ret = OCTEON_MBOX_STATUS_SUCCESS;
161 	long timeout = LIO_MBOX_WRITE_WAIT_TIME;
162 	unsigned long flags;
163 
164 	spin_lock_irqsave(&mbox->lock, flags);
165 
166 	if ((mbox_cmd->msg.s.type == OCTEON_MBOX_RESPONSE) &&
167 	    !(mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVED)) {
168 		spin_unlock_irqrestore(&mbox->lock, flags);
169 		return OCTEON_MBOX_STATUS_FAILED;
170 	}
171 
172 	if ((mbox_cmd->msg.s.type == OCTEON_MBOX_REQUEST) &&
173 	    !(mbox->state & OCTEON_MBOX_STATE_IDLE)) {
174 		spin_unlock_irqrestore(&mbox->lock, flags);
175 		return OCTEON_MBOX_STATUS_BUSY;
176 	}
177 
178 	if (mbox_cmd->msg.s.type == OCTEON_MBOX_REQUEST) {
179 		memcpy(&mbox->mbox_resp, mbox_cmd,
180 		       sizeof(struct octeon_mbox_cmd));
181 		mbox->state = OCTEON_MBOX_STATE_RESPONSE_PENDING;
182 	}
183 
184 	spin_unlock_irqrestore(&mbox->lock, flags);
185 
186 	count = 0;
187 
188 	while (readq(mbox->mbox_write_reg) != OCTEON_PFVFSIG) {
189 		schedule_timeout_uninterruptible(timeout);
190 		if (count++ == LIO_MBOX_WRITE_WAIT_CNT) {
191 			ret = OCTEON_MBOX_STATUS_FAILED;
192 			break;
193 		}
194 	}
195 
196 	if (ret == OCTEON_MBOX_STATUS_SUCCESS) {
197 		writeq(mbox_cmd->msg.u64, mbox->mbox_write_reg);
198 		for (i = 0; i < (u32)(mbox_cmd->msg.s.len - 1); i++) {
199 			count = 0;
200 			while (readq(mbox->mbox_write_reg) !=
201 			       OCTEON_PFVFACK) {
202 				schedule_timeout_uninterruptible(timeout);
203 				if (count++ == LIO_MBOX_WRITE_WAIT_CNT) {
204 					ret = OCTEON_MBOX_STATUS_FAILED;
205 					break;
206 				}
207 			}
208 			if (ret == OCTEON_MBOX_STATUS_SUCCESS)
209 				writeq(mbox_cmd->data[i], mbox->mbox_write_reg);
210 			else
211 				break;
212 		}
213 	}
214 
215 	spin_lock_irqsave(&mbox->lock, flags);
216 	if (mbox_cmd->msg.s.type == OCTEON_MBOX_RESPONSE) {
217 		mbox->state = OCTEON_MBOX_STATE_IDLE;
218 		writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
219 	} else {
220 		if ((!mbox_cmd->msg.s.resp_needed) ||
221 		    (ret == OCTEON_MBOX_STATUS_FAILED)) {
222 			mbox->state &= ~OCTEON_MBOX_STATE_RESPONSE_PENDING;
223 			if (!(mbox->state &
224 			      (OCTEON_MBOX_STATE_REQUEST_RECEIVING |
225 			       OCTEON_MBOX_STATE_REQUEST_RECEIVED)))
226 				mbox->state = OCTEON_MBOX_STATE_IDLE;
227 		}
228 	}
229 	spin_unlock_irqrestore(&mbox->lock, flags);
230 
231 	return ret;
232 }
233 
get_vf_stats(struct octeon_device * oct,struct oct_vf_stats * stats)234 static void get_vf_stats(struct octeon_device *oct,
235 			 struct oct_vf_stats *stats)
236 {
237 	int i;
238 
239 	for (i = 0; i < oct->num_iqs; i++) {
240 		if (!oct->instr_queue[i])
241 			continue;
242 		stats->tx_packets += oct->instr_queue[i]->stats.tx_done;
243 		stats->tx_bytes += oct->instr_queue[i]->stats.tx_tot_bytes;
244 	}
245 
246 	for (i = 0; i < oct->num_oqs; i++) {
247 		if (!oct->droq[i])
248 			continue;
249 		stats->rx_packets += oct->droq[i]->stats.rx_pkts_received;
250 		stats->rx_bytes += oct->droq[i]->stats.rx_bytes_received;
251 	}
252 }
253 
254 /**
255  * octeon_mbox_process_cmd:
256  * @mbox: Pointer mailbox
257  * @mbox_cmd: Pointer to command received
258  *
259  * Process the cmd received in mbox
260  */
octeon_mbox_process_cmd(struct octeon_mbox * mbox,struct octeon_mbox_cmd * mbox_cmd)261 static int octeon_mbox_process_cmd(struct octeon_mbox *mbox,
262 				   struct octeon_mbox_cmd *mbox_cmd)
263 {
264 	struct octeon_device *oct = mbox->oct_dev;
265 	struct pci_dev *vfdev;
266 
267 	switch (mbox_cmd->msg.s.cmd) {
268 	case OCTEON_VF_ACTIVE:
269 		dev_dbg(&oct->pci_dev->dev, "got vfactive sending data back\n");
270 		mbox_cmd->msg.s.type = OCTEON_MBOX_RESPONSE;
271 		mbox_cmd->msg.s.resp_needed = 1;
272 		mbox_cmd->msg.s.len = 2;
273 		mbox_cmd->data[0] = 0; /* VF version is in mbox_cmd->data[0] */
274 		((struct lio_version *)&mbox_cmd->data[0])->major =
275 			LIQUIDIO_BASE_MAJOR_VERSION;
276 		((struct lio_version *)&mbox_cmd->data[0])->minor =
277 			LIQUIDIO_BASE_MINOR_VERSION;
278 		((struct lio_version *)&mbox_cmd->data[0])->micro =
279 			LIQUIDIO_BASE_MICRO_VERSION;
280 		memcpy(mbox_cmd->msg.s.params, (uint8_t *)&oct->pfvf_hsword, 6);
281 		/* Sending core cofig info to the corresponding active VF.*/
282 		octeon_mbox_write(oct, mbox_cmd);
283 		break;
284 
285 	case OCTEON_VF_FLR_REQUEST:
286 		dev_info(&oct->pci_dev->dev,
287 			 "got a request for FLR from VF that owns DPI ring %u\n",
288 			 mbox->q_no);
289 		vfdev = lio_vf_pci_dev_by_qno(oct, mbox->q_no);
290 		if (!vfdev)
291 			break;
292 
293 		pcie_flr(vfdev);
294 		pci_dev_put(vfdev);
295 		break;
296 
297 	case OCTEON_PF_CHANGED_VF_MACADDR:
298 		if (OCTEON_CN23XX_VF(oct))
299 			octeon_pf_changed_vf_macaddr(oct,
300 						     mbox_cmd->msg.s.params);
301 		break;
302 
303 	case OCTEON_GET_VF_STATS:
304 		dev_dbg(&oct->pci_dev->dev, "Got VF stats request. Sending data back\n");
305 		mbox_cmd->msg.s.type = OCTEON_MBOX_RESPONSE;
306 		mbox_cmd->msg.s.resp_needed = 1;
307 		mbox_cmd->msg.s.len = 1 +
308 			sizeof(struct oct_vf_stats) / sizeof(u64);
309 		get_vf_stats(oct, (struct oct_vf_stats *)mbox_cmd->data);
310 		octeon_mbox_write(oct, mbox_cmd);
311 		break;
312 	default:
313 		break;
314 	}
315 	return 0;
316 }
317 
318 /**
319  * octeon_mbox_process_message
320  * @mbox: mailbox
321  *
322  * Process the received mbox message.
323  */
octeon_mbox_process_message(struct octeon_mbox * mbox)324 int octeon_mbox_process_message(struct octeon_mbox *mbox)
325 {
326 	struct octeon_mbox_cmd mbox_cmd;
327 	unsigned long flags;
328 
329 	spin_lock_irqsave(&mbox->lock, flags);
330 
331 	if (mbox->state & OCTEON_MBOX_STATE_ERROR) {
332 		if (mbox->state & (OCTEON_MBOX_STATE_RESPONSE_PENDING |
333 				   OCTEON_MBOX_STATE_RESPONSE_RECEIVING)) {
334 			memcpy(&mbox_cmd, &mbox->mbox_resp,
335 			       sizeof(struct octeon_mbox_cmd));
336 			mbox->state = OCTEON_MBOX_STATE_IDLE;
337 			writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
338 			spin_unlock_irqrestore(&mbox->lock, flags);
339 			mbox_cmd.recv_status = 1;
340 			if (mbox_cmd.fn)
341 				mbox_cmd.fn(mbox->oct_dev, &mbox_cmd,
342 					    mbox_cmd.fn_arg);
343 			return 0;
344 		}
345 
346 		mbox->state = OCTEON_MBOX_STATE_IDLE;
347 		writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
348 		spin_unlock_irqrestore(&mbox->lock, flags);
349 		return 0;
350 	}
351 
352 	if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVED) {
353 		memcpy(&mbox_cmd, &mbox->mbox_resp,
354 		       sizeof(struct octeon_mbox_cmd));
355 		mbox->state = OCTEON_MBOX_STATE_IDLE;
356 		writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
357 		spin_unlock_irqrestore(&mbox->lock, flags);
358 		mbox_cmd.recv_status = 0;
359 		if (mbox_cmd.fn)
360 			mbox_cmd.fn(mbox->oct_dev, &mbox_cmd, mbox_cmd.fn_arg);
361 		return 0;
362 	}
363 
364 	if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVED) {
365 		memcpy(&mbox_cmd, &mbox->mbox_req,
366 		       sizeof(struct octeon_mbox_cmd));
367 		if (!mbox_cmd.msg.s.resp_needed) {
368 			mbox->state &= ~OCTEON_MBOX_STATE_REQUEST_RECEIVED;
369 			if (!(mbox->state &
370 			      OCTEON_MBOX_STATE_RESPONSE_PENDING))
371 				mbox->state = OCTEON_MBOX_STATE_IDLE;
372 			writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
373 		}
374 
375 		spin_unlock_irqrestore(&mbox->lock, flags);
376 		octeon_mbox_process_cmd(mbox, &mbox_cmd);
377 		return 0;
378 	}
379 
380 	spin_unlock_irqrestore(&mbox->lock, flags);
381 	WARN_ON(1);
382 
383 	return 0;
384 }
385 
octeon_mbox_cancel(struct octeon_device * oct,int q_no)386 int octeon_mbox_cancel(struct octeon_device *oct, int q_no)
387 {
388 	struct octeon_mbox *mbox = oct->mbox[q_no];
389 	struct octeon_mbox_cmd *mbox_cmd;
390 	unsigned long flags = 0;
391 
392 	spin_lock_irqsave(&mbox->lock, flags);
393 	mbox_cmd = &mbox->mbox_resp;
394 
395 	if (!(mbox->state & OCTEON_MBOX_STATE_RESPONSE_PENDING)) {
396 		spin_unlock_irqrestore(&mbox->lock, flags);
397 		return 1;
398 	}
399 
400 	mbox->state = OCTEON_MBOX_STATE_IDLE;
401 	memset(mbox_cmd, 0, sizeof(*mbox_cmd));
402 	writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
403 	spin_unlock_irqrestore(&mbox->lock, flags);
404 
405 	return 0;
406 }
407