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 17 * details. 18 **********************************************************************/ 19 20 /*! \file octeon_nic.h 21 * \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 32 31 32 typedef void (*octnic_ctrl_pkt_cb_fn_t) (void *); 33 34 /* Structure of control information passed by the NIC module to the OSI 35 * layer when sending control commands to Octeon device software. 36 */ 37 struct 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 OSI 67 * layer when forwarding data to Octeon device software. 68 */ 69 struct octnic_data_pkt { 70 /** Pointer to information maintained by NIC module for this packet. The 71 * 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 send 90 * network data to Octeon. 91 */ 92 union 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 112 static 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 118 static inline void 119 octnet_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 have 133 * irh and ossp[0], ossp[1] for a total of 32 bytes 134 */ 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 else 145 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 172 static inline void 173 octnet_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 have 189 * irh and ossp[1] and ossp[2] for a total of 24 bytes 190 */ 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 else 213 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 command 236 * @param cmd - pointer to instruction to be filled in. 237 * @param setup - pointer to the setup structure 238 * @param q_no - which queue for back pressure 239 * 240 * Assumes the cmd instruction is pre-allocated, but no fields are filled in. 241 */ 242 static inline void 243 octnet_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 else 249 octnet_prepare_pci_cmd_o3(oct, cmd, setup, tag); 250 } 251 252 /** Allocate and a soft command with space for a response immediately following 253 * the commnad. 254 * @param oct - octeon device pointer 255 * @param cmd - pointer to the command structure, pre-filled for everything 256 * except the response. 257 * @param rdatasize - size in bytes of the response. 258 * 259 * @returns pointer to allocated buffer with command copied into it, and 260 * response space immediately following. 261 */ 262 void * 263 octeon_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 device 268 * @param oct - octeon device pointer 269 * @param ndata - control structure with queueing, and buffer information 270 * 271 * @returns IQ_FAILED if it failed to add to the input queue. IQ_STOP if it the 272 * queue should be stopped, and IQ_SEND_OK if it sent okay. 273 */ 274 int 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 device 279 * @param oct - octeon device pointer 280 * @param nctrl - control structure with command, timout, and callback info 281 * @returns IQ_FAILED if it failed to add to the input queue. IQ_STOP if it the 282 * queue should be stopped, and IQ_SEND_OK if it sent okay. 283 */ 284 int 285 octnet_send_nic_ctrl_pkt(struct octeon_device *oct, 286 struct octnic_ctrl_pkt *nctrl); 287 288 #endif 289