289 lines · c
1/**********************************************************************2 * Author: Cavium, Inc.3 *4 * Contact: support@cavium.com5 * 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 modify10 * it under the terms of the GNU General Public License, Version 2, as11 * published by the Free Software Foundation.12 *13 * This file is distributed in the hope that it will be useful, but14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or16 * NONINFRINGEMENT. See the GNU General Public License for more17 * details.18 **********************************************************************/19 20/*! \file octeon_nic.h21 * \brief Host NIC Driver: Routine to send network data &22 * control packet to Octeon.23 */24 25#ifndef __OCTEON_NIC_H__26#define __OCTEON_NIC_H__27 28/* Maximum number of 8-byte words can be sent in a NIC control message.29 */30#define MAX_NCTRL_UDD 3231 32typedef void (*octnic_ctrl_pkt_cb_fn_t) (void *);33 34/* Structure of control information passed by the NIC module to the OSI35 * layer when sending control commands to Octeon device software.36 */37struct octnic_ctrl_pkt {38 /** Command to be passed to the Octeon device software. */39 union octnet_cmd ncmd;40 41 /** Send buffer */42 void *data;43 u64 dmadata;44 45 /** Response buffer */46 void *rdata;47 u64 dmardata;48 49 /** Additional data that may be needed by some commands. */50 u64 udd[MAX_NCTRL_UDD];51 52 /** Input queue to use to send this command. */53 u64 iq_no;54 55 /** The network device that issued the control command. */56 u64 netpndev;57 58 /** Callback function called when the command has been fetched */59 octnic_ctrl_pkt_cb_fn_t cb_fn;60 61 u32 sc_status;62};63 64#define MAX_UDD_SIZE(nctrl) (sizeof((nctrl)->udd))65 66/** Structure of data information passed by the NIC module to the OSI67 * layer when forwarding data to Octeon device software.68 */69struct octnic_data_pkt {70 /** Pointer to information maintained by NIC module for this packet. The71 * OSI layer passes this as-is to the driver.72 */73 void *buf;74 75 /** Type of buffer passed in "buf" above. */76 u32 reqtype;77 78 /** Total data bytes to be transferred in this command. */79 u32 datasize;80 81 /** Command to be passed to the Octeon device software. */82 union octeon_instr_64B cmd;83 84 /** Input queue to use to send this command. */85 u32 q_no;86 87};88 89/** Structure passed by NIC module to OSI layer to prepare a command to send90 * network data to Octeon.91 */92union octnic_cmd_setup {93 struct {94 u32 iq_no:8;95 u32 gather:1;96 u32 timestamp:1;97 u32 ip_csum:1;98 u32 transport_csum:1;99 u32 tnl_csum:1;100 u32 rsvd:19;101 102 union {103 u32 datasize;104 u32 gatherptrs;105 } u;106 } s;107 108 u64 u64;109 110};111 112static inline int octnet_iq_is_full(struct octeon_device *oct, u32 q_no)113{114 return ((u32)atomic_read(&oct->instr_queue[q_no]->instr_pending)115 >= (oct->instr_queue[q_no]->max_count - 2));116}117 118static inline void119octnet_prepare_pci_cmd_o2(struct octeon_device *oct,120 union octeon_instr_64B *cmd,121 union octnic_cmd_setup *setup, u32 tag)122{123 struct octeon_instr_ih2 *ih2;124 struct octeon_instr_irh *irh;125 union octnic_packet_params packet_params;126 int port;127 128 memset(cmd, 0, sizeof(union octeon_instr_64B));129 130 ih2 = (struct octeon_instr_ih2 *)&cmd->cmd2.ih2;131 132 /* assume that rflag is cleared so therefore front data will only have133 * irh and ossp[0], ossp[1] for a total of 32 bytes134 */135 ih2->fsz = LIO_PCICMD_O2;136 137 ih2->tagtype = ORDERED_TAG;138 ih2->grp = DEFAULT_POW_GRP;139 140 port = (int)oct->instr_queue[setup->s.iq_no]->txpciq.s.port;141 142 if (tag)143 ih2->tag = tag;144 else145 ih2->tag = LIO_DATA(port);146 147 ih2->raw = 1;148 ih2->qos = (port & 3) + 4; /* map qos based on interface */149 150 if (!setup->s.gather) {151 ih2->dlengsz = setup->s.u.datasize;152 } else {153 ih2->gather = 1;154 ih2->dlengsz = setup->s.u.gatherptrs;155 }156 157 irh = (struct octeon_instr_irh *)&cmd->cmd2.irh;158 159 irh->opcode = OPCODE_NIC;160 irh->subcode = OPCODE_NIC_NW_DATA;161 162 packet_params.u32 = 0;163 164 packet_params.s.ip_csum = setup->s.ip_csum;165 packet_params.s.transport_csum = setup->s.transport_csum;166 packet_params.s.tnl_csum = setup->s.tnl_csum;167 packet_params.s.tsflag = setup->s.timestamp;168 169 irh->ossp = packet_params.u32;170}171 172static inline void173octnet_prepare_pci_cmd_o3(struct octeon_device *oct,174 union octeon_instr_64B *cmd,175 union octnic_cmd_setup *setup, u32 tag)176{177 struct octeon_instr_irh *irh;178 struct octeon_instr_ih3 *ih3;179 struct octeon_instr_pki_ih3 *pki_ih3;180 union octnic_packet_params packet_params;181 int port;182 183 memset(cmd, 0, sizeof(union octeon_instr_64B));184 185 ih3 = (struct octeon_instr_ih3 *)&cmd->cmd3.ih3;186 pki_ih3 = (struct octeon_instr_pki_ih3 *)&cmd->cmd3.pki_ih3;187 188 /* assume that rflag is cleared so therefore front data will only have189 * irh and ossp[1] and ossp[2] for a total of 24 bytes190 */191 ih3->pkind = oct->instr_queue[setup->s.iq_no]->txpciq.s.pkind;192 /*PKI IH*/193 ih3->fsz = LIO_PCICMD_O3;194 195 if (!setup->s.gather) {196 ih3->dlengsz = setup->s.u.datasize;197 } else {198 ih3->gather = 1;199 ih3->dlengsz = setup->s.u.gatherptrs;200 }201 202 pki_ih3->w = 1;203 pki_ih3->raw = 1;204 pki_ih3->utag = 1;205 pki_ih3->utt = 1;206 pki_ih3->uqpg = oct->instr_queue[setup->s.iq_no]->txpciq.s.use_qpg;207 208 port = (int)oct->instr_queue[setup->s.iq_no]->txpciq.s.port;209 210 if (tag)211 pki_ih3->tag = tag;212 else213 pki_ih3->tag = LIO_DATA(port);214 215 pki_ih3->tagtype = ORDERED_TAG;216 pki_ih3->qpg = oct->instr_queue[setup->s.iq_no]->txpciq.s.qpg;217 pki_ih3->pm = 0x7; /*0x7 - meant for Parse nothing, uninterpreted*/218 pki_ih3->sl = 8; /* sl will be sizeof(pki_ih3)*/219 220 irh = (struct octeon_instr_irh *)&cmd->cmd3.irh;221 222 irh->opcode = OPCODE_NIC;223 irh->subcode = OPCODE_NIC_NW_DATA;224 225 packet_params.u32 = 0;226 227 packet_params.s.ip_csum = setup->s.ip_csum;228 packet_params.s.transport_csum = setup->s.transport_csum;229 packet_params.s.tnl_csum = setup->s.tnl_csum;230 packet_params.s.tsflag = setup->s.timestamp;231 232 irh->ossp = packet_params.u32;233}234 235/** Utility function to prepare a 64B NIC instruction based on a setup command236 * @param cmd - pointer to instruction to be filled in.237 * @param setup - pointer to the setup structure238 * @param q_no - which queue for back pressure239 *240 * Assumes the cmd instruction is pre-allocated, but no fields are filled in.241 */242static inline void243octnet_prepare_pci_cmd(struct octeon_device *oct, union octeon_instr_64B *cmd,244 union octnic_cmd_setup *setup, u32 tag)245{246 if (OCTEON_CN6XXX(oct))247 octnet_prepare_pci_cmd_o2(oct, cmd, setup, tag);248 else249 octnet_prepare_pci_cmd_o3(oct, cmd, setup, tag);250}251 252/** Allocate and a soft command with space for a response immediately following253 * the commnad.254 * @param oct - octeon device pointer255 * @param cmd - pointer to the command structure, pre-filled for everything256 * except the response.257 * @param rdatasize - size in bytes of the response.258 *259 * @returns pointer to allocated buffer with command copied into it, and260 * response space immediately following.261 */262void *263octeon_alloc_soft_command_resp(struct octeon_device *oct,264 union octeon_instr_64B *cmd,265 u32 rdatasize);266 267/** Send a NIC data packet to the device268 * @param oct - octeon device pointer269 * @param ndata - control structure with queueing, and buffer information270 *271 * @returns IQ_FAILED if it failed to add to the input queue. IQ_STOP if it the272 * queue should be stopped, and IQ_SEND_OK if it sent okay.273 */274int octnet_send_nic_data_pkt(struct octeon_device *oct,275 struct octnic_data_pkt *ndata,276 int xmit_more);277 278/** Send a NIC control packet to the device279 * @param oct - octeon device pointer280 * @param nctrl - control structure with command, timout, and callback info281 * @returns IQ_FAILED if it failed to add to the input queue. IQ_STOP if it the282 * queue should be stopped, and IQ_SEND_OK if it sent okay.283 */284int285octnet_send_nic_ctrl_pkt(struct octeon_device *oct,286 struct octnic_ctrl_pkt *nctrl);287 288#endif289