/* * IMG SPFI controller driver * * Copyright (C) 2007,2008,2013 Imagination Technologies Ltd. * Copyright (C) 2014 Google, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SPFI_DEVICE_PARAMETER(x) (0x00 + 0x4 * (x)) #define SPFI_DEVICE_PARAMETER_BITCLK_SHIFT 24 #define SPFI_DEVICE_PARAMETER_BITCLK_MASK 0xff #define SPFI_DEVICE_PARAMETER_CSSETUP_SHIFT 16 #define SPFI_DEVICE_PARAMETER_CSSETUP_MASK 0xff #define SPFI_DEVICE_PARAMETER_CSHOLD_SHIFT 8 #define SPFI_DEVICE_PARAMETER_CSHOLD_MASK 0xff #define SPFI_DEVICE_PARAMETER_CSDELAY_SHIFT 0 #define SPFI_DEVICE_PARAMETER_CSDELAY_MASK 0xff #define SPFI_CONTROL 0x14 #define SPFI_CONTROL_CONTINUE BIT(12) #define SPFI_CONTROL_SOFT_RESET BIT(11) #define SPFI_CONTROL_SEND_DMA BIT(10) #define SPFI_CONTROL_GET_DMA BIT(9) #define SPFI_CONTROL_SE BIT(8) #define SPFI_CONTROL_TMODE_SHIFT 5 #define SPFI_CONTROL_TMODE_MASK 0x7 #define SPFI_CONTROL_TMODE_SINGLE 0 #define SPFI_CONTROL_TMODE_DUAL 1 #define SPFI_CONTROL_TMODE_QUAD 2 #define SPFI_CONTROL_SPFI_EN BIT(0) #define SPFI_TRANSACTION 0x18 #define SPFI_TRANSACTION_TSIZE_SHIFT 16 #define SPFI_TRANSACTION_TSIZE_MASK 0xffff #define SPFI_PORT_STATE 0x1c #define SPFI_PORT_STATE_DEV_SEL_SHIFT 20 #define SPFI_PORT_STATE_DEV_SEL_MASK 0x7 #define SPFI_PORT_STATE_CK_POL(x) BIT(19 - (x)) #define SPFI_PORT_STATE_CK_PHASE(x) BIT(14 - (x)) #define SPFI_TX_32BIT_VALID_DATA 0x20 #define SPFI_TX_8BIT_VALID_DATA 0x24 #define SPFI_RX_32BIT_VALID_DATA 0x28 #define SPFI_RX_8BIT_VALID_DATA 0x2c #define SPFI_INTERRUPT_STATUS 0x30 #define SPFI_INTERRUPT_ENABLE 0x34 #define SPFI_INTERRUPT_CLEAR 0x38 #define SPFI_INTERRUPT_IACCESS BIT(12) #define SPFI_INTERRUPT_GDEX8BIT BIT(11) #define SPFI_INTERRUPT_ALLDONETRIG BIT(9) #define SPFI_INTERRUPT_GDFUL BIT(8) #define SPFI_INTERRUPT_GDHF BIT(7) #define SPFI_INTERRUPT_GDEX32BIT BIT(6) #define SPFI_INTERRUPT_GDTRIG BIT(5) #define SPFI_INTERRUPT_SDFUL BIT(3) #define SPFI_INTERRUPT_SDHF BIT(2) #define SPFI_INTERRUPT_SDE BIT(1) #define SPFI_INTERRUPT_SDTRIG BIT(0) /* * There are four parallel FIFOs of 16 bytes each. The word buffer * (*_32BIT_VALID_DATA) accesses all four FIFOs at once, resulting in an * effective FIFO size of 64 bytes. The byte buffer (*_8BIT_VALID_DATA) * accesses only a single FIFO, resulting in an effective FIFO size of * 16 bytes. */ #define SPFI_32BIT_FIFO_SIZE 64 #define SPFI_8BIT_FIFO_SIZE 16 struct img_spfi { struct device *dev; struct spi_master *master; spinlock_t lock; void __iomem *regs; phys_addr_t phys; int irq; struct clk *spfi_clk; struct clk *sys_clk; struct dma_chan *rx_ch; struct dma_chan *tx_ch; bool tx_dma_busy; bool rx_dma_busy; }; struct img_spfi_device_data { bool gpio_requested; }; static inline u32 spfi_readl(struct img_spfi *spfi, u32 reg) { return readl(spfi->regs + reg); } static inline void spfi_writel(struct img_spfi *spfi, u32 val, u32 reg) { writel(val, spfi->regs + reg); } static inline void spfi_start(struct img_spfi *spfi) { u32 val; val = spfi_readl(spfi, SPFI_CONTROL); val |= SPFI_CONTROL_SPFI_EN; spfi_writel(spfi, val, SPFI_CONTROL); } static inline void spfi_reset(struct img_spfi *spfi) { spfi_writel(spfi, SPFI_CONTROL_SOFT_RESET, SPFI_CONTROL); spfi_writel(spfi, 0, SPFI_CONTROL); } static int spfi_wait_all_done(struct img_spfi *spfi) { unsigned long timeout = jiffies + msecs_to_jiffies(50); while (time_before(jiffies, timeout)) { u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); if (status & SPFI_INTERRUPT_ALLDONETRIG) { spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG, SPFI_INTERRUPT_CLEAR); return 0; } cpu_relax(); } dev_err(spfi->dev, "Timed out waiting for transaction to complete\n"); spfi_reset(spfi); return -ETIMEDOUT; } static unsigned int spfi_pio_write32(struct img_spfi *spfi, const u32 *buf, unsigned int max) { unsigned int count = 0; u32 status; while (count < max / 4) { spfi_writel(spfi, SPFI_INTERRUPT_SDFUL, SPFI_INTERRUPT_CLEAR); status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); if (status & SPFI_INTERRUPT_SDFUL) break; spfi_writel(spfi, buf[count], SPFI_TX_32BIT_VALID_DATA); count++; } return count * 4; } static unsigned int spfi_pio_write8(struct img_spfi *spfi, const u8 *buf, unsigned int max) { unsigned int count = 0; u32 status; while (count < max) { spfi_writel(spfi, SPFI_INTERRUPT_SDFUL, SPFI_INTERRUPT_CLEAR); status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); if (status & SPFI_INTERRUPT_SDFUL) break; spfi_writel(spfi, buf[count], SPFI_TX_8BIT_VALID_DATA); count++; } return count; } static unsigned int spfi_pio_read32(struct img_spfi *spfi, u32 *buf, unsigned int max) { unsigned int count = 0; u32 status; while (count < max / 4) { spfi_writel(spfi, SPFI_INTERRUPT_GDEX32BIT, SPFI_INTERRUPT_CLEAR); status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); if (!(status & SPFI_INTERRUPT_GDEX32BIT)) break; buf[count] = spfi_readl(spfi, SPFI_RX_32BIT_VALID_DATA); count++; } return count * 4; } static unsigned int spfi_pio_read8(struct img_spfi *spfi, u8 *buf, unsigned int max) { unsigned int count = 0; u32 status; while (count < max) { spfi_writel(spfi, SPFI_INTERRUPT_GDEX8BIT, SPFI_INTERRUPT_CLEAR); status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); if (!(status & SPFI_INTERRUPT_GDEX8BIT)) break; buf[count] = spfi_readl(spfi, SPFI_RX_8BIT_VALID_DATA); count++; } return count; } static int img_spfi_start_pio(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) { struct img_spfi *spfi = spi_master_get_devdata(spi->master); unsigned int tx_bytes = 0, rx_bytes = 0; const void *tx_buf = xfer->tx_buf; void *rx_buf = xfer->rx_buf; unsigned long timeout; int ret; if (tx_buf) tx_bytes = xfer->len; if (rx_buf) rx_bytes = xfer->len; spfi_start(spfi); timeout = jiffies + msecs_to_jiffies(xfer->len * 8 * 1000 / xfer->speed_hz + 100); while ((tx_bytes > 0 || rx_bytes > 0) && time_before(jiffies, timeout)) { unsigned int tx_count, rx_count; if (tx_bytes >= 4) tx_count = spfi_pio_write32(spfi, tx_buf, tx_by
# Copyright 2017 Nokia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# VSPERF specific configuration file for execution of RFC2544 throughput
# traffic. Traffic executed by traffic generator is forwarded directly
# between interfaces connected to the traffic generator. So test will only
# benchmark the performance of OVS external bridge at controller node.
# Details about supported test options and test case execution can be
# found in VSPERF documentation:
#
#   http://artifacts.opnfv.org/vswitchperf/docs/userguide/yardstick.html

