1/* 2 ************************************************************************** 3 * Copyright (c) 2014, The Linux Foundation. All rights reserved. 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all copies. 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 13 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 ************************************************************************** 15 */ 16 17#include "nss_data_plane.h" 18#include "nss_phys_if.h" 19#include "nss_core.h" 20#include "nss_tx_rx_common.h" 21#include <nss_gmac_api_if.h> 22 23#define NSS_DP_SUPPORTED_FEATURES NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_FRAGLIST | (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO) 24 25struct nss_data_plane_param nss_data_plane_params[NSS_MAX_PHYSICAL_INTERFACES]; 26 27/* 28 * nss_data_plane_open() 29 * Called by gmac to notify open to nss-fw 30 */ 31static int nss_data_plane_open(void *arg, uint32_t tx_desc_ring, uint32_t rx_desc_ring, uint32_t mode) 32{ 33 struct nss_data_plane_param *dp = (struct nss_data_plane_param *)arg; 34 35 if (dp->notify_open) { 36 return NSS_GMAC_SUCCESS; 37 } 38 if (nss_phys_if_open(dp->nss_ctx, tx_desc_ring, rx_desc_ring, mode, dp->if_num) == NSS_TX_SUCCESS) { 39 dp->notify_open = 1; 40 return NSS_GMAC_SUCCESS; 41 } 42 return NSS_GMAC_FAILURE; 43} 44 45/* 46 * nss_data_plane_close() 47 * Called by gmac to notify close to nss-fw 48 */ 49static int nss_data_plane_close(void *arg) 50{ 51 /* 52 * We don't actually do synopsys gmac close in fw, just return success 53 */ 54 return NSS_GMAC_SUCCESS; 55} 56 57/* 58 * nss_data_plane_link_state() 59 * Called by gmac to notify link state change to nss-fw 60 */ 61static int nss_data_plane_link_state(void *arg, uint32_t link_state) 62{ 63 struct nss_data_plane_param *dp = (struct nss_data_plane_param *)arg; 64 65 return nss_phys_if_link_state(dp->nss_ctx, link_state, dp->if_num); 66} 67 68/* 69 * nss_data_plane_mac_addr() 70 * Called by gmac to set mac address 71 */ 72static int nss_data_plane_mac_addr(void *arg, uint8_t *addr) 73{ 74 struct nss_data_plane_param *dp = (struct nss_data_plane_param *)arg; 75 76 return nss_phys_if_mac_addr(dp->nss_ctx, addr, dp->if_num); 77} 78 79/* 80 * nss_data_plane_change_mtu() 81 * Called by gmac to change mtu of a gmac 82 */ 83static int nss_data_plane_change_mtu(void *arg, uint32_t mtu) 84{ 85 struct nss_data_plane_param *dp = (struct nss_data_plane_param *)arg; 86 87 return nss_phys_if_change_mtu(dp->nss_ctx, mtu, dp->if_num); 88} 89 90/* 91 * nss_data_plane_buf() 92 * Called by gmac to pass a sk_buff for xmit 93 */ 94static int nss_data_plane_buf(void *arg, struct sk_buff *os_buf) 95{ 96 struct nss_data_plane_param *dp = (struct nss_data_plane_param *)arg; 97 98 return nss_phys_if_buf(dp->nss_ctx, os_buf, dp->if_num); 99} 100 101/* 102 * nss_data_plane_set_features() 103 * Called by gmac to allow data plane to modify the set of features it supports 104*/ 105static void nss_data_plane_set_features(struct net_device *netdev) 106{ 107 netdev->features |= NSS_DP_SUPPORTED_FEATURES; 108 netdev->hw_features |= NSS_DP_SUPPORTED_FEATURES; 109 netdev->vlan_features |= NSS_DP_SUPPORTED_FEATURES; 110 netdev->wanted_features |= NSS_DP_SUPPORTED_FEATURES; 111} 112 113/* 114 * nss offload data plane ops 115 */ 116static struct nss_gmac_data_plane_ops dp_ops = 117{ 118 .open = nss_data_plane_open, 119 .close = nss_data_plane_close, 120 .link_state = nss_data_plane_link_state, 121 .mac_addr = nss_data_plane_mac_addr, 122 .change_mtu = nss_data_plane_change_mtu, 123 .xmit = nss_data_plane_buf, 124 .set_features = nss_data_plane_set_features, 125}; 126 127/* 128 * nss_data_plane_set_enabled() 129 */ 130void nss_data_plane_set_enabled(int if_num) 131{ 132 nss_data_plane_params[if_num].enabled = 1; 133} 134 135/* 136 * nss_data_plane_register_to_nss_gmac() 137 */ 138bool nss_data_plane_register_to_nss_gmac(struct nss_ctx_instance *nss_ctx, int if_num) 139{ 140 struct nss_data_plane_param *ndpp = &nss_data_plane_params[if_num]; 141 struct nss_top_instance *nss_top = nss_ctx->nss_top; 142 struct net_device *netdev; 143 bool is_open; 144 145 if (!ndpp->enabled) { 146 return false; 147 } 148 149 netdev = nss_gmac_get_netdev_by_macid(if_num); 150 if (!netdev) { 151 nss_info("Platform don't have gmac%d enabled, don't bring up nss_phys_if and don't register to nss-gmac", if_num); 152 return false; 153 } 154 155 is_open = nss_gmac_is_in_open_state(netdev); 156 ndpp->dev = netdev; 157 ndpp->nss_ctx = nss_ctx; 158 ndpp->if_num = if_num; 159 ndpp->notify_open = 0; 160 ndpp->features = 0; 161 162 if (nss_gmac_override_data_plane(netdev, &dp_ops, ndpp) != NSS_GMAC_SUCCESS) { 163 nss_info("Override nss-gmac data plane failed\n"); 164 return false; 165 } 166 167 /* 168 * Setup the receive callback so that data pkts received form NSS-FW will 169 * be redirected to the gmac driver as we are overriding the data plane 170 */ 171 nss_top->phys_if_handler_id[if_num] = nss_ctx->id; 172 nss_phys_if_register_handler(if_num); 173 174 nss_top->subsys_dp_register[if_num].ndev = netdev; 175 nss_top->subsys_dp_register[if_num].cb = nss_gmac_receive; 176 nss_top->subsys_dp_register[if_num].app_data = NULL; 177 nss_top->subsys_dp_register[if_num].features = ndpp->features; 178 179 /* 180 * Now we are registered and our side is ready, if the gmac was opened, ask it to start again 181 */ 182 if (is_open) { 183 nss_gmac_start_data_plane(netdev, ndpp); 184 } 185 return true; 186} 187 188/* 189 * nss_data_plane_unregister_from_nss_gmac() 190 */ 191void nss_data_plane_unregister_from_nss_gmac(int if_num) 192{ 193 nss_gmac_restore_data_plane(nss_data_plane_params[if_num].dev); 194 nss_data_plane_params[if_num].dev = NULL; 195 nss_data_plane_params[if_num].nss_ctx = NULL; 196 nss_data_plane_params[if_num].if_num = 0; 197 nss_data_plane_params[if_num].notify_open = 0; 198 nss_data_plane_params[if_num].enabled = 0; 199} 200