1 /* 2 * BSD LICENSE 3 * 4 * Copyright(c) 2017 Cavium, Inc.. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Cavium, Inc. nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 /*$FreeBSD$*/ 34 35 /* \file lio_ctrl.h 36 * \brief Host NIC Driver: Routine to send network data & 37 * control packet to Octeon. 38 */ 39 40 #ifndef __LIO_CTRL_H__ 41 #define __LIO_CTRL_H__ 42 43 /* Maximum number of 8-byte words can be sent in a NIC control message. */ 44 #define LIO_MAX_NCTRL_UDD 32 45 46 typedef void (*lio_ctrl_pkt_cb_fn_t)(void *); 47 48 /* 49 * Structure of control information passed by the NIC module to the OSI 50 * layer when sending control commands to Octeon device software. 51 */ 52 struct lio_ctrl_pkt { 53 /* Command to be passed to the Octeon device software. */ 54 union octeon_cmd ncmd; 55 56 /* Send buffer */ 57 void *data; 58 uint64_t dmadata; 59 60 /* Response buffer */ 61 void *rdata; 62 uint64_t dmardata; 63 64 /* Additional data that may be needed by some commands. */ 65 uint64_t udd[LIO_MAX_NCTRL_UDD]; 66 67 /* Input queue to use to send this command. */ 68 uint64_t iq_no; 69 70 /* 71 * Time to wait for Octeon software to respond to this control command. 72 * If wait_time is 0, OSI assumes no response is expected. 73 */ 74 size_t wait_time; 75 76 /* The network device that issued the control command. */ 77 struct lio *lio; 78 79 /* Callback function called when the command has been fetched */ 80 lio_ctrl_pkt_cb_fn_t cb_fn; 81 }; 82 83 /* 84 * Structure of data information passed by the NIC module to the OSI 85 * layer when forwarding data to Octeon device software. 86 */ 87 struct lio_data_pkt { 88 /* 89 * Pointer to information maintained by NIC module for this packet. The 90 * OSI layer passes this as-is to the driver. 91 */ 92 void *buf; 93 94 /* Type of buffer passed in "buf" above. */ 95 uint32_t reqtype; 96 97 /* Total data bytes to be transferred in this command. */ 98 uint32_t datasize; 99 100 /* Command to be passed to the Octeon device software. */ 101 union lio_instr_64B cmd; 102 103 /* Input queue to use to send this command. */ 104 uint32_t q_no; 105 106 }; 107 108 /* 109 * Structure passed by NIC module to OSI layer to prepare a command to send 110 * network data to Octeon. 111 */ 112 union lio_cmd_setup { 113 struct { 114 uint32_t iq_no:8; 115 uint32_t gather:1; 116 uint32_t timestamp:1; 117 uint32_t ip_csum:1; 118 uint32_t transport_csum:1; 119 uint32_t tnl_csum:1; 120 uint32_t rsvd:19; 121 122 union { 123 uint32_t datasize; 124 uint32_t gatherptrs; 125 } u; 126 } s; 127 128 uint64_t cmd_setup64; 129 130 }; 131 132 static inline int 133 lio_iq_is_full(struct octeon_device *oct, uint32_t q_no) 134 { 135 136 return (atomic_load_acq_int(&oct->instr_queue[q_no]->instr_pending) >= 137 (oct->instr_queue[q_no]->max_count - 2)); 138 } 139 140 static inline void 141 lio_prepare_pci_cmd_o3(struct octeon_device *oct, union lio_instr_64B *cmd, 142 union lio_cmd_setup *setup, uint32_t tag) 143 { 144 union octeon_packet_params packet_params; 145 struct octeon_instr_irh *irh; 146 struct octeon_instr_ih3 *ih3; 147 struct octeon_instr_pki_ih3 *pki_ih3; 148 int port; 149 150 bzero(cmd, sizeof(union lio_instr_64B)); 151 152 ih3 = (struct octeon_instr_ih3 *)&cmd->cmd3.ih3; 153 pki_ih3 = (struct octeon_instr_pki_ih3 *)&cmd->cmd3.pki_ih3; 154 155 /* 156 * assume that rflag is cleared so therefore front data will only have 157 * irh and ossp[1] and ossp[2] for a total of 24 bytes 158 */ 159 ih3->pkind = oct->instr_queue[setup->s.iq_no]->txpciq.s.pkind; 160 /* PKI IH */ 161 ih3->fsz = LIO_PCICMD_O3; 162 163 if (!setup->s.gather) { 164 ih3->dlengsz = setup->s.u.datasize; 165 } else { 166 ih3->gather = 1; 167 ih3->dlengsz = setup->s.u.gatherptrs; 168 } 169 170 pki_ih3->w = 1; 171 pki_ih3->raw = 0; 172 pki_ih3->utag = 0; 173 pki_ih3->utt = 1; 174 pki_ih3->uqpg = oct->instr_queue[setup->s.iq_no]->txpciq.s.use_qpg; 175 176 port = (int)oct->instr_queue[setup->s.iq_no]->txpciq.s.port; 177 178 if (tag) 179 pki_ih3->tag = tag; 180 else 181 pki_ih3->tag = LIO_DATA(port); 182 183 pki_ih3->tagtype = LIO_ORDERED_TAG; 184 pki_ih3->qpg = oct->instr_queue[setup->s.iq_no]->txpciq.s.qpg; 185 pki_ih3->pm = 0x0; /* parse from L2 */ 186 /* sl will be sizeof(pki_ih3) + irh + ossp0 + ossp1 */ 187 pki_ih3->sl = 32; 188 189 irh = (struct octeon_instr_irh *)&cmd->cmd3.irh; 190 191 irh->opcode = LIO_OPCODE_NIC; 192 irh->subcode = LIO_OPCODE_NIC_NW_DATA; 193 194 packet_params.pkt_params32 = 0; 195 196 packet_params.s.ip_csum = setup->s.ip_csum; 197 packet_params.s.transport_csum = setup->s.transport_csum; 198 packet_params.s.tnl_csum = setup->s.tnl_csum; 199 packet_params.s.tsflag = setup->s.timestamp; 200 201 irh->ossp = packet_params.pkt_params32; 202 } 203 204 /* 205 * Utility function to prepare a 64B NIC instruction based on a setup command 206 * @param oct - Pointer to current octeon device 207 * @param cmd - pointer to instruction to be filled in. 208 * @param setup - pointer to the setup structure 209 * @param q_no - which queue for back pressure 210 * 211 * Assumes the cmd instruction is pre-allocated, but no fields are filled in. 212 */ 213 static inline void 214 lio_prepare_pci_cmd(struct octeon_device *oct, union lio_instr_64B *cmd, 215 union lio_cmd_setup *setup, uint32_t tag) 216 { 217 218 lio_prepare_pci_cmd_o3(oct, cmd, setup, tag); 219 } 220 221 /* 222 * Send a NIC data packet to the device 223 * @param oct - octeon device pointer 224 * @param ndata - control structure with queueing, and buffer information 225 * 226 * @returns LIO_IQ_FAILED if it failed to add to the input queue. 227 * LIO_IQ_STOP if it the queue should be stopped, 228 * and LIO_IQ_SEND_OK if it sent okay. 229 */ 230 int lio_send_data_pkt(struct octeon_device *oct, 231 struct lio_data_pkt *ndata); 232 233 /* 234 * Send a NIC control packet to the device 235 * @param oct - octeon device pointer 236 * @param nctrl - control structure with command, timeout, and callback info 237 * @returns IQ_FAILED if it failed to add to the input queue. IQ_STOP if it the 238 * queue should be stopped, and LIO_IQ_SEND_OK if it sent okay. 239 */ 240 int lio_send_ctrl_pkt(struct octeon_device *oct, 241 struct lio_ctrl_pkt *nctrl); 242 243 #endif /* __LIO_CTRL_H__ */ 244