cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

octeon_nic.h (8016B)


      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
     32typedef 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 */
     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 OSI
     67 * layer when forwarding data to Octeon device software.
     68 */
     69struct 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 */
     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 void
    119octnet_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
    172static inline void
    173octnet_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 */
    242static inline void
    243octnet_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 */
    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 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 */
    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 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 */
    284int
    285octnet_send_nic_ctrl_pkt(struct octeon_device *oct,
    286			 struct octnic_ctrl_pkt *nctrl);
    287
    288#endif