0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/pci.h>
0019 #include <linux/netdevice.h>
0020 #include "liquidio_common.h"
0021 #include "octeon_droq.h"
0022 #include "octeon_iq.h"
0023 #include "response_manager.h"
0024 #include "octeon_device.h"
0025 #include "octeon_main.h"
0026 #include "octeon_mailbox.h"
0027 #include "cn23xx_pf_device.h"
0028
0029
0030
0031
0032
0033
0034
0035
0036 int octeon_mbox_read(struct octeon_mbox *mbox)
0037 {
0038 union octeon_mbox_message msg;
0039 int ret = 0;
0040
0041 spin_lock(&mbox->lock);
0042
0043 msg.u64 = readq(mbox->mbox_read_reg);
0044
0045 if ((msg.u64 == OCTEON_PFVFACK) || (msg.u64 == OCTEON_PFVFSIG)) {
0046 spin_unlock(&mbox->lock);
0047 return 0;
0048 }
0049
0050 if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVING) {
0051 mbox->mbox_req.data[mbox->mbox_req.recv_len - 1] = msg.u64;
0052 mbox->mbox_req.recv_len++;
0053 } else {
0054 if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVING) {
0055 mbox->mbox_resp.data[mbox->mbox_resp.recv_len - 1] =
0056 msg.u64;
0057 mbox->mbox_resp.recv_len++;
0058 } else {
0059 if ((mbox->state & OCTEON_MBOX_STATE_IDLE) &&
0060 (msg.s.type == OCTEON_MBOX_REQUEST)) {
0061 mbox->state &= ~OCTEON_MBOX_STATE_IDLE;
0062 mbox->state |=
0063 OCTEON_MBOX_STATE_REQUEST_RECEIVING;
0064 mbox->mbox_req.msg.u64 = msg.u64;
0065 mbox->mbox_req.q_no = mbox->q_no;
0066 mbox->mbox_req.recv_len = 1;
0067 } else {
0068 if ((mbox->state &
0069 OCTEON_MBOX_STATE_RESPONSE_PENDING) &&
0070 (msg.s.type == OCTEON_MBOX_RESPONSE)) {
0071 mbox->state &=
0072 ~OCTEON_MBOX_STATE_RESPONSE_PENDING;
0073 mbox->state |=
0074 OCTEON_MBOX_STATE_RESPONSE_RECEIVING
0075 ;
0076 mbox->mbox_resp.msg.u64 = msg.u64;
0077 mbox->mbox_resp.q_no = mbox->q_no;
0078 mbox->mbox_resp.recv_len = 1;
0079 } else {
0080 writeq(OCTEON_PFVFERR,
0081 mbox->mbox_read_reg);
0082 mbox->state |= OCTEON_MBOX_STATE_ERROR;
0083 spin_unlock(&mbox->lock);
0084 return 1;
0085 }
0086 }
0087 }
0088 }
0089
0090 if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVING) {
0091 if (mbox->mbox_req.recv_len < mbox->mbox_req.msg.s.len) {
0092 ret = 0;
0093 } else {
0094 mbox->state &= ~OCTEON_MBOX_STATE_REQUEST_RECEIVING;
0095 mbox->state |= OCTEON_MBOX_STATE_REQUEST_RECEIVED;
0096 ret = 1;
0097 }
0098 } else {
0099 if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVING) {
0100 if (mbox->mbox_resp.recv_len <
0101 mbox->mbox_resp.msg.s.len) {
0102 ret = 0;
0103 } else {
0104 mbox->state &=
0105 ~OCTEON_MBOX_STATE_RESPONSE_RECEIVING;
0106 mbox->state |=
0107 OCTEON_MBOX_STATE_RESPONSE_RECEIVED;
0108 ret = 1;
0109 }
0110 } else {
0111 WARN_ON(1);
0112 }
0113 }
0114
0115 writeq(OCTEON_PFVFACK, mbox->mbox_read_reg);
0116
0117 spin_unlock(&mbox->lock);
0118
0119 return ret;
0120 }
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 int octeon_mbox_write(struct octeon_device *oct,
0132 struct octeon_mbox_cmd *mbox_cmd)
0133 {
0134 struct octeon_mbox *mbox = oct->mbox[mbox_cmd->q_no];
0135 u32 count, i, ret = OCTEON_MBOX_STATUS_SUCCESS;
0136 long timeout = LIO_MBOX_WRITE_WAIT_TIME;
0137 unsigned long flags;
0138
0139 spin_lock_irqsave(&mbox->lock, flags);
0140
0141 if ((mbox_cmd->msg.s.type == OCTEON_MBOX_RESPONSE) &&
0142 !(mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVED)) {
0143 spin_unlock_irqrestore(&mbox->lock, flags);
0144 return OCTEON_MBOX_STATUS_FAILED;
0145 }
0146
0147 if ((mbox_cmd->msg.s.type == OCTEON_MBOX_REQUEST) &&
0148 !(mbox->state & OCTEON_MBOX_STATE_IDLE)) {
0149 spin_unlock_irqrestore(&mbox->lock, flags);
0150 return OCTEON_MBOX_STATUS_BUSY;
0151 }
0152
0153 if (mbox_cmd->msg.s.type == OCTEON_MBOX_REQUEST) {
0154 memcpy(&mbox->mbox_resp, mbox_cmd,
0155 sizeof(struct octeon_mbox_cmd));
0156 mbox->state = OCTEON_MBOX_STATE_RESPONSE_PENDING;
0157 }
0158
0159 spin_unlock_irqrestore(&mbox->lock, flags);
0160
0161 count = 0;
0162
0163 while (readq(mbox->mbox_write_reg) != OCTEON_PFVFSIG) {
0164 schedule_timeout_uninterruptible(timeout);
0165 if (count++ == LIO_MBOX_WRITE_WAIT_CNT) {
0166 ret = OCTEON_MBOX_STATUS_FAILED;
0167 break;
0168 }
0169 }
0170
0171 if (ret == OCTEON_MBOX_STATUS_SUCCESS) {
0172 writeq(mbox_cmd->msg.u64, mbox->mbox_write_reg);
0173 for (i = 0; i < (u32)(mbox_cmd->msg.s.len - 1); i++) {
0174 count = 0;
0175 while (readq(mbox->mbox_write_reg) !=
0176 OCTEON_PFVFACK) {
0177 schedule_timeout_uninterruptible(timeout);
0178 if (count++ == LIO_MBOX_WRITE_WAIT_CNT) {
0179 ret = OCTEON_MBOX_STATUS_FAILED;
0180 break;
0181 }
0182 }
0183 if (ret == OCTEON_MBOX_STATUS_SUCCESS)
0184 writeq(mbox_cmd->data[i], mbox->mbox_write_reg);
0185 else
0186 break;
0187 }
0188 }
0189
0190 spin_lock_irqsave(&mbox->lock, flags);
0191 if (mbox_cmd->msg.s.type == OCTEON_MBOX_RESPONSE) {
0192 mbox->state = OCTEON_MBOX_STATE_IDLE;
0193 writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
0194 } else {
0195 if ((!mbox_cmd->msg.s.resp_needed) ||
0196 (ret == OCTEON_MBOX_STATUS_FAILED)) {
0197 mbox->state &= ~OCTEON_MBOX_STATE_RESPONSE_PENDING;
0198 if (!(mbox->state &
0199 (OCTEON_MBOX_STATE_REQUEST_RECEIVING |
0200 OCTEON_MBOX_STATE_REQUEST_RECEIVED)))
0201 mbox->state = OCTEON_MBOX_STATE_IDLE;
0202 }
0203 }
0204 spin_unlock_irqrestore(&mbox->lock, flags);
0205
0206 return ret;
0207 }
0208
0209 static void get_vf_stats(struct octeon_device *oct,
0210 struct oct_vf_stats *stats)
0211 {
0212 int i;
0213
0214 for (i = 0; i < oct->num_iqs; i++) {
0215 if (!oct->instr_queue[i])
0216 continue;
0217 stats->tx_packets += oct->instr_queue[i]->stats.tx_done;
0218 stats->tx_bytes += oct->instr_queue[i]->stats.tx_tot_bytes;
0219 }
0220
0221 for (i = 0; i < oct->num_oqs; i++) {
0222 if (!oct->droq[i])
0223 continue;
0224 stats->rx_packets += oct->droq[i]->stats.rx_pkts_received;
0225 stats->rx_bytes += oct->droq[i]->stats.rx_bytes_received;
0226 }
0227 }
0228
0229
0230
0231
0232
0233
0234
0235
0236 static int octeon_mbox_process_cmd(struct octeon_mbox *mbox,
0237 struct octeon_mbox_cmd *mbox_cmd)
0238 {
0239 struct octeon_device *oct = mbox->oct_dev;
0240
0241 switch (mbox_cmd->msg.s.cmd) {
0242 case OCTEON_VF_ACTIVE:
0243 dev_dbg(&oct->pci_dev->dev, "got vfactive sending data back\n");
0244 mbox_cmd->msg.s.type = OCTEON_MBOX_RESPONSE;
0245 mbox_cmd->msg.s.resp_needed = 1;
0246 mbox_cmd->msg.s.len = 2;
0247 mbox_cmd->data[0] = 0;
0248 ((struct lio_version *)&mbox_cmd->data[0])->major =
0249 LIQUIDIO_BASE_MAJOR_VERSION;
0250 ((struct lio_version *)&mbox_cmd->data[0])->minor =
0251 LIQUIDIO_BASE_MINOR_VERSION;
0252 ((struct lio_version *)&mbox_cmd->data[0])->micro =
0253 LIQUIDIO_BASE_MICRO_VERSION;
0254 memcpy(mbox_cmd->msg.s.params, (uint8_t *)&oct->pfvf_hsword, 6);
0255
0256 octeon_mbox_write(oct, mbox_cmd);
0257 break;
0258
0259 case OCTEON_VF_FLR_REQUEST:
0260 dev_info(&oct->pci_dev->dev,
0261 "got a request for FLR from VF that owns DPI ring %u\n",
0262 mbox->q_no);
0263 pcie_flr(oct->sriov_info.dpiring_to_vfpcidev_lut[mbox->q_no]);
0264 break;
0265
0266 case OCTEON_PF_CHANGED_VF_MACADDR:
0267 if (OCTEON_CN23XX_VF(oct))
0268 octeon_pf_changed_vf_macaddr(oct,
0269 mbox_cmd->msg.s.params);
0270 break;
0271
0272 case OCTEON_GET_VF_STATS:
0273 dev_dbg(&oct->pci_dev->dev, "Got VF stats request. Sending data back\n");
0274 mbox_cmd->msg.s.type = OCTEON_MBOX_RESPONSE;
0275 mbox_cmd->msg.s.resp_needed = 1;
0276 mbox_cmd->msg.s.len = 1 +
0277 sizeof(struct oct_vf_stats) / sizeof(u64);
0278 get_vf_stats(oct, (struct oct_vf_stats *)mbox_cmd->data);
0279 octeon_mbox_write(oct, mbox_cmd);
0280 break;
0281 default:
0282 break;
0283 }
0284 return 0;
0285 }
0286
0287
0288
0289
0290
0291
0292
0293 int octeon_mbox_process_message(struct octeon_mbox *mbox)
0294 {
0295 struct octeon_mbox_cmd mbox_cmd;
0296 unsigned long flags;
0297
0298 spin_lock_irqsave(&mbox->lock, flags);
0299
0300 if (mbox->state & OCTEON_MBOX_STATE_ERROR) {
0301 if (mbox->state & (OCTEON_MBOX_STATE_RESPONSE_PENDING |
0302 OCTEON_MBOX_STATE_RESPONSE_RECEIVING)) {
0303 memcpy(&mbox_cmd, &mbox->mbox_resp,
0304 sizeof(struct octeon_mbox_cmd));
0305 mbox->state = OCTEON_MBOX_STATE_IDLE;
0306 writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
0307 spin_unlock_irqrestore(&mbox->lock, flags);
0308 mbox_cmd.recv_status = 1;
0309 if (mbox_cmd.fn)
0310 mbox_cmd.fn(mbox->oct_dev, &mbox_cmd,
0311 mbox_cmd.fn_arg);
0312 return 0;
0313 }
0314
0315 mbox->state = OCTEON_MBOX_STATE_IDLE;
0316 writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
0317 spin_unlock_irqrestore(&mbox->lock, flags);
0318 return 0;
0319 }
0320
0321 if (mbox->state & OCTEON_MBOX_STATE_RESPONSE_RECEIVED) {
0322 memcpy(&mbox_cmd, &mbox->mbox_resp,
0323 sizeof(struct octeon_mbox_cmd));
0324 mbox->state = OCTEON_MBOX_STATE_IDLE;
0325 writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
0326 spin_unlock_irqrestore(&mbox->lock, flags);
0327 mbox_cmd.recv_status = 0;
0328 if (mbox_cmd.fn)
0329 mbox_cmd.fn(mbox->oct_dev, &mbox_cmd, mbox_cmd.fn_arg);
0330 return 0;
0331 }
0332
0333 if (mbox->state & OCTEON_MBOX_STATE_REQUEST_RECEIVED) {
0334 memcpy(&mbox_cmd, &mbox->mbox_req,
0335 sizeof(struct octeon_mbox_cmd));
0336 if (!mbox_cmd.msg.s.resp_needed) {
0337 mbox->state &= ~OCTEON_MBOX_STATE_REQUEST_RECEIVED;
0338 if (!(mbox->state &
0339 OCTEON_MBOX_STATE_RESPONSE_PENDING))
0340 mbox->state = OCTEON_MBOX_STATE_IDLE;
0341 writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
0342 }
0343
0344 spin_unlock_irqrestore(&mbox->lock, flags);
0345 octeon_mbox_process_cmd(mbox, &mbox_cmd);
0346 return 0;
0347 }
0348
0349 spin_unlock_irqrestore(&mbox->lock, flags);
0350 WARN_ON(1);
0351
0352 return 0;
0353 }
0354
0355 int octeon_mbox_cancel(struct octeon_device *oct, int q_no)
0356 {
0357 struct octeon_mbox *mbox = oct->mbox[q_no];
0358 struct octeon_mbox_cmd *mbox_cmd;
0359 unsigned long flags = 0;
0360
0361 spin_lock_irqsave(&mbox->lock, flags);
0362 mbox_cmd = &mbox->mbox_resp;
0363
0364 if (!(mbox->state & OCTEON_MBOX_STATE_RESPONSE_PENDING)) {
0365 spin_unlock_irqrestore(&mbox->lock, flags);
0366 return 1;
0367 }
0368
0369 mbox->state = OCTEON_MBOX_STATE_IDLE;
0370 memset(mbox_cmd, 0, sizeof(*mbox_cmd));
0371 writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
0372 spin_unlock_irqrestore(&mbox->lock, flags);
0373
0374 return 0;
0375 }