schema: "yardstick:task:0.1"

scenarios:
{% for multistream in [1, 1000] %}
-
  type: VsperfDPDK
  options:
    testname: 'pvp_tput'
    traffic_type: 'rfc2544_throughput'
    multistream: {{multistream}} 
    frame_size: 64
    test_params: 'TRAFFICGEN_DURATION=60;'
    trafficgen_port1: 'ens4'
    trafficgen_port2: 'ens5'
    conf_file: '~/vsperf-yardstick.conf'
    moongen_helper_file: '~/moongen.py'
    moongen_host_ip: '10.5.201.151'
    moongen_port1_mac: '8c:dc:d4:ae:7c:5c'
    moongen_port2_mac: '8c:dc:d4:ae:7c:5d'
    trafficgen_port1_nw: 'test2'
    trafficgen_port2_nw: 'test3'

  host: vsperf.demo

  runner:
    type: Sequence
    scenario_option_name: frame_size
    sequence:
    - 64
    - 128
    - 256
    - 512
    - 1024
    - 1280
    - 1518

  sla:
    # The throughput SLA (or any other SLA) cannot be set to a meaningful
    # value without knowledge of the server and networking environment,
    # possibly including prior testing in that environment to establish
    # a baseline SLA level under well-understood circumstances.
    metrics: 'throughput_rx_fps'
    throughput_rx_fps: 500000
    action: monitor
{% endfor %}

context:
  name: demo
  image: yardstick-vsperf-server
  flavor: vsperf-flavor
  user: ubuntu

  placement_groups:
    pgrp1:
      policy: "availability"

  servers:
    vsperf:
      floating_ip: true
      placement: "pgrp1"

  networks:
    test:
      cidr: '10.0.1.0/24'
    test2:
      cidr: '10.0.2.0/24'
    test3:
      cidr: '10.0.3.0/24'