bcm-knet.c (289076B)
1 /* 2 * Copyright 2017 Broadcom 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License, version 2, as 6 * published by the Free Software Foundation (the "GPL"). 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License version 2 (GPLv2) for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * version 2 (GPLv2) along with this source code. 15 */ 16 /* 17 * $Id: bcm-knet.c,v 1.90 Broadcom SDK $ 18 * $Copyright: (c) 2005 Broadcom Corp. 19 * All Rights Reserved.$ 20 */ 21 22 /* 23 * This module implements a Linux network driver for Broadcom 24 * XGS switch devices. The driver simultaneously serves a 25 * number of vitual Linux network devices and a Tx/Rx API 26 * implemented in user space. 27 * 28 * Packets received from the switch device are sent to either 29 * a virtual Linux network device or the user mode Rx API 30 * based on a set of packet filters.susp 31 * 32 * Packets from the virtual Linux network devices and the user 33 * mode Tx API are multiplexed with priority given to the Tx API. 34 * 35 * A message-based IOCTL interface is used for managing packet 36 * filters and virtual Linux network interfaces. 37 * 38 * A virtual network interface can be configured to work in RCPU 39 * mode, which means that packets from the switch device will 40 * be encasulated with a RCPU header and a block of meta data 41 * that basically contains the core DCB information. Likewise, 42 * packets received from the Linux network stack are assumed to 43 * be RCPU encapsulated when going out on an interface in RCPU 44 * mode. 45 * 46 * The module implements basic Rx DMA rate control. The rate is 47 * specified in packets per second, and different Rx DMA channels 48 * can be configured to use different maximum packet rates. 49 * The packet rate can be configure as a module parameter, and 50 * it can also be changed dynamically through the proc file 51 * system (syntax is described in function header comment). 52 * 53 * To support multiple instance, each instance has its event queue. 54 * 55 * To support pci hot-plug in this module, the resource update 56 * should be handled when the PCI device is re-plugged. 57 * NOTE: the KNET detach should be invoked befere removing the 58 * device. 59 * 60 * For a list of supported module parameters, please see below. 61 */ 62 63 #include <gmodule.h> /* Must be included first */ 64 #include <linux-bde.h> 65 #include <kcom.h> 66 #include <bcm-knet.h> 67 68 #include <linux/netdevice.h> 69 #include <linux/etherdevice.h> 70 #include <linux/ethtool.h> 71 #include <linux/random.h> 72 #include <linux/seq_file.h> 73 #include <linux/if_vlan.h> 74 75 76 MODULE_AUTHOR("Broadcom Corporation"); 77 MODULE_DESCRIPTION("Network Device Driver for Broadcom BCM TxRx API"); 78 MODULE_LICENSE("GPL"); 79 80 static int debug; 81 LKM_MOD_PARAM(debug, "i", int, 0); 82 MODULE_PARM_DESC(debug, 83 "Debug level (default 0)"); 84 85 static char *mac_addr = NULL; 86 LKM_MOD_PARAM(mac_addr, "s", charp, 0); 87 MODULE_PARM_DESC(mac_addr, 88 "Ethernet MAC address (default 02:10:18:xx:xx:xx)"); 89 90 static int rx_buffer_size = 9216; 91 LKM_MOD_PARAM(rx_buffer_size, "i", int, 0); 92 MODULE_PARM_DESC(rx_buffer_size, 93 "Size of RX packet buffers (default 9216)"); 94 95 static int default_mtu = 1500; 96 LKM_MOD_PARAM(default_mtu, "i", int, 0); 97 MODULE_PARM_DESC(default_mtu, 98 "Default MTU for KNET network interfaces (default 1500)"); 99 100 static int rx_sync_retry = 1000; 101 LKM_MOD_PARAM(rx_sync_retry, "i", int, 0); 102 MODULE_PARM_DESC(rx_sync_retry, 103 "Retries if chain is incomplete on interrupt (default 10)"); 104 105 static char *base_dev_name = NULL; 106 LKM_MOD_PARAM(base_dev_name, "s", charp, 0); 107 MODULE_PARM_DESC(base_dev_name, 108 "Base device name (default bcm0, bcm1, etc.)"); 109 110 static int rcpu_mode = 0; 111 LKM_MOD_PARAM(rcpu_mode, "i", int, 0); 112 MODULE_PARM_DESC(rcpu_mode, 113 "Enable RCPU encapsulation (default 0)"); 114 115 static char *rcpu_dmac = NULL; 116 LKM_MOD_PARAM(rcpu_dmac, "s", charp, 0); 117 MODULE_PARM_DESC(rcpu_dmac, 118 "RCPU destination MAC address (by default use L2 destination MAC address)"); 119 120 static char *rcpu_smac = NULL; 121 LKM_MOD_PARAM(rcpu_smac, "s", charp, 0); 122 MODULE_PARM_DESC(rcpu_smac, 123 "RCPU source MAC address (by default use L2 source MAC address)"); 124 125 static int rcpu_ethertype = 0xde08; 126 LKM_MOD_PARAM(rcpu_ethertype, "i", int, 0); 127 MODULE_PARM_DESC(rcpu_ethertype, 128 "RCPU EtherType (default DE08h)"); 129 130 static int rcpu_signature = 0; 131 LKM_MOD_PARAM(rcpu_signature, "i", int, 0); 132 MODULE_PARM_DESC(rcpu_signature, 133 "RCPU Signature (default is PCI device ID)"); 134 135 static int rcpu_vlan = 1; 136 LKM_MOD_PARAM(rcpu_vlan, "i", int, 0); 137 MODULE_PARM_DESC(rcpu_vlan, 138 "RCPU VLAN ID (default 1)"); 139 140 static int use_rx_skb = 0; 141 LKM_MOD_PARAM(use_rx_skb, "i", int, 0); 142 MODULE_PARM_DESC(use_rx_skb, 143 "Use socket buffers for receive operation (default 0)"); 144 145 static int num_rx_prio = 1; 146 LKM_MOD_PARAM(num_rx_prio, "i", int, 0); 147 MODULE_PARM_DESC(num_rx_prio, 148 "Number of filter priorities per Rx DMA channel"); 149 150 static int rx_rate[8] = { 100000, 100000, 100000, 100000, 100000, 100000, 100000, 0 }; 151 LKM_MOD_PARAM_ARRAY(rx_rate, "1-4i", int, NULL, 0); 152 MODULE_PARM_DESC(rx_rate, 153 "Rx rate in packets per second (default 100000)"); 154 155 static int rx_burst[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 156 LKM_MOD_PARAM_ARRAY(rx_burst, "1-4i", int, NULL, 0); 157 MODULE_PARM_DESC(rx_burst, 158 "Rx rate burst maximum in packets (default rx_rate/10)"); 159 160 static int check_rcpu_signature = 0; 161 LKM_MOD_PARAM(check_rcpu_signature, "i", int, 0); 162 MODULE_PARM_DESC(check_rcpu_signature, 163 "Check RCPU Signature for Tx packets from RCPU interfaces"); 164 165 static int basedev_suspend = 0; 166 LKM_MOD_PARAM(basedev_suspend, "i", int, 0); 167 MODULE_PARM_DESC(basedev_suspend, 168 "Pause traffic till base device is up (enabled by default in NAPI mode)"); 169 170 /* Debug levels */ 171 #define DBG_LVL_VERB 0x1 172 #define DBG_LVL_DCB 0x2 173 #define DBG_LVL_PKT 0x4 174 #define DBG_LVL_SKB 0x8 175 #define DBG_LVL_CMD 0x10 176 #define DBG_LVL_EVT 0x20 177 #define DBG_LVL_IRQ 0x40 178 #define DBG_LVL_NAPI 0x80 179 #define DBG_LVL_PDMP 0x100 180 #define DBG_LVL_FLTR 0x200 181 #define DBG_LVL_KCOM 0x400 182 #define DBG_LVL_RCPU 0x800 183 #define DBG_LVL_WARN 0x1000 184 #define DBG_LVL_NDEV 0x2000 185 #define DBG_LVL_INST 0x4000 186 /* Level to output Dune internal headers Parsing */ 187 #define DBG_LVL_DUNE 0x8000 188 #define DBG_LVL_DCB_TX 0x10000 189 #define DBG_LVL_DCB_RX 0x20000 190 #define DBG_LVL_PDMP_TX 0x40000 191 #define DBG_LVL_PDMP_RX 0x80000 192 193 #define DBG_VERB(_s) do { if (debug & DBG_LVL_VERB) gprintk _s; } while (0) 194 #define DBG_PKT(_s) do { if (debug & DBG_LVL_PKT) gprintk _s; } while (0) 195 #define DBG_SKB(_s) do { if (debug & DBG_LVL_SKB) gprintk _s; } while (0) 196 #define DBG_CMD(_s) do { if (debug & DBG_LVL_CMD) gprintk _s; } while (0) 197 #define DBG_EVT(_s) do { if (debug & DBG_LVL_EVT) gprintk _s; } while (0) 198 #define DBG_IRQ(_s) do { if (debug & DBG_LVL_IRQ) gprintk _s; } while (0) 199 #define DBG_NAPI(_s) do { if (debug & DBG_LVL_NAPI) gprintk _s; } while (0) 200 #define DBG_PDMP(_s) do { if (debug & DBG_LVL_PDMP) gprintk _s; } while (0) 201 #define DBG_FLTR(_s) do { if (debug & DBG_LVL_FLTR) gprintk _s; } while (0) 202 #define DBG_KCOM(_s) do { if (debug & DBG_LVL_KCOM) gprintk _s; } while (0) 203 #define DBG_RCPU(_s) do { if (debug & DBG_LVL_RCPU) gprintk _s; } while (0) 204 #define DBG_WARN(_s) do { if (debug & DBG_LVL_WARN) gprintk _s; } while (0) 205 #define DBG_NDEV(_s) do { if (debug & DBG_LVL_NDEV) gprintk _s; } while (0) 206 #define DBG_INST(_s) do { if (debug & DBG_LVL_INST) gprintk _s; } while (0) 207 #define DBG_DUNE(_s) do { if (debug & DBG_LVL_DUNE) gprintk _s; } while (0) 208 #define DBG_DCB_TX(_s) do { if (debug & (DBG_LVL_DCB|DBG_LVL_DCB_TX)) \ 209 gprintk _s; } while (0) 210 #define DBG_DCB_RX(_s) do { if (debug & (DBG_LVL_DCB|DBG_LVL_DCB_RX)) \ 211 gprintk _s; } while (0) 212 #define DBG_DCB(_s) do { if (debug & (DBG_LVL_DCB|DBG_LVL_DCB_TX| \ 213 DBG_LVL_DCB_RX)) \ 214 gprintk _s; } while (0) 215 216 217 /* This flag is used to indicate if debugging packet function is open or closed */ 218 static int dbg_pkt_enable = 0; 219 220 /* Module Information */ 221 #define MODULE_MAJOR 122 222 #define MODULE_NAME "linux-bcm-knet" 223 224 #ifndef NAPI_SUPPORT 225 #define NAPI_SUPPORT 1 226 #endif 227 228 #if NAPI_SUPPORT 229 230 static int use_napi = 0; 231 LKM_MOD_PARAM(use_napi, "i", int, 0); 232 MODULE_PARM_DESC(use_napi, 233 "Use NAPI interface (default 0)"); 234 235 static int napi_weight = 64; 236 LKM_MOD_PARAM(napi_weight, "i", int, 0); 237 MODULE_PARM_DESC(napi_weight, 238 "Weight of NAPI interfaces (default 64)"); 239 240 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 241 #define bkn_napi_enable(_dev, _napi) netif_poll_enable(_dev) 242 #define bkn_napi_disable(_dev, _napi) netif_poll_disable(_dev) 243 #define bkn_napi_schedule(_dev, _napi) netif_rx_schedule(_dev) 244 #define bkn_napi_schedule_prep(_dev, _napi) netif_rx_schedule_prep(_dev) 245 #define __bkn_napi_schedule(_dev, _napi) __netif_rx_schedule(_dev) 246 #define bkn_napi_complete(_dev, _napi) netif_rx_complete(_dev) 247 #else 248 #define bkn_napi_enable(_dev, _napi) napi_enable(_napi) 249 #define bkn_napi_disable(_dev, _napi) napi_disable(_napi) 250 #define bkn_napi_schedule(_dev, _napi) napi_schedule(_napi) 251 #define bkn_napi_schedule_prep(_dev, _napi) napi_schedule_prep(_napi) 252 #define __bkn_napi_schedule(_dev, _napi) __napi_schedule(_napi) 253 #define bkn_napi_complete(_dev, _napi) napi_complete(_napi) 254 #endif 255 256 #else 257 258 static int use_napi = 0; 259 static int napi_weight = 0; 260 261 #define bkn_napi_enable(_dev, _napi) 262 #define bkn_napi_disable(_dev, _napi) 263 #define bkn_napi_schedule(_dev, _napi) 264 #define bkn_napi_schedule_prep(_dev, _napi) (0) 265 #define __bkn_napi_schedule(_dev, _napi) 266 #define bkn_napi_complete(_dev, _napi) 267 268 #endif 269 270 /* 271 * If proxy support is compiled in the module will attempt to use 272 * the user/kernel message service provided by the linux-uk-proxy 273 * kernel module, otherwise device IOCTL will be used. 274 */ 275 #ifndef PROXY_SUPPORT 276 #define PROXY_SUPPORT 0 277 #endif 278 279 #if PROXY_SUPPORT 280 281 #include <linux-uk-proxy.h> 282 283 static int use_proxy = 1; 284 LKM_MOD_PARAM(use_proxy, "i", int, 0); 285 MODULE_PARM_DESC(use_proxy, 286 "Use Linux User/Kernel proxy (default 1)"); 287 288 #define PROXY_SERVICE_CREATE(_s,_q,_f) linux_uk_proxy_service_create(_s,_q,_f) 289 #define PROXY_SERVICE_DESTROY(_s) linux_uk_proxy_service_destroy(_s); 290 #define PROXY_SEND(_s,_m,_l) linux_uk_proxy_send(_s,_m,_l) 291 #define PROXY_RECV(_s,_m,_l) linux_uk_proxy_recv(_s,_m,_l) 292 293 #else 294 295 static int use_proxy = 0; 296 297 #define PROXY_SERVICE_CREATE(_s,_q,_f) 298 #define PROXY_SERVICE_DESTROY(_s) 299 #define PROXY_SEND(_s,_m,_l) 300 #define PROXY_RECV(_s,_m,_l) (-1) 301 302 #endif 303 304 /* Compatibility */ 305 306 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)) 307 #define NETDEV_UPDATE_TRANS_START_TIME(dev) dev->trans_start = jiffies 308 #else 309 #define NETDEV_UPDATE_TRANS_START_TIME(dev) netif_trans_update(dev) 310 #endif 311 312 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) 313 #define skb_copy_to_linear_data(_skb, _pkt, _len) \ 314 eth_copy_and_sum(_skb, _pkt, _len, 0) 315 struct napi_struct { int not_used; }; 316 #define netif_napi_add(_dev, _napi, _poll, _weight) do { \ 317 (_dev)->poll = _poll; \ 318 (_dev)->weight = _weight; \ 319 } while(0) 320 #endif 321 322 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) 323 #define SKB_PADTO(_skb,_len) (((_skb = skb_padto(_skb,_len)) == NULL) ? -1 : 0) 324 #else 325 #define SKB_PADTO(_skb,_len) skb_padto(_skb,_len) 326 #endif 327 328 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)) 329 #define skb_header_cloned(_skb) \ 330 skb_cloned(_skb) 331 #endif 332 333 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) 334 static inline void *netdev_priv(struct net_device *dev) 335 { 336 return dev->priv; 337 } 338 #endif /* KERNEL_VERSION(2,4,27) */ 339 340 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) 341 /* Special check for MontaVista 2.4.20 MIPS */ 342 #if !(defined(MAX_USER_RT_PRIO) && defined(CONFIG_MIPS)) 343 static inline void free_netdev(struct net_device *dev) 344 { 345 kfree(dev); 346 } 347 #endif 348 static inline void netif_poll_disable(struct net_device *dev) 349 { 350 while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) { 351 /* No hurry. */ 352 current->state = TASK_INTERRUPTIBLE; 353 schedule_timeout(1); 354 } 355 } 356 static inline void netif_poll_enable(struct net_device *dev) 357 { 358 clear_bit(__LINK_STATE_RX_SCHED, &dev->state); 359 } 360 #endif /* KERNEL_VERSION(2,4,23) */ 361 362 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,21) 363 static struct sk_buff *skb_pad(struct sk_buff *skb, int pad) 364 { 365 struct sk_buff *nskb; 366 367 /* If the skbuff is non linear tailroom is always zero.. */ 368 if(skb_tailroom(skb) >= pad) 369 { 370 memset(skb->data+skb->len, 0, pad); 371 return skb; 372 } 373 374 nskb = skb_copy_expand(skb, skb_headroom(skb), skb_tailroom(skb) + pad, GFP_ATOMIC); 375 kfree_skb(skb); 376 if(nskb) 377 memset(nskb->data+nskb->len, 0, pad); 378 return nskb; 379 } 380 static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) 381 { 382 unsigned int size = skb->len; 383 if(likely(size >= len)) 384 return skb; 385 return skb_pad(skb, len-size); 386 } 387 #endif /* KERNEL_VERSION(2,4,21) */ 388 389 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) 390 #define bkn_vlan_hwaccel_put_tag(_skb, _proto, _tci) \ 391 __vlan_hwaccel_put_tag(_skb, _tci) 392 #else 393 #define bkn_vlan_hwaccel_put_tag(_skb, _proto, _tci) \ 394 __vlan_hwaccel_put_tag(_skb, htons(_proto), _tci) 395 #endif 396 397 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 398 #define bkn_dma_mapping_error(d, a) \ 399 dma_mapping_error(a) 400 #define bkn_pci_dma_mapping_error(d, a) \ 401 pci_dma_mapping_error(a) 402 #else 403 #define bkn_dma_mapping_error(d, a) \ 404 dma_mapping_error(d, a) 405 #define bkn_pci_dma_mapping_error(d, a) \ 406 pci_dma_mapping_error(d, a) 407 #endif 408 409 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) 410 enum { 411 SKBTX_HW_TSTAMP = 1 << 0, 412 SKBTX_SW_TSTAMP = 1 << 1, 413 SKBTX_IN_PROGRESS = 1 << 2, 414 }; 415 struct skb_shared_hwtstamps { 416 ktime_t hwtstamp; 417 ktime_t syststamp; 418 }; 419 struct bkn_skb_shared_info { 420 uint8_t tx_flags; 421 struct skb_shared_hwtstamps hwtstamps; 422 }; 423 #define bkn_skb_shinfo(_skb) ((struct bkn_skb_shared_info *)(unsigned char *)_skb->end) 424 #define bkn_skb_tx_flags(_skb) bkn_skb_shinfo(_skb)->tx_flags 425 static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb) 426 { 427 return &bkn_skb_shinfo(skb)->hwtstamps; 428 } 429 void skb_tstamp_tx(struct sk_buff *orig_skb, struct skb_shared_hwtstamps *hwtstamps) 430 { 431 } 432 static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) 433 { 434 } 435 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) 436 static inline ktime_t ns_to_ktime(u64 ns) 437 { 438 static const ktime_t ktime; 439 return ktime; 440 } 441 #endif 442 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) 443 #include <linux/net_tstamp.h> 444 enum { 445 SKBTX_HW_TSTAMP = 1 << 0, 446 SKBTX_SW_TSTAMP = 1 << 1, 447 SKBTX_IN_PROGRESS = 1 << 2, 448 }; 449 #define bkn_skb_tx_flags(_skb) skb_shinfo(_skb)->tx_flags.flags 450 static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) 451 { 452 } 453 #else 454 #include <linux/net_tstamp.h> 455 #define bkn_skb_tx_flags(_skb) skb_shinfo(_skb)->tx_flags 456 static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) 457 { 458 return skb_tx_timestamp(skb); 459 } 460 #endif 461 462 #ifdef LINUX_BDE_DMA_DEVICE_SUPPORT 463 #define DMA_DEV device 464 #define DMA_FROMDEV DMA_FROM_DEVICE 465 #define DMA_TODEV DMA_TO_DEVICE 466 #define DMA_MAP_SINGLE(d,p,s,r) dma_map_single(d,p,s,r) 467 #define DMA_UNMAP_SINGLE(d,a,s,r) dma_unmap_single(d,a,s,r) 468 #define DMA_ALLOC_COHERENT(d,s,h) dma_alloc_coherent(d,s,h,GFP_ATOMIC|GFP_DMA32) 469 #define DMA_FREE_COHERENT(d,s,a,h) dma_free_coherent(d,s,a,h) 470 #define DMA_MAPPING_ERROR(d,a) bkn_dma_mapping_error(d,a) 471 #else 472 #define DMA_DEV pci_dev 473 #define DMA_FROMDEV PCI_DMA_FROMDEVICE 474 #define DMA_TODEV PCI_DMA_TODEVICE 475 #define DMA_MAP_SINGLE(d,p,s,r) pci_map_single(d,p,s,r) 476 #define DMA_UNMAP_SINGLE(d,a,s,r) pci_unmap_single(d,a,s,r) 477 #define DMA_ALLOC_COHERENT(d,s,h) pci_alloc_consistent(d,s,h) 478 #define DMA_FREE_COHERENT(d,s,a,h) pci_free_consistent(d,s,a,h) 479 #define DMA_MAPPING_ERROR(d,a) bkn_pci_dma_mapping_error(d,a) 480 #endif 481 482 /* RCPU operations */ 483 #define RCPU_OPCODE_RX 0x10 484 #define RCPU_OPCODE_TX 0x20 485 486 /* RCPU flags */ 487 #define RCPU_F_MODHDR 0x4 488 489 /* RCPU encapsulation */ 490 #define RCPU_HDR_SIZE 32 491 #define RCPU_TX_META_SIZE 32 492 #define RCPU_TX_ENCAP_SIZE (RCPU_HDR_SIZE + RCPU_TX_META_SIZE) 493 #define RCPU_RX_META_SIZE 64 494 #define RCPU_RX_ENCAP_SIZE (RCPU_HDR_SIZE + RCPU_RX_META_SIZE) 495 496 #define PKT_TX_HDR_SIZE 16 497 498 static volatile int module_initialized; 499 500 static ibde_t *kernel_bde = NULL; 501 502 /* Descriptor info */ 503 typedef struct bkn_desc_info_s { 504 uint32_t *dcb_mem; 505 uint64_t dcb_dma; 506 struct sk_buff *skb; 507 uint64_t skb_dma; 508 uint32_t dma_size; 509 } bkn_desc_info_t; 510 511 /* DCB chain info */ 512 typedef struct bkn_dcb_chain_s { 513 struct list_head list; 514 int dcb_cnt; 515 int dcb_cur; 516 uint32_t *dcb_mem; 517 uint64_t dcb_dma; 518 } bkn_dcb_chain_t; 519 520 #define MAX_TX_DCBS 64 521 #define MAX_RX_DCBS 64 522 523 #define NUM_DMA_CHAN 8 524 #define NUM_RX_CHAN 7 525 #define NUM_CMICX_RX_CHAN 7 526 #define NUM_CMICM_RX_CHAN 3 527 528 #define FCS_SZ 4 529 #define TAG_SZ 4 530 531 /* Device control info */ 532 typedef struct bkn_switch_info_s { 533 struct list_head list; 534 struct list_head ndev_list; /* Associated virtual Ethernet interfaces */ 535 struct net_device **ndevs; /* Indexed array of ndev_list */ 536 int ndev_max; /* Size of indexed array */ 537 struct list_head rxpf_list; /* Associated Rx packet filters */ 538 volatile void *base_addr; /* Base address for PCI register access */ 539 struct DMA_DEV *dma_dev; /* Required for DMA memory control */ 540 struct pci_dev *pdev; /* Required for DMA memory control */ 541 struct net_device *dev; /* Base network device */ 542 struct napi_struct napi; /* New NAPI */ 543 struct timer_list timer; /* Retry/resource timer */ 544 int timer_queued; /* Flag indicating queued timer function */ 545 uint32_t timer_runs; /* Timer function runs (debug only) */ 546 struct timer_list rxtick; /* Rx rate control timer */ 547 uint32_t rxticks_per_sec; /* Rx rate control update frequency */ 548 uint32_t rxtick_jiffies; /* Time between updates (in jiffies) */ 549 uint32_t rxticks; /* Rx rate control debug counter */ 550 uint32_t interrupts; /* Total number of interrupts */ 551 spinlock_t lock; /* Main lock for device */ 552 int dev_no; /* Device number (from BDE) */ 553 int cpu_no; /* Cpu number. 1 for iHost(AXI),0 for others */ 554 int dcb_type; /* DCB type */ 555 int dcb_wsize; /* DCB size (in 32-bit words) */ 556 int pkt_hdr_size; /* Packet header size */ 557 uint32_t ftmh_lb_key_ext_size; /* FTMH LB-Key Extension existence/size */ 558 uint32_t ftmh_stacking_ext_size; /* FTMH Stacking extension existence/size */ 559 uint32_t pph_base_size; /* Size of PPH base */ 560 uint32_t pph_lif_ext_size[8]; /* Size of PPH Lif extension header */ 561 uint8_t udh_enable; /* Indicates UDH existence */ 562 uint32_t udh_length_type[4]; /* Size of UDH header per type */ 563 int rx_chans; /* Number of Rx channels */ 564 uint32_t dma_hi; /* DMA higher address */ 565 uint32_t cmic_type; /* CMIC type (CMICe or CMICm) */ 566 uint32_t irq_mask; /* Active IRQs for DMA control */ 567 uint32_t napi_poll_mode; /* NAPI is in polling mode */ 568 uint32_t napi_not_done; /* NAPI poll did not process all packets */ 569 uint32_t napi_poll_again; /* Used if DCB chain is restarted */ 570 uint32_t tx_yield; /* Tx schedule for Continuous DMA and Non-NAPI mode */ 571 void *dcb_mem; /* Logical pointer to DCB memory */ 572 uint64_t dcb_dma; /* Physical bus address for DCB memory */ 573 int dcb_mem_size; /* Total size of allocated DCB memory */ 574 uint32_t dma_events; /* DMA events pending for BCM API */ 575 uint32_t rcpu_sig; /* RCPU signature */ 576 uint64_t halt_addr[NUM_DMA_CHAN]; /* DMA halt address */ 577 uint32_t cdma_channels; /* Active channels for Continuous DMA mode */ 578 uint32_t poll_channels; /* Channels for polling */ 579 uint32_t inst_id; /* Instance id of this device */ 580 int evt_idx; /* Event queue index for this device*/ 581 int basedev_suspended; /* Base device suspended */ 582 int tx_hwts; /* HW timestamp for Tx */ 583 int rx_hwts; /* HW timestamp for Rx */ 584 struct sk_buff_head tx_ptp_queue; /* Tx PTP skb queue */ 585 struct work_struct tx_ptp_work; /* Tx PTP work */ 586 struct { 587 bkn_desc_info_t desc[MAX_TX_DCBS+1]; 588 int free; /* Number of free Tx DCBs */ 589 int cur; /* Index of current Tx DCB */ 590 int dirty; /* Index of next Tx DCB to complete */ 591 int api_active; /* BCM Tx API is in progress */ 592 int suspends; /* Calls to netif_stop_queue (debug only) */ 593 struct list_head api_dcb_list; /* Tx DCB chains from BCM Tx API */ 594 bkn_dcb_chain_t *api_dcb_chain; /* Current Tx DCB chain */ 595 bkn_dcb_chain_t *api_dcb_chain_end; /* Tx DCB chain end */ 596 uint32_t pkts; /* Tx packet counter */ 597 uint32_t pkts_d_no_skb; /* Tx drop - skb allocation failed */ 598 uint32_t pkts_d_rcpu_encap; /* Tx drop - bad RCPU encapsulation */ 599 uint32_t pkts_d_rcpu_sig; /* Tx drop - bad RCPU signature */ 600 uint32_t pkts_d_rcpu_meta; /* Tx drop - bad RCPU meta data */ 601 uint32_t pkts_d_pad_fail; /* Tx drop - pad to minimum size failed */ 602 uint32_t pkts_d_dma_resrc; /* Tx drop - no DMA resources */ 603 uint32_t pkts_d_callback; /* Tx drop - consumed by call-back */ 604 uint32_t pkts_d_no_link; /* Tx drop - software link down */ 605 uint32_t pkts_d_over_limit; /* Tx drop - length is out of range */ 606 } tx; 607 struct { 608 bkn_desc_info_t desc[MAX_RX_DCBS+1]; 609 int free; /* Number of free Rx DCBs */ 610 int cur; /* Index of current Rx DCB */ 611 int dirty; /* Index of next Rx DCB to complete */ 612 int running; /* Rx DMA is active */ 613 int api_active; /* BCM Rx API is active */ 614 int chain_complete; /* All DCBs in chain processed */ 615 int sync_err; /* Chain done with incomplete DCBs (debug) */ 616 int sync_retry; /* Total retry times for sync error (debug) */ 617 int sync_maxloop; /* Max loop times once in recovering sync (debug) */ 618 int use_rx_skb; /* Use SKBs for DMA */ 619 uint32_t rate_max; /* Rx rate in packets/sec */ 620 uint32_t burst_max; /* Rx burst size in number of packets */ 621 uint32_t tokens; /* Tokens for Rx rate control */ 622 uint32_t rate; /* Current packet rate */ 623 unsigned long tok_jif; /* Jiffies at last token update */ 624 unsigned long rate_jif; /* Jiffies at last rate update */ 625 struct list_head api_dcb_list; /* Rx DCB chains from BCM Rx API */ 626 bkn_dcb_chain_t *api_dcb_chain; /* Current Rx DCB chain */ 627 bkn_dcb_chain_t *api_dcb_chain_end; /* Rx DCB chain end */ 628 uint32_t pkts; /* Rx packet counter */ 629 uint32_t pkts_ref; /* Rx packet count for rate calculation */ 630 uint32_t pkts_f_api; /* Rx packets filtered to API */ 631 uint32_t pkts_f_netif; /* Rx packets filtered to net interface */ 632 uint32_t pkts_m_api; /* Rx packets mirrored to API */ 633 uint32_t pkts_m_netif; /* Rx packets mirrored to net interface */ 634 uint32_t pkts_d_no_skb; /* Rx drop - skb allocation failed */ 635 uint32_t pkts_d_no_match; /* Rx drop - no matching filters */ 636 uint32_t pkts_d_unkn_netif; /* Rx drop - unknown net interface ID */ 637 uint32_t pkts_d_unkn_dest; /* Rx drop - unknown destination type */ 638 uint32_t pkts_d_callback; /* Rx drop - consumed by call-back */ 639 uint32_t pkts_d_no_link; /* Rx drop - software link down */ 640 uint32_t pkts_d_no_api_buf; /* Rx drop - no API buffers */ 641 } rx[NUM_RX_CHAN]; 642 } bkn_switch_info_t; 643 644 /* PTCH_2 */ 645 #define BKN_DNX_PTCH_2_SIZE 2 646 /* ITMH */ 647 #define BKN_DNX_ITMH_SIZE 5 648 /* Modlue Header */ 649 #define BKN_DNX_MODULE_HEADER_SIZE 20 650 /* FTMH */ 651 #define BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_MSB 17 652 #define BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_NOF_BITS 16 653 #define BKN_DNX_FTMH_PP_DSP_MSB 33 654 #define BKN_DNX_FTMH_PP_DSP_NOF_BITS 8 655 #define BKN_DNX_FTMH_ACTION_TYPE_MSB 43 656 #define BKN_DNX_FTMH_ACTION_TYPE_NOF_BITS 2 657 #define BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_MSB 73 658 #define BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_NOF_BITS 1 659 #define BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_MSB 74 660 #define BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_NOF_BITS 1 661 #define BKN_DNX_FTMH_TM_DST_EXT_PRESENT_MSB 75 662 #define BKN_DNX_FTMH_TM_DST_EXT_PRESENT_NOF_BITS 1 663 #define BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_MSB 76 664 #define BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_NOF_BITS 1 665 #define BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_MSB 77 666 #define BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_NOF_BITS 1 667 #define BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_MSB 78 668 #define BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_NOF_BITS 1 669 /* Fix Length for FTMH and Extension headers */ 670 #define BKN_DNX_FTMH_BASE_SIZE 10 671 #define BKN_DNX_FTMH_BIER_BFR_EXT_SIZE 2 672 #define BKN_DNX_FTMH_TM_DST_EXT_SIZE 3 673 #define BKN_DNX_FTMH_FLOW_ID_EXT_SIZE 3 674 #define BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE 6 675 /* TSH */ 676 #define BKN_DNX_TSH_SIZE 4 677 /* PPH */ 678 #define BKN_DNX_PPH_BASE_TYPE_9 9 679 #define BKN_DNX_PPH_BASE_TYPE_10 10 680 #define BKN_DNX_PPH_BASE_TYPE_12 12 681 #define BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB 5 682 #define BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS 16 683 #define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB 53 684 #define BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS 1 685 #define BKN_DNX_PPH_9_FHEI_SIZE_MSB 54 686 #define BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS 2 687 #define BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB 56 688 #define BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS 3 689 #define BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB 9 690 #define BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS 16 691 #define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB 61 692 #define BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS 1 693 #define BKN_DNX_PPH_10_FHEI_SIZE_MSB 62 694 #define BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS 2 695 #define BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB 64 696 #define BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS 3 697 #define BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB 21 698 #define BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS 18 699 #define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB 77 700 #define BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS 1 701 #define BKN_DNX_PPH_12_FHEI_SIZE_MSB 78 702 #define BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS 2 703 #define BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB 80 704 #define BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS 3 705 /* PPH.FHEI_TYPE */ 706 #define BKN_DNX_PPH_FHEI_TYPE_SZ0 1 707 #define BKN_DNX_PPH_FHEI_TYPE_SZ1 2 708 #define BKN_DNX_PPH_FHEI_TYPE_SZ2 3 709 /* FHEI */ 710 #define BKN_DNX_PPH_FHEI_SZ0_SIZE 3 711 #define BKN_DNX_PPH_FHEI_SZ1_SIZE 5 712 #define BKN_DNX_PPH_FHEI_SZ2_SIZE 8 713 #define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB 0 714 #define BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS 27 715 #define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB 27 716 #define BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS 9 717 #define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB 36 718 #define BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS 4 719 /* PPH Extension */ 720 #define BKN_DNX_PPH_LEARN_EXT_SIZE 19 721 /* UDH */ 722 #define BKN_DNX_UDH_DATA_TYPE_0_MSB 0 723 #define BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS 2 724 #define BKN_DNX_UDH_DATA_TYPE_1_MSB 2 725 #define BKN_DNX_UDH_DATA_TYPE_1_NOF_BITS 2 726 #define BKN_DNX_UDH_DATA_TYPE_2_MSB 4 727 #define BKN_DNX_UDH_DATA_TYPE_2_NOF_BITS 2 728 #define BKN_DNX_UDH_DATA_TYPE_3_MSB 6 729 #define BKN_DNX_UDH_DATA_TYPE_3_NOF_BITS 2 730 #define BKN_DNX_UDH_BASE_SIZE 1 731 732 #define BKN_DPP_HDR_MAX_SIZE 40 733 /* PTCH_2 */ 734 #define BKN_DPP_PTCH_2_SIZE 2 735 /* ITMH */ 736 #define BKN_DPP_ITMH_SIZE 4 737 /* FTMH */ 738 #define BKN_DPP_FTMH_LB_EXT_EN 0x1 739 #define BKN_DPP_FTMH_STACKING_EXT_EN 0x2 740 #define BKN_DPP_FTMH_SIZE_BYTE 9 741 #define BKN_DPP_FTMH_LB_EXT_SIZE_BYTE 1 742 #define BKN_DPP_FTMH_STACKING_SIZE_BYTE 2 743 #define BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE 2 744 #define BKN_DPP_FTMH_LB_EXT_SIZE_BYTE 1 745 #define BKN_DPP_FTMH_PKT_SIZE_MSB 0 746 #define BKN_DPP_FTMH_PKT_SIZE_NOF_BITS 14 747 #define BKN_DPP_FTMH_TC_MSB 14 748 #define BKN_DPP_FTMH_TC_NOF_BITS 3 749 #define BKN_DPP_FTMH_SRC_SYS_PORT_MSB 17 750 #define BKN_DPP_FTMH_SRC_SYS_PORT_NOF_BITS 16 751 #define BKN_DPP_FTMH_EXT_DSP_EXIST_MSB 68 752 #define BKN_DPP_FTMH_EXT_DSP_EXIST_NOF_BITS 1 753 #define BKN_DPP_FTMH_EXT_MSB 45 754 #define BKN_DPP_FTMH_EXT_NOF_BITS 2 755 #define BKN_DPP_FTMH_FIRST_EXT_MSB 72 756 #define BKN_DPP_FTMH_ACTION_TYPE_MSB 43 757 #define BKN_DPP_FTMH_ACTION_TYPE_NOF_BITS 2 758 #define BKN_DPP_FTMH_PPH_TYPE_MSB 45 759 #define BKN_DPP_FTMH_PPH_TYPE_NOF_BITS 2 760 761 /* PPH */ 762 #define BKN_DPP_PPH_SIZE_BYTE 7 763 #define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB 0 764 #define BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS 1 765 #define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB 1 766 #define BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS 1 767 #define BKN_DPP_PPH_FHEI_SIZE_MSB 2 768 #define BKN_DPP_PPH_FHEI_SIZE_NOF_BITS 2 769 #define BKN_DPP_PPH_FORWARD_CODE_MSB 4 770 #define BKN_DPP_PPH_FORWARD_CODE_NOF_BITS 4 771 #define BKN_DPP_PPH_VSI_MSB 22 772 #define BKN_DPP_PPH_VSI_NOF_BITS 16 773 /* FHEI TRAP/SNOOP 3B */ 774 #define BKN_DPP_PPH_FHEI_3B_SIZE_BYTE 3 775 #define BKN_DPP_PPH_FHEI_5B_SIZE_BYTE 5 776 #define BKN_DPP_PPH_FHEI_8B_SIZE_BYTE 8 777 #define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB 0 778 #define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS 16 779 #define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB 16 780 #define BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS 8 781 /* PPH extension */ 782 #define BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE 3 783 #define BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE 5 784 785 /* ftmh action type. */ 786 typedef enum bkn_dpp_ftmh_action_type_e { 787 BKN_DPP_FTMH_ACTION_TYPE_FORWARD = 0, /* TM action is forward */ 788 BKN_DPP_FTMH_ACTION_TYPE_SNOOP = 1, /* TM action is snoop */ 789 BKN_DPP_FTMH_ACTION_TYPE_INBOUND_MIRROR = 2, /* TM action is inbound mirror. */ 790 BKN_DPP_FTMH_ACTION_TYPE_OUTBOUND_MIRROR = 3 /* TM action is outbound mirror. */ 791 }bkn_dpp_ftmh_action_type_t; 792 793 /* ftmh dest extension. */ 794 typedef struct bkn_dpp_ftmh_dest_extension_s { 795 uint8 valid; /* Set if the extension is present */ 796 uint32_t dst_sys_port; /* Destination System Port */ 797 } bkn_dpp_ftmh_dest_extension_t; 798 799 /* dnx packet */ 800 typedef struct bkn_dune_system_header_info_s { 801 uint32_t ntwrk_header_ptr; 802 struct { 803 uint32_t packet_size; /* Packet size in bytes */ 804 uint32_t action_type; /* Indicates if the copy is one of the Forward Snoop or Mirror packet copies */ 805 uint32_t pph_type; 806 uint32_t prio; /* Traffic class */ 807 uint32_t src_sys_port; /* Source System port*/ 808 } ftmh; 809 struct { 810 uint32_t vsi; 811 uint32_t trap_qualifier; /* RAW Data */ 812 uint32_t trap_id; /* RAW Data */ 813 } internal; 814 uint32_t system_header_size; 815 uint32_t ftmh_spa; /* FTMH: Source-System-Port-Aggregate*/ 816 uint32_t pph_forward_domain; /* PPH: Forward-Domain*/ 817 uint32_t fhei_qualifier; /* FHEI: Qualifier */ 818 uint32_t fhei_code; /* FHEI: Code */ 819 uint32_t fhei_type; /* FHEI: Type */ 820 } bkn_dune_system_header_info_t; 821 822 #define PREV_IDX(_cur, _max) (((_cur) == 0) ? (_max) - 1 : (_cur) - 1) 823 824 #if defined(CMIC_SOFT_BYTE_SWAP) 825 826 #define CMIC_SWAP32(_x) ((((_x) & 0xff000000) >> 24) \ 827 | (((_x) & 0x00ff0000) >> 8) \ 828 | (((_x) & 0x0000ff00) << 8) \ 829 | (((_x) & 0x000000ff) << 24)) 830 831 #define DEV_READ32(_d, _a, _p) \ 832 do { \ 833 uint32_t _data; \ 834 _data = (((volatile uint32_t *)(_d)->base_addr)[(_a)/4]); \ 835 *(_p) = CMIC_SWAP32(_data); \ 836 } while(0) 837 838 #define DEV_WRITE32(_d, _a, _v) \ 839 do { \ 840 uint32_t _data = CMIC_SWAP32(_v); \ 841 ((volatile uint32_t *)(_d)->base_addr)[(_a)/4] = (_data); \ 842 } while(0) 843 844 #else 845 846 #define DEV_READ32(_d, _a, _p) \ 847 do { \ 848 *(_p) = (((volatile uint32_t *)(_d)->base_addr)[(_a)/4]); \ 849 } while(0) 850 851 #define DEV_WRITE32(_d, _a, _v) \ 852 do { \ 853 ((volatile uint32_t *)(_d)->base_addr)[(_a)/4] = (_v); \ 854 } while(0) 855 856 #endif /* defined(CMIC_SOFT_BYTE_SWAP) */ 857 858 #define MEMORY_BARRIER smp_mb() 859 860 /* Default random MAC address has Broadcom OUI with local admin bit set */ 861 static u8 bkn_dev_mac[6] = { 0x02, 0x10, 0x18, 0x00, 0x00, 0x00 }; 862 863 static u8 bkn_rcpu_dmac[6]; 864 static u8 bkn_rcpu_smac[6]; 865 866 /* Driver Proc Entry root */ 867 static struct proc_dir_entry *bkn_proc_root = NULL; 868 869 typedef struct bkn_priv_s { 870 struct list_head list; 871 struct net_device_stats stats; 872 struct net_device *dev; 873 bkn_switch_info_t *sinfo; 874 int id; 875 int type; 876 int port; 877 uint8_t itmh[4]; 878 int qnum; 879 uint32_t vlan; 880 uint32_t flags; 881 uint32_t cb_user_data; 882 uint8_t system_headers[27]; 883 uint32_t system_headers_size; 884 } bkn_priv_t; 885 886 typedef struct bkn_filter_s { 887 struct list_head list; 888 int dev_no; 889 unsigned long hits; 890 kcom_filter_t kf; 891 } bkn_filter_t; 892 893 894 /* 895 * Multiple instance support in KNET 896 */ 897 static int _bkn_multi_inst = 0; 898 typedef struct { 899 wait_queue_head_t evt_wq; 900 int evt_wq_put; 901 int evt_wq_get; 902 uint32_t inst_id; 903 } bkn_evt_resource_t; 904 905 static bkn_evt_resource_t _bkn_evt[LINUX_BDE_MAX_DEVICES]; 906 907 static int bkn_knet_dev_init(int d); 908 static int bkn_knet_dev_reinit(int d); 909 910 /* IOCTL debug counters */ 911 static int ioctl_cmd; 912 static int ioctl_evt; 913 914 /* Switch devices */ 915 LIST_HEAD(_sinfo_list); 916 917 /* Reallocation chunk size for netif array */ 918 #define NDEVS_CHUNK 64 919 920 /* User call-backs */ 921 static knet_skb_cb_f knet_rx_cb = NULL; 922 static knet_skb_cb_f knet_tx_cb = NULL; 923 static knet_filter_cb_f knet_filter_cb = NULL; 924 static knet_hw_tstamp_enable_cb_f knet_hw_tstamp_enable_cb = NULL; 925 static knet_hw_tstamp_enable_cb_f knet_hw_tstamp_disable_cb = NULL; 926 static knet_hw_tstamp_tx_time_get_cb_f knet_hw_tstamp_tx_time_get_cb = NULL; 927 static knet_hw_tstamp_tx_meta_get_cb_f knet_hw_tstamp_tx_meta_get_cb = NULL; 928 static knet_hw_tstamp_ptp_clock_index_cb_f knet_hw_tstamp_ptp_clock_index_cb = NULL; 929 static knet_hw_tstamp_rx_time_upscale_cb_f knet_hw_tstamp_rx_time_upscale_cb = NULL; 930 931 /* 932 * Thread management 933 */ 934 935 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) 936 /* 937 * Old style using kernel_thread() 938 */ 939 typedef struct { 940 const char * name; 941 volatile int pid; 942 volatile int run; 943 struct completion completion; 944 int state; 945 } bkn_thread_ctrl_t; 946 947 static int 948 bkn_thread_start(bkn_thread_ctrl_t *tc, const char *name, 949 int (*threadfn)(void *)) 950 { 951 if (name == NULL) { 952 return -1; 953 } 954 tc->name = name; 955 tc->pid = kernel_thread(threadfn, tc, 0); 956 if (tc->pid < 0) { 957 tc->pid = 0; 958 return -1; 959 } 960 tc->run = 1; 961 init_completion(&tc->completion); 962 return 0; 963 } 964 965 static int 966 bkn_thread_stop(bkn_thread_ctrl_t *tc) 967 { 968 if (tc->pid == 0) { 969 return 0; 970 } 971 tc->run = 0; 972 kill_proc(tc->pid, SIGTERM, 1); 973 wait_for_completion(&tc->completion); 974 return 0; 975 } 976 977 static int 978 bkn_thread_should_stop(bkn_thread_ctrl_t *tc) 979 { 980 if (tc->run) { 981 return 0; 982 } 983 tc->pid = 0; 984 return 1; 985 } 986 987 static void 988 bkn_thread_boot(bkn_thread_ctrl_t *tc) 989 { 990 siginitsetinv(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL)); 991 } 992 993 static void 994 bkn_thread_exit(bkn_thread_ctrl_t *tc) 995 { 996 complete_and_exit(&tc->completion, 0); 997 } 998 999 static void 1000 bkn_sleep(int clicks) 1001 { 1002 wait_queue_head_t wq; 1003 1004 init_waitqueue_head(&wq); 1005 sleep_on_timeout(&wq, clicks); 1006 } 1007 #else 1008 /* 1009 * New style using kthread API 1010 */ 1011 #include <linux/kthread.h> 1012 typedef struct { 1013 const char * name; 1014 struct task_struct *task; 1015 int state; 1016 } bkn_thread_ctrl_t; 1017 1018 static int 1019 bkn_thread_start(bkn_thread_ctrl_t *tc, const char *name, 1020 int (*threadfn)(void *)) 1021 { 1022 if (name == NULL) { 1023 return -1; 1024 } 1025 tc->name = name; 1026 tc->task = kthread_run(threadfn, tc, name); 1027 if (IS_ERR(tc->task)) { 1028 tc->task = NULL; 1029 return -1; 1030 } 1031 return 0; 1032 } 1033 1034 static int 1035 bkn_thread_stop(bkn_thread_ctrl_t *tc) 1036 { 1037 if (tc->task == NULL) { 1038 return 0; 1039 } 1040 send_sig(SIGTERM, tc->task, 0); 1041 return kthread_stop(tc->task); 1042 } 1043 1044 static int 1045 bkn_thread_should_stop(bkn_thread_ctrl_t *tc) 1046 { 1047 return kthread_should_stop(); 1048 } 1049 1050 static void 1051 bkn_thread_boot(bkn_thread_ctrl_t *tc) 1052 { 1053 allow_signal(SIGTERM); 1054 allow_signal(SIGKILL); 1055 } 1056 1057 static void 1058 bkn_thread_exit(bkn_thread_ctrl_t *tc) 1059 { 1060 } 1061 1062 static void 1063 bkn_sleep(int clicks) 1064 { 1065 wait_queue_head_t wq; 1066 1067 init_waitqueue_head(&wq); 1068 wait_event_timeout(wq, 0, clicks); 1069 } 1070 #endif 1071 1072 static bkn_thread_ctrl_t bkn_cmd_ctrl; 1073 static bkn_thread_ctrl_t bkn_evt_ctrl; 1074 1075 /* 1076 * On XGS devices bit 15 fo the Transferred Bytes field in 1077 * the DCBs is used to indicate that kernel processing is 1078 * complete. Using this bit reduces the theoretically maximum 1079 * supported packet size from 64K to 32K, but this is still 1080 * adequate for 16K jumbo packets. 1081 */ 1082 #define SOC_DCB_KNET_DONE 0x8000 1083 #define SOC_DCB_KNET_COUNT_MASK 0x7fff 1084 #define SOC_DCB_META_OFFSET 2 1085 1086 /* Default channel configuration */ 1087 #define XGS_DMA_TX_CHAN 0 1088 #define XGS_DMA_RX_CHAN 1 1089 1090 /* CMIC registers */ 1091 #define CMIC_DMA_CTRLr 0x00000100 1092 #define CMIC_DMA_STATr 0x00000104 1093 #define CMIC_DMA_DESC0r 0x00000110 1094 #define CMIC_IRQ_STATr 0x00000144 1095 #define CMIC_IRQ_MASKr 0x00000148 1096 #define CMIC_DEV_REV_IDr 0x00000178 1097 1098 /* CMIC interrupts reserved for kernel handler */ 1099 #define CMIC_TXRX_IRQ_MASK 0x7f80 1100 1101 /* CMICm registers */ 1102 #define CMICM_CMC_BASE 0x00031000 1103 #define CMICM_DMA_CTRLr (CMICM_CMC_BASE + 0x00000140) 1104 #define CMICM_DMA_STATr (CMICM_CMC_BASE + 0x00000150) 1105 #define CMICM_DMA_STAT_CLRr (CMICM_CMC_BASE + 0x000001a4) 1106 #define CMICM_DMA_DESC0r (CMICM_CMC_BASE + 0x00000158) 1107 #define CMICM_DMA_HALT_ADDRr (CMICM_CMC_BASE + 0x00000120) 1108 #define CMICM_IRQ_STATr (CMICM_CMC_BASE + 0x00000400) 1109 #define CMICM_IRQ_PCI_MASKr (CMICM_CMC_BASE + 0x00000414) 1110 #define CMICM_IRQ_UC0_MASKr (CMICM_CMC_BASE + 0x00000428) 1111 #define CMICM_DEV_REV_IDr 0x00010224 1112 1113 /* CMICm interrupts reserved for kernel handler */ 1114 #define CMICM_TXRX_IRQ_MASK 0xff00 1115 1116 /* CMICd increased interrupts reserved for kernel handler */ 1117 #define CMICD_CTRLD_IRQ_MASK 0x78000000 1118 1119 /* CMICx registers */ 1120 #define CMICX_CMC_BASE 0x00000000 1121 #define CMICX_DMA_CTRLr (CMICX_CMC_BASE + 0x00002100) 1122 #define CMICX_DMA_STATr (CMICX_CMC_BASE + 0x00002114) 1123 #define CMICX_DMA_DESC_HIr (CMICX_CMC_BASE + 0x00002108) 1124 #define CMICX_DMA_DESC_LOr (CMICX_CMC_BASE + 0x00002104) 1125 #define CMICX_DMA_HALT_HIr (CMICX_CMC_BASE + 0x00002110) 1126 #define CMICX_DMA_HALT_LOr (CMICX_CMC_BASE + 0x0000210c) 1127 #define CMICX_IRQ_STATr (CMICX_CMC_BASE + 0x0000106c) 1128 #define CMICX_IRQ_STAT_CLRr (CMICX_CMC_BASE + 0x00001074) 1129 #define CMICX_IRQ_ENABr 0x18013100 1130 #define IHOST_GIC_GIC400_GICD_ISENABLERN_5r 0x10781114 1131 #define IHOST_GIC_GIC400_GICD_ICENABLERN_5r 0x10781194 1132 1133 /* CMICx interrupts reserved for kernel handler */ 1134 #define CMICX_TXRX_IRQ_MASK 0xffffffff 1135 1136 #define DEV_IS_CMICX(_sinfo) ((_sinfo)->cmic_type == 'x') 1137 #define DEV_IS_CMICM(_sinfo) ((_sinfo)->cmic_type == 'm') 1138 #define CDMA_CH(_d, _ch) ((_d)->cdma_channels & (1 << (_ch))) 1139 1140 /* 1141 * DMA_STAT: control bits 1142 * 1143 * xxx_SET and xxx_CLR can be WRITTEN to CMIC_DMA_STAT 1144 * xxx_TST can be masked against values read from CMIC_DMA_STAT. 1145 * Argument required: 0 <= ch <= 3 1146 */ 1147 #define DS_DMA_ACTIVE(ch) (0x00040000 << (ch)) 1148 #define DS_DMA_EN_SET(ch) (0x80|(ch)) 1149 #define DS_DMA_EN_CLR(ch) (0x00|(ch)) 1150 #define DS_DMA_EN_TST(ch) (0x00000001 << (ch)) 1151 1152 #define DS_CHAIN_DONE_SET(ch) (0x80|(4+(ch))) 1153 #define DS_CHAIN_DONE_CLR(ch) (0x00|(4+(ch))) 1154 #define DS_CHAIN_DONE_TST(ch) (0x00000010 << (ch)) 1155 1156 #define DS_DESC_DONE_SET(ch) (0x80|(8+(ch))) 1157 #define DS_DESC_DONE_CLR(ch) (0x00|(8+(ch))) 1158 #define DS_DESC_DONE_TST(ch) (0x00000100 << (ch)) 1159 1160 #define DC_ABORT_DMA(ch) (0x04 << (8 * (ch))) 1161 1162 #define DS_CMC_DESCRD_CMPLT_CLR(ch) (0x00000001 << (ch)) 1163 #define DS_CMC_CTRLD_INT_CLR(ch) (0x00000100 << (ch)) 1164 #define DS_CMC_DMA_ACTIVE(ch) (0x00000100 << (ch)) 1165 1166 #define CMICX_DS_CMC_DESC_DONE(ch) (0x00000001 << ((ch) * 4)) 1167 #define CMICX_DS_CMC_CHAIN_DONE(ch) (0x00000002 << ((ch) * 4)) 1168 #define CMICX_DS_CMC_CTRLD_INT(ch) (0x00000008 << ((ch) * 4)) 1169 #define CMICX_DS_CMC_DMA_CHAIN_DONE (0x00000001) 1170 #define CMICX_DS_CMC_DMA_ACTIVE (0x00000002) 1171 1172 #define DMA_TO_BUS_HI(dma) ((dma) | sinfo->dma_hi) 1173 #define BUS_TO_DMA_HI(bus) ((bus) & ~sinfo->dma_hi) 1174 1175 /* 1176 * DMA_CTRL: control bits 1177 */ 1178 #define DC_CMC_DIRECTION (0x00000001) 1179 #define DC_CMC_ENABLE (0x00000002) 1180 #define DC_CMC_ABORT (0x00000004) 1181 #define DC_CMC_CTRLD_INT (0x00000100) 1182 #define DC_CMC_CONTINUOUS (0x00000200) 1183 1184 #define CMICX_DC_CMC_DIRECTION (0x00000001) 1185 #define CMICX_DC_CMC_ENABLE (0x00000002) 1186 #define CMICX_DC_CMC_ABORT (0x00000004) 1187 #define CMICX_DC_CMC_CTRLD_INT (0x00000080) 1188 #define CMICX_DC_CMC_CONTINUOUS (0x00000100) 1189 1190 /* 1191 * Per-channel operations. 1192 * These are the basis for the TX/RX functions 1193 */ 1194 1195 static inline void 1196 xgs_dma_chain_clear(bkn_switch_info_t *sinfo, int chan) 1197 { 1198 DBG_IRQ(("Clear chain on device %d chan %d\n", 1199 sinfo->dev_no, chan)); 1200 DEV_WRITE32(sinfo, CMIC_DMA_STATr, DS_DMA_EN_CLR(chan)); 1201 DEV_WRITE32(sinfo, CMIC_DMA_STATr, DS_CHAIN_DONE_CLR(chan)); 1202 1203 MEMORY_BARRIER; 1204 } 1205 1206 static inline void 1207 xgs_dma_desc_clear(bkn_switch_info_t *sinfo, int chan) 1208 { 1209 uint32_t val; 1210 1211 DBG_IRQ(("Clear desc on device %d chan %d\n", 1212 sinfo->dev_no, chan)); 1213 DEV_WRITE32(sinfo, CMIC_DMA_STATr, DS_DESC_DONE_CLR(chan)); 1214 1215 MEMORY_BARRIER; 1216 1217 /* Flush write buffer */ 1218 DEV_READ32(sinfo, CMIC_DMA_STATr, &val); 1219 1220 MEMORY_BARRIER; 1221 } 1222 1223 static int 1224 xgs_dma_chan_clear(bkn_switch_info_t *sinfo, int chan) 1225 { 1226 xgs_dma_chain_clear(sinfo, chan); 1227 xgs_dma_desc_clear(sinfo, chan); 1228 1229 return 0; 1230 } 1231 1232 static int 1233 xgs_dma_chan_init(bkn_switch_info_t *sinfo, int chan, int dir) 1234 { 1235 uint32_t cdc; 1236 1237 DEV_READ32(sinfo, CMIC_DMA_CTRLr, &cdc); 1238 1239 cdc &= ~(0x9 << (8 * chan)); 1240 if (dir) { 1241 cdc |= 0x1 << (8 * chan); 1242 } else { 1243 cdc |= 0x8 << (8 * chan); 1244 } 1245 1246 DEV_WRITE32(sinfo, CMIC_DMA_CTRLr, cdc); 1247 1248 return 0; 1249 } 1250 1251 static int 1252 xgs_dma_chan_start(bkn_switch_info_t *sinfo, int chan, uint64_t dcb) 1253 { 1254 /* Write the DCB address to the DESC address for this channel */ 1255 DEV_WRITE32(sinfo, CMIC_DMA_DESC0r + 4 * chan, dcb); 1256 1257 MEMORY_BARRIER; 1258 1259 /* Kick it off */ 1260 DEV_WRITE32(sinfo, CMIC_DMA_STATr, DS_DMA_EN_SET(chan)); 1261 1262 MEMORY_BARRIER; 1263 1264 return 0; 1265 } 1266 1267 static int 1268 xgs_dma_chan_abort(bkn_switch_info_t *sinfo, int chan, int polls) 1269 { 1270 uint32_t ctrl, dma_stat; 1271 int p; 1272 1273 /* Clear enable */ 1274 DEV_WRITE32(sinfo, CMIC_DMA_STATr, DS_DMA_EN_CLR(chan)); 1275 1276 MEMORY_BARRIER; 1277 1278 /* Abort the channel */ 1279 DEV_READ32(sinfo, CMIC_DMA_CTRLr, &ctrl); 1280 DEV_WRITE32(sinfo, CMIC_DMA_CTRLr, ctrl | DC_ABORT_DMA(chan)); 1281 1282 MEMORY_BARRIER; 1283 1284 /* Poll for abort completion */ 1285 for (p = 0; p < polls; p++) { 1286 DEV_READ32(sinfo, CMIC_DMA_STATr, &dma_stat); 1287 if (!(dma_stat & DS_DMA_ACTIVE(chan))) { 1288 /* Restore previous control value */ 1289 DEV_WRITE32(sinfo, CMIC_DMA_CTRLr, ctrl); 1290 1291 MEMORY_BARRIER; 1292 1293 /* Clear up channel */ 1294 xgs_dma_chan_clear(sinfo, chan); 1295 1296 return polls; 1297 } 1298 } 1299 DBG_WARN(("DMA channel %d abort failed\n", chan)); 1300 1301 return -1; 1302 } 1303 1304 static inline void 1305 xgs_irq_mask_set(bkn_switch_info_t *sinfo, uint32_t mask) 1306 { 1307 if (sinfo->napi_poll_mode) { 1308 mask = 0; 1309 } 1310 lkbde_irq_mask_set(sinfo->dev_no | LKBDE_ISR2_DEV, CMIC_IRQ_MASKr, 1311 mask, CMIC_TXRX_IRQ_MASK); 1312 } 1313 1314 static inline void 1315 xgs_irq_mask_enable(bkn_switch_info_t *sinfo, int chan, int update_hw) 1316 { 1317 uint32_t mask; 1318 1319 if (chan == XGS_DMA_TX_CHAN) { 1320 mask = 0x100; 1321 } else { 1322 mask = 0x180 << (2 * chan); 1323 } 1324 1325 sinfo->irq_mask |= mask; 1326 1327 if (update_hw) { 1328 xgs_irq_mask_set(sinfo, sinfo->irq_mask); 1329 } 1330 } 1331 1332 static inline void 1333 xgs_irq_mask_disable(bkn_switch_info_t *sinfo, int chan, int update_hw) 1334 { 1335 uint32_t mask; 1336 1337 if (chan == XGS_DMA_TX_CHAN) { 1338 mask = 0x100; 1339 } else { 1340 mask = 0x180 << (2 * chan); 1341 } 1342 1343 sinfo->irq_mask &= ~mask; 1344 1345 if (update_hw) { 1346 xgs_irq_mask_set(sinfo, sinfo->irq_mask); 1347 } 1348 } 1349 1350 static inline void 1351 xgsm_dma_chain_clear(bkn_switch_info_t *sinfo, int chan) 1352 { 1353 uint32_t cdc; 1354 1355 /* Disabing DMA clears chain done */ 1356 DEV_READ32(sinfo, CMICM_DMA_CTRLr + 4 * chan, &cdc); 1357 cdc &= ~(DC_CMC_ENABLE | DC_CMC_ABORT); 1358 DEV_WRITE32(sinfo, CMICM_DMA_CTRLr + 4 * chan, cdc); 1359 1360 MEMORY_BARRIER; 1361 } 1362 1363 static inline void 1364 xgsm_dma_desc_clear(bkn_switch_info_t *sinfo, int chan) 1365 { 1366 uint32_t val; 1367 1368 val = DS_CMC_DESCRD_CMPLT_CLR(chan); 1369 if (CDMA_CH(sinfo, chan)) { 1370 val |= DS_CMC_CTRLD_INT_CLR(chan); 1371 } 1372 DEV_WRITE32(sinfo, CMICM_DMA_STAT_CLRr, val); 1373 1374 MEMORY_BARRIER; 1375 1376 /* Flush write buffer */ 1377 DEV_READ32(sinfo, CMICM_DMA_STAT_CLRr, &val); 1378 1379 MEMORY_BARRIER; 1380 } 1381 1382 static int 1383 xgsm_dma_chan_clear(bkn_switch_info_t *sinfo, int chan) 1384 { 1385 xgsm_dma_chain_clear(sinfo, chan); 1386 xgsm_dma_desc_clear(sinfo, chan); 1387 1388 return 0; 1389 } 1390 1391 static inline void 1392 xgsm_cdma_halt_set(bkn_switch_info_t *sinfo, int chan) 1393 { 1394 DEV_WRITE32(sinfo, CMICM_DMA_HALT_ADDRr + 4 * chan, 1395 sinfo->halt_addr[chan]); 1396 1397 MEMORY_BARRIER; 1398 } 1399 1400 static int 1401 xgsm_dma_chan_init(bkn_switch_info_t *sinfo, int chan, int dir) 1402 { 1403 uint32_t cdc; 1404 1405 DEV_READ32(sinfo, CMICM_DMA_CTRLr + 4 * chan, &cdc); 1406 cdc &= ~DC_CMC_DIRECTION; 1407 if (dir) { 1408 cdc |= DC_CMC_DIRECTION; 1409 } 1410 if (CDMA_CH(sinfo, chan)) { 1411 cdc |= DC_CMC_CONTINUOUS | DC_CMC_CTRLD_INT; 1412 xgsm_cdma_halt_set(sinfo, chan); 1413 } 1414 DEV_WRITE32(sinfo, CMICM_DMA_CTRLr + 4 * chan, cdc); 1415 1416 return 0; 1417 } 1418 1419 static int 1420 xgsm_dma_chan_start(bkn_switch_info_t *sinfo, int chan, uint64_t dcb) 1421 { 1422 uint32_t cdc; 1423 1424 /* Write the DCB address to the DESC address for this channel */ 1425 DEV_WRITE32(sinfo, CMICM_DMA_DESC0r + 4 * chan, dcb); 1426 1427 MEMORY_BARRIER; 1428 1429 /* Kick it off */ 1430 DEV_READ32(sinfo, CMICM_DMA_CTRLr + 4 * chan, &cdc); 1431 cdc |= DC_CMC_ENABLE; 1432 DEV_WRITE32(sinfo, CMICM_DMA_CTRLr + 4 * chan, cdc); 1433 1434 MEMORY_BARRIER; 1435 1436 return 0; 1437 } 1438 1439 static int 1440 xgsm_dma_chan_abort(bkn_switch_info_t *sinfo, int chan, int polls) 1441 { 1442 uint32_t ctrl, dma_stat; 1443 int p; 1444 1445 /* Skip abort sequence if channel is not active */ 1446 DEV_READ32(sinfo, CMICM_DMA_STATr, &dma_stat); 1447 if (!(dma_stat & DS_CMC_DMA_ACTIVE(chan))) { 1448 return 0; 1449 } 1450 1451 /* Abort the channel */ 1452 DEV_READ32(sinfo, CMICM_DMA_CTRLr + 4 * chan, &ctrl); 1453 ctrl |= (DC_CMC_ENABLE | DC_CMC_ABORT); 1454 DEV_WRITE32(sinfo, CMICM_DMA_CTRLr + 4 * chan, ctrl); 1455 1456 MEMORY_BARRIER; 1457 1458 /* Poll for abort completion */ 1459 for (p = 0; p < polls; p++) { 1460 DEV_READ32(sinfo, CMICM_DMA_STATr, &dma_stat); 1461 if (!(dma_stat & DS_CMC_DMA_ACTIVE(chan))) { 1462 /* Clear up channel */ 1463 xgsm_dma_chan_clear(sinfo, chan); 1464 return polls; 1465 } 1466 } 1467 DBG_WARN(("DMA channel %d abort failed\n", chan)); 1468 1469 return -1; 1470 } 1471 1472 static inline void 1473 xgsm_irq_mask_set(bkn_switch_info_t *sinfo, uint32_t mask) 1474 { 1475 uint32_t irq_mask_reg = CMICM_IRQ_PCI_MASKr; 1476 uint32_t ctrld_mask = 0; 1477 1478 if (sinfo->napi_poll_mode) { 1479 mask = 0; 1480 } 1481 if (sinfo->cpu_no == 1) { 1482 irq_mask_reg = CMICM_IRQ_UC0_MASKr; 1483 } 1484 1485 /* Get the Controlled Interrupts mask for Continuous DMA mode */ 1486 ctrld_mask |= (sinfo->cdma_channels << 27) & CMICD_CTRLD_IRQ_MASK; 1487 1488 lkbde_irq_mask_set(sinfo->dev_no | LKBDE_ISR2_DEV, irq_mask_reg, 1489 mask, CMICM_TXRX_IRQ_MASK | ctrld_mask); 1490 } 1491 1492 static inline void 1493 xgsm_irq_mask_enable(bkn_switch_info_t *sinfo, int chan, int update_hw) 1494 { 1495 uint32_t mask; 1496 1497 if (CDMA_CH(sinfo, chan)) { 1498 mask = 0x08000000 << chan; 1499 } else { 1500 if (chan == XGS_DMA_TX_CHAN) { 1501 mask = 0x8000; 1502 } else { 1503 mask = 0xc000 >> (2 * chan); 1504 } 1505 } 1506 1507 sinfo->irq_mask |= mask; 1508 1509 if (update_hw) { 1510 xgsm_irq_mask_set(sinfo, sinfo->irq_mask); 1511 } 1512 } 1513 1514 static inline void 1515 xgsm_irq_mask_disable(bkn_switch_info_t *sinfo, int chan, int update_hw) 1516 { 1517 uint32_t mask; 1518 1519 if (CDMA_CH(sinfo, chan)) { 1520 mask = 0x08000000 << chan; 1521 } else { 1522 if (chan == XGS_DMA_TX_CHAN) { 1523 mask = 0x8000; 1524 } else { 1525 mask = 0xc000 >> (2 * chan); 1526 } 1527 } 1528 1529 sinfo->irq_mask &= ~mask; 1530 1531 if (update_hw) { 1532 xgsm_irq_mask_set(sinfo, sinfo->irq_mask); 1533 } 1534 } 1535 1536 static inline void 1537 xgsx_dma_chain_clear(bkn_switch_info_t *sinfo, int chan) 1538 { 1539 uint32_t ctrl, stat; 1540 1541 /* Disabing DMA clears chain done */ 1542 DEV_READ32(sinfo, CMICX_DMA_CTRLr + 0x80 * chan, &ctrl); 1543 ctrl &= ~(CMICX_DC_CMC_ENABLE | CMICX_DC_CMC_ABORT); 1544 DEV_WRITE32(sinfo, CMICX_DMA_CTRLr + 0x80 * chan, ctrl); 1545 1546 stat = CMICX_DS_CMC_CHAIN_DONE(chan); 1547 DEV_WRITE32(sinfo, CMICX_IRQ_STAT_CLRr, stat); 1548 1549 MEMORY_BARRIER; 1550 1551 /* Flush write buffer */ 1552 DEV_READ32(sinfo, CMICX_IRQ_STAT_CLRr, &stat); 1553 1554 MEMORY_BARRIER; 1555 } 1556 1557 static inline void 1558 xgsx_dma_desc_clear(bkn_switch_info_t *sinfo, int chan) 1559 { 1560 uint32_t stat; 1561 1562 if (CDMA_CH(sinfo, chan)) { 1563 stat = CMICX_DS_CMC_CTRLD_INT(chan); 1564 } else { 1565 stat = CMICX_DS_CMC_DESC_DONE(chan); 1566 } 1567 DEV_WRITE32(sinfo, CMICX_IRQ_STAT_CLRr, stat); 1568 1569 MEMORY_BARRIER; 1570 1571 /* Flush write buffer */ 1572 DEV_READ32(sinfo, CMICX_IRQ_STAT_CLRr, &stat); 1573 1574 MEMORY_BARRIER; 1575 } 1576 1577 static int 1578 xgsx_dma_chan_clear(bkn_switch_info_t *sinfo, int chan) 1579 { 1580 xgsx_dma_chain_clear(sinfo, chan); 1581 xgsx_dma_desc_clear(sinfo, chan); 1582 1583 return 0; 1584 } 1585 1586 static inline void 1587 xgsx_cdma_halt_set(bkn_switch_info_t *sinfo, int chan) 1588 { 1589 DEV_WRITE32(sinfo, CMICX_DMA_HALT_LOr + 0x80 * chan, 1590 sinfo->halt_addr[chan]); 1591 DEV_WRITE32(sinfo, CMICX_DMA_HALT_HIr + 0x80 * chan, 1592 DMA_TO_BUS_HI(sinfo->halt_addr[chan] >> 32)); 1593 1594 MEMORY_BARRIER; 1595 } 1596 1597 static int 1598 xgsx_dma_chan_init(bkn_switch_info_t *sinfo, int chan, int dir) 1599 { 1600 uint32_t ctrl; 1601 1602 DEV_READ32(sinfo, CMICX_DMA_CTRLr + 0x80 * chan, &ctrl); 1603 ctrl &= ~CMICX_DC_CMC_DIRECTION; 1604 if (dir) { 1605 ctrl |= CMICX_DC_CMC_DIRECTION; 1606 } 1607 if (CDMA_CH(sinfo, chan)) { 1608 ctrl |= CMICX_DC_CMC_CONTINUOUS | CMICX_DC_CMC_CTRLD_INT; 1609 xgsx_cdma_halt_set(sinfo, chan); 1610 } 1611 DEV_WRITE32(sinfo, CMICX_DMA_CTRLr + 0x80 * chan, ctrl); 1612 1613 MEMORY_BARRIER; 1614 1615 return 0; 1616 } 1617 1618 static int 1619 xgsx_dma_chan_start(bkn_switch_info_t *sinfo, int chan, uint64_t dcb) 1620 { 1621 uint32_t ctrl; 1622 1623 /* Write the DCB address to the DESC address for this channel */ 1624 DEV_WRITE32(sinfo, CMICX_DMA_DESC_LOr + 0x80 * chan, dcb); 1625 DEV_WRITE32(sinfo, CMICX_DMA_DESC_HIr + 0x80 * chan, DMA_TO_BUS_HI(dcb >> 32)); 1626 1627 MEMORY_BARRIER; 1628 1629 /* Kick it off */ 1630 DEV_READ32(sinfo, CMICX_DMA_CTRLr + 0x80 * chan, &ctrl); 1631 ctrl |= CMICX_DC_CMC_ENABLE; 1632 DEV_WRITE32(sinfo, CMICX_DMA_CTRLr + 0x80 * chan, ctrl); 1633 1634 MEMORY_BARRIER; 1635 1636 return 0; 1637 } 1638 1639 static int 1640 xgsx_dma_chan_abort(bkn_switch_info_t *sinfo, int chan, int polls) 1641 { 1642 uint32_t ctrl, stat; 1643 int p; 1644 1645 /* Skip abort sequence if channel is not active */ 1646 DEV_READ32(sinfo, CMICX_DMA_STATr + 0x80 * chan, &stat); 1647 if (!(stat & CMICX_DS_CMC_DMA_ACTIVE)) { 1648 return 0; 1649 } 1650 1651 /* Abort the channel */ 1652 DEV_READ32(sinfo, CMICX_DMA_CTRLr + 0x80 * chan, &ctrl); 1653 ctrl |= CMICX_DC_CMC_ENABLE | CMICX_DC_CMC_ABORT; 1654 DEV_WRITE32(sinfo, CMICX_DMA_CTRLr + 0x80 * chan, ctrl); 1655 1656 MEMORY_BARRIER; 1657 1658 /* Poll for abort completion */ 1659 for (p = 0; p < polls; p++) { 1660 DEV_READ32(sinfo, CMICX_DMA_STATr + 0x80 * chan, &stat); 1661 if (!(stat & CMICX_DS_CMC_DMA_ACTIVE)) { 1662 /* Clear up channel */ 1663 xgsx_dma_chan_clear(sinfo, chan); 1664 return polls; 1665 } 1666 } 1667 1668 DBG_WARN(("DMA channel %d abort failed\n", chan)); 1669 1670 return -1; 1671 } 1672 1673 static inline void 1674 xgsx_irq_mask_set(bkn_switch_info_t *sinfo, uint32_t mask) 1675 { 1676 uint32_t irq_mask_reg = CMICX_IRQ_ENABr; 1677 uint32_t irq_mask, irq_fmask, disable_mask; 1678 1679 if (sinfo->napi_poll_mode) { 1680 mask = 0; 1681 } 1682 1683 if (sinfo->cpu_no == 1) { 1684 lkbde_irq_mask_get(sinfo->dev_no, &irq_mask, &irq_fmask); 1685 disable_mask = ~mask & (irq_mask & irq_fmask); 1686 if (disable_mask) { 1687 lkbde_irq_mask_set(sinfo->dev_no | LKBDE_ISR2_DEV | LKBDE_IPROC_REG, 1688 IHOST_GIC_GIC400_GICD_ICENABLERN_5r, disable_mask, CMICX_TXRX_IRQ_MASK); 1689 } 1690 irq_mask_reg = IHOST_GIC_GIC400_GICD_ISENABLERN_5r; 1691 } 1692 1693 lkbde_irq_mask_set(sinfo->dev_no | LKBDE_ISR2_DEV | LKBDE_IPROC_REG, 1694 irq_mask_reg, mask, CMICX_TXRX_IRQ_MASK); 1695 } 1696 1697 static inline void 1698 xgsx_irq_mask_enable(bkn_switch_info_t *sinfo, int chan, int update_hw) 1699 { 1700 uint32_t mask; 1701 1702 if (CDMA_CH(sinfo, chan)) { 1703 mask = CMICX_DS_CMC_CTRLD_INT(chan); 1704 } else { 1705 if (chan == XGS_DMA_TX_CHAN) { 1706 mask = CMICX_DS_CMC_CHAIN_DONE(chan); 1707 } else { 1708 mask = CMICX_DS_CMC_DESC_DONE(chan) | 1709 CMICX_DS_CMC_CHAIN_DONE(chan); 1710 } 1711 } 1712 1713 sinfo->irq_mask |= mask; 1714 1715 if (update_hw) { 1716 xgsx_irq_mask_set(sinfo, sinfo->irq_mask); 1717 } 1718 } 1719 1720 static inline void 1721 xgsx_irq_mask_disable(bkn_switch_info_t *sinfo, int chan, int update_hw) 1722 { 1723 uint32_t mask; 1724 1725 if (CDMA_CH(sinfo, chan)) { 1726 mask = CMICX_DS_CMC_CTRLD_INT(chan); 1727 } else { 1728 if (chan == XGS_DMA_TX_CHAN) { 1729 mask = CMICX_DS_CMC_CHAIN_DONE(chan); 1730 } else { 1731 mask = CMICX_DS_CMC_DESC_DONE(chan) | 1732 CMICX_DS_CMC_CHAIN_DONE(chan); 1733 } 1734 } 1735 1736 sinfo->irq_mask &= ~mask; 1737 1738 if (update_hw) { 1739 xgsx_irq_mask_set(sinfo, sinfo->irq_mask); 1740 } 1741 } 1742 1743 static inline void 1744 dev_dma_chain_clear(bkn_switch_info_t *sinfo, int chan) 1745 { 1746 if (DEV_IS_CMICX(sinfo)) { 1747 xgsx_dma_chain_clear(sinfo, chan); 1748 } else if (DEV_IS_CMICM(sinfo)) { 1749 xgsm_dma_chain_clear(sinfo, chan); 1750 } else { 1751 xgs_dma_chain_clear(sinfo, chan); 1752 } 1753 } 1754 1755 static inline void 1756 dev_dma_desc_clear(bkn_switch_info_t *sinfo, int chan) 1757 { 1758 if (DEV_IS_CMICX(sinfo)) { 1759 xgsx_dma_desc_clear(sinfo, chan); 1760 } else if (DEV_IS_CMICM(sinfo)) { 1761 xgsm_dma_desc_clear(sinfo, chan); 1762 } else { 1763 xgs_dma_desc_clear(sinfo, chan); 1764 } 1765 } 1766 1767 static int 1768 dev_dma_chan_clear(bkn_switch_info_t *sinfo, int chan) 1769 { 1770 if (DEV_IS_CMICX(sinfo)) { 1771 return xgsx_dma_chan_clear(sinfo, chan); 1772 } else if (DEV_IS_CMICM(sinfo)) { 1773 return xgsm_dma_chan_clear(sinfo, chan); 1774 } else { 1775 return xgs_dma_chan_clear(sinfo, chan); 1776 } 1777 } 1778 1779 static void 1780 dev_cdma_halt_set(bkn_switch_info_t *sinfo, int chan) 1781 { 1782 if (DEV_IS_CMICX(sinfo)) { 1783 xgsx_cdma_halt_set(sinfo, chan); 1784 } else if (DEV_IS_CMICM(sinfo)) { 1785 xgsm_cdma_halt_set(sinfo, chan); 1786 } 1787 } 1788 1789 static int 1790 dev_dma_chan_init(bkn_switch_info_t *sinfo, int chan, int dir) 1791 { 1792 if (DEV_IS_CMICX(sinfo)) { 1793 return xgsx_dma_chan_init(sinfo, chan, dir); 1794 } else if (DEV_IS_CMICM(sinfo)) { 1795 return xgsm_dma_chan_init(sinfo, chan, dir); 1796 } else { 1797 return xgs_dma_chan_init(sinfo, chan, dir); 1798 } 1799 } 1800 1801 static int 1802 dev_dma_chan_start(bkn_switch_info_t *sinfo, int chan, uint64_t dcb) 1803 { 1804 if (DEV_IS_CMICX(sinfo)) { 1805 return xgsx_dma_chan_start(sinfo, chan, dcb); 1806 } else if (DEV_IS_CMICM(sinfo)) { 1807 return xgsm_dma_chan_start(sinfo, chan, dcb); 1808 } else { 1809 return xgs_dma_chan_start(sinfo, chan, dcb); 1810 } 1811 } 1812 1813 static int 1814 dev_dma_chan_abort(bkn_switch_info_t *sinfo, int chan, int polls) 1815 { 1816 if (DEV_IS_CMICX(sinfo)) { 1817 return xgsx_dma_chan_abort(sinfo, chan, polls); 1818 } else if (DEV_IS_CMICM(sinfo)) { 1819 return xgsm_dma_chan_abort(sinfo, chan, polls); 1820 } else { 1821 return xgs_dma_chan_abort(sinfo, chan, polls); 1822 } 1823 } 1824 1825 static inline void 1826 dev_irq_mask_set(bkn_switch_info_t *sinfo, uint32_t mask) 1827 { 1828 if (DEV_IS_CMICX(sinfo)) { 1829 xgsx_irq_mask_set(sinfo, mask); 1830 } else if (DEV_IS_CMICM(sinfo)) { 1831 xgsm_irq_mask_set(sinfo, mask); 1832 } else { 1833 xgs_irq_mask_set(sinfo, mask); 1834 } 1835 } 1836 1837 static inline void 1838 dev_irq_mask_enable(bkn_switch_info_t *sinfo, int chan, int update_hw) 1839 { 1840 if (DEV_IS_CMICX(sinfo)) { 1841 xgsx_irq_mask_enable(sinfo, chan, update_hw); 1842 } else if (DEV_IS_CMICM(sinfo)) { 1843 xgsm_irq_mask_enable(sinfo, chan, update_hw); 1844 } else { 1845 xgs_irq_mask_enable(sinfo, chan, update_hw); 1846 } 1847 } 1848 1849 static void 1850 dev_irq_mask_disable(bkn_switch_info_t *sinfo, int chan, int update_hw) 1851 { 1852 if (DEV_IS_CMICX(sinfo)) { 1853 xgsx_irq_mask_disable(sinfo, chan, update_hw); 1854 } else if (DEV_IS_CMICM(sinfo)) { 1855 xgsm_irq_mask_disable(sinfo, chan, update_hw); 1856 } else { 1857 xgs_irq_mask_disable(sinfo, chan, update_hw); 1858 } 1859 } 1860 1861 static int 1862 bkn_alloc_dcbs(bkn_switch_info_t *sinfo) 1863 { 1864 int dcb_size; 1865 int tx_ring_size, rx_ring_size; 1866 dma_addr_t dcb_dma = 0; 1867 1868 dcb_size = sinfo->dcb_wsize * sizeof(uint32_t); 1869 tx_ring_size = dcb_size * (MAX_TX_DCBS + 1); 1870 rx_ring_size = dcb_size * (MAX_RX_DCBS + 1); 1871 sinfo->dcb_mem_size = tx_ring_size + rx_ring_size * sinfo->rx_chans; 1872 1873 sinfo->dcb_mem = DMA_ALLOC_COHERENT(sinfo->dma_dev, 1874 sinfo->dcb_mem_size, 1875 &dcb_dma); 1876 if (sinfo->dcb_mem == NULL) { 1877 gprintk("DCB memory allocation (%d bytes) failed.\n", 1878 sinfo->dcb_mem_size); 1879 return -ENOMEM; 1880 } 1881 sinfo->dcb_dma = (uint64_t)dcb_dma; 1882 1883 return 0; 1884 } 1885 1886 static void 1887 bkn_free_dcbs(bkn_switch_info_t *sinfo) 1888 { 1889 if (sinfo->dcb_mem != NULL) { 1890 DMA_FREE_COHERENT(sinfo->dma_dev, sinfo->dcb_mem_size, 1891 sinfo->dcb_mem, (dma_addr_t)sinfo->dcb_dma); 1892 sinfo->dcb_mem = NULL; 1893 } 1894 } 1895 1896 static void 1897 bkn_clean_tx_dcbs(bkn_switch_info_t *sinfo) 1898 { 1899 bkn_desc_info_t *desc; 1900 1901 DBG_DCB_TX(("Cleaning Tx DCBs (%d %d).\n", 1902 sinfo->tx.cur, sinfo->tx.dirty)); 1903 while (sinfo->tx.free < MAX_TX_DCBS) { 1904 desc = &sinfo->tx.desc[sinfo->tx.dirty]; 1905 if (desc->skb != NULL) { 1906 DBG_SKB(("Cleaning Tx SKB from DCB %d.\n", 1907 sinfo->tx.dirty)); 1908 DMA_UNMAP_SINGLE(sinfo->dma_dev, 1909 desc->skb_dma, desc->dma_size, 1910 DMA_TODEV); 1911 desc->skb_dma = 0; 1912 dev_kfree_skb_any(desc->skb); 1913 desc->skb = NULL; 1914 } 1915 if (++sinfo->tx.dirty >= MAX_TX_DCBS) { 1916 sinfo->tx.dirty = 0; 1917 } 1918 sinfo->tx.free++; 1919 } 1920 sinfo->tx.api_active = 0; 1921 DBG_DCB_TX(("Cleaned Tx DCBs (%d %d).\n", 1922 sinfo->tx.cur, sinfo->tx.dirty)); 1923 } 1924 1925 static void 1926 bkn_clean_rx_dcbs(bkn_switch_info_t *sinfo, int chan) 1927 { 1928 bkn_desc_info_t *desc; 1929 1930 DBG_DCB_RX(("Cleaning Rx%d DCBs (%d %d).\n", 1931 chan, sinfo->rx[chan].cur, sinfo->rx[chan].dirty)); 1932 while (sinfo->rx[chan].free) { 1933 desc = &sinfo->rx[chan].desc[sinfo->rx[chan].dirty]; 1934 if (desc->skb != NULL) { 1935 DBG_SKB(("Cleaning Rx%d SKB from DCB %d.\n", 1936 chan, sinfo->rx[chan].dirty)); 1937 DMA_UNMAP_SINGLE(sinfo->dma_dev, 1938 desc->skb_dma, desc->dma_size, 1939 DMA_FROMDEV); 1940 desc->skb_dma = 0; 1941 dev_kfree_skb_any(desc->skb); 1942 desc->skb = NULL; 1943 } 1944 if (++sinfo->rx[chan].dirty >= MAX_RX_DCBS) { 1945 sinfo->rx[chan].dirty = 0; 1946 } 1947 sinfo->rx[chan].free--; 1948 } 1949 sinfo->rx[chan].running = 0; 1950 sinfo->rx[chan].api_active = 0; 1951 DBG_DCB_RX(("Cleaned Rx%d DCBs (%d %d).\n", 1952 chan, sinfo->rx[chan].cur, sinfo->rx[chan].dirty)); 1953 } 1954 1955 static void 1956 bkn_clean_dcbs(bkn_switch_info_t *sinfo) 1957 { 1958 int chan; 1959 1960 bkn_clean_tx_dcbs(sinfo); 1961 1962 for (chan = 0; chan < sinfo->rx_chans; chan++) { 1963 bkn_clean_rx_dcbs(sinfo, chan); 1964 } 1965 } 1966 1967 static void 1968 bkn_init_dcbs(bkn_switch_info_t *sinfo) 1969 { 1970 int dcb_size; 1971 uint32_t *dcb_mem; 1972 uint64_t dcb_dma; 1973 bkn_desc_info_t *desc; 1974 int idx; 1975 int chan; 1976 1977 memset(sinfo->dcb_mem, 0, sinfo->dcb_mem_size); 1978 1979 dcb_size = sinfo->dcb_wsize * sizeof(uint32_t); 1980 dcb_mem = sinfo->dcb_mem; 1981 dcb_dma = sinfo->dcb_dma; 1982 1983 for (idx = 0; idx < (MAX_TX_DCBS + 1); idx++) { 1984 if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN)) { 1985 if (sinfo->cmic_type == 'x') { 1986 dcb_mem[2] |= 1 << 24 | 1 << 16; 1987 } else { 1988 dcb_mem[1] |= 1 << 24 | 1 << 16; 1989 } 1990 if (idx == MAX_TX_DCBS) { 1991 if (sinfo->cmic_type == 'x') { 1992 dcb_mem[0] = sinfo->tx.desc[0].dcb_dma; 1993 dcb_mem[1] = DMA_TO_BUS_HI(sinfo->tx.desc[0].dcb_dma >> 32); 1994 dcb_mem[2] |= 1 << 18; 1995 } else { 1996 dcb_mem[0] = sinfo->tx.desc[0].dcb_dma; 1997 dcb_mem[1] |= 1 << 18; 1998 } 1999 } 2000 } 2001 desc = &sinfo->tx.desc[idx]; 2002 desc->dcb_mem = dcb_mem; 2003 desc->dcb_dma = dcb_dma; 2004 dcb_mem += sinfo->dcb_wsize; 2005 dcb_dma += dcb_size; 2006 } 2007 sinfo->halt_addr[XGS_DMA_TX_CHAN] = sinfo->tx.desc[0].dcb_dma; 2008 sinfo->tx.free = MAX_TX_DCBS; 2009 sinfo->tx.cur = 0; 2010 sinfo->tx.dirty = 0; 2011 2012 DBG_DCB_TX(("Tx DCBs @ 0x%08x.\n", 2013 (uint32_t)sinfo->tx.desc[0].dcb_dma)); 2014 2015 for (chan = 0; chan < sinfo->rx_chans; chan++) { 2016 for (idx = 0; idx < (MAX_RX_DCBS + 1); idx++) { 2017 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 2018 if (sinfo->cmic_type == 'x') { 2019 dcb_mem[2] |= 1 << 24 | 1 << 16; 2020 } else { 2021 dcb_mem[1] |= 1 << 24 | 1 << 16; 2022 } 2023 if (idx == MAX_RX_DCBS) { 2024 if (sinfo->cmic_type == 'x') { 2025 dcb_mem[0] = sinfo->rx[chan].desc[0].dcb_dma; 2026 dcb_mem[1] = DMA_TO_BUS_HI(sinfo->rx[chan].desc[0].dcb_dma >> 32); 2027 dcb_mem[2] |= 1 << 18; 2028 } else { 2029 dcb_mem[0] = sinfo->rx[chan].desc[0].dcb_dma; 2030 dcb_mem[1] |= 1 << 18; 2031 } 2032 } 2033 } 2034 desc = &sinfo->rx[chan].desc[idx]; 2035 desc->dcb_mem = dcb_mem; 2036 desc->dcb_dma = dcb_dma; 2037 dcb_mem += sinfo->dcb_wsize; 2038 dcb_dma += dcb_size; 2039 } 2040 sinfo->halt_addr[XGS_DMA_RX_CHAN + chan] = sinfo->rx[chan].desc[MAX_RX_DCBS].dcb_dma; 2041 sinfo->rx[chan].free = 0; 2042 sinfo->rx[chan].cur = 0; 2043 sinfo->rx[chan].dirty = 0; 2044 2045 DBG_DCB_RX(("Rx%d DCBs @ 0x%08x.\n", 2046 chan, (uint32_t)sinfo->rx[chan].desc[0].dcb_dma)); 2047 } 2048 } 2049 2050 static void 2051 bkn_dump_dcb(char *prefix, uint32_t *dcb, int wsize, int txrx) 2052 { 2053 if (XGS_DMA_TX_CHAN == txrx) { 2054 if (wsize > 4) { 2055 DBG_DCB_TX(("%s: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x ... 0x%08x\n", 2056 prefix, dcb[0], dcb[1], dcb[2], dcb[3], dcb[4], dcb[5], 2057 dcb[wsize - 1])); 2058 } else { 2059 DBG_DCB_TX(("%s: 0x%08x 0x%08x 0x%08x 0x%08x\n", 2060 prefix, dcb[0], dcb[1], dcb[2], dcb[3])); 2061 } 2062 } else { 2063 if (wsize > 4) { 2064 DBG_DCB_RX(("%s: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x ... 0x%08x\n", 2065 prefix, dcb[0], dcb[1], dcb[2], dcb[3], dcb[4], dcb[5], 2066 dcb[wsize - 1])); 2067 } else { 2068 DBG_DCB_RX(("%s: 0x%08x 0x%08x 0x%08x 0x%08x\n", 2069 prefix, dcb[0], dcb[1], dcb[2], dcb[3])); 2070 } 2071 } 2072 } 2073 2074 static void 2075 bkn_dump_pkt(uint8_t *data, int size, int txrx) 2076 { 2077 int idx; 2078 char str[128]; 2079 2080 if (!(debug & DBG_LVL_PDMP) && 2081 !(txrx == XGS_DMA_TX_CHAN && debug & DBG_LVL_PDMP_TX) && 2082 !(txrx == XGS_DMA_RX_CHAN && debug & DBG_LVL_PDMP_RX)) { 2083 return; 2084 } 2085 2086 for (idx = 0; idx < size; idx++) { 2087 if ((idx & 0xf) == 0) { 2088 sprintf(str, "%04x: ", idx); 2089 } 2090 if ((idx & 0xf) == 8) { 2091 sprintf(&str[strlen(str)], "- "); 2092 } 2093 sprintf(&str[strlen(str)], "%02x ", data[idx]); 2094 if ((idx & 0xf) == 0xf) { 2095 sprintf(&str[strlen(str)], "\n"); 2096 gprintk(str); 2097 } 2098 } 2099 if ((idx & 0xf) != 0) { 2100 sprintf(&str[strlen(str)], "\n"); 2101 gprintk(str); 2102 } 2103 } 2104 2105 static bkn_switch_info_t * 2106 bkn_sinfo_from_unit(int unit) 2107 { 2108 struct list_head *list; 2109 bkn_switch_info_t *sinfo; 2110 2111 list_for_each(list, &_sinfo_list) { 2112 sinfo = (bkn_switch_info_t *)list; 2113 if (sinfo->dev_no == unit || unit == -1) { 2114 return sinfo; 2115 } 2116 } 2117 return NULL; 2118 } 2119 2120 static void 2121 bkn_cdma_goto(bkn_switch_info_t *sinfo, int chan, uint64_t dcb) 2122 { 2123 if (sinfo->basedev_suspended) { 2124 return; 2125 } 2126 2127 /* Set the new halt location */ 2128 sinfo->halt_addr[chan] = dcb; 2129 dev_cdma_halt_set(sinfo, chan); 2130 } 2131 2132 static void 2133 bkn_api_rx_restart(bkn_switch_info_t *sinfo, int chan) 2134 { 2135 bkn_dcb_chain_t *dcb_chain; 2136 int start_dma; 2137 2138 if (sinfo->basedev_suspended) { 2139 return; 2140 } 2141 2142 /* If resume from basedev suspended, there could be a suspended chain */ 2143 if (sinfo->rx[chan].api_dcb_chain) { 2144 return; 2145 } 2146 2147 /* Assume that driver lock is held */ 2148 if (!list_empty(&sinfo->rx[chan].api_dcb_list)) { 2149 dcb_chain = list_entry(sinfo->rx[chan].api_dcb_list.next, 2150 bkn_dcb_chain_t, list); 2151 start_dma = 0; 2152 if (sinfo->rx[chan].use_rx_skb == 0) { 2153 sinfo->rx[chan].chain_complete = 0; 2154 start_dma = 1; 2155 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan) && 2156 sinfo->rx[chan].api_active) { 2157 /* HW is running already, so we just move to the next chain */ 2158 start_dma = 0; 2159 } 2160 } 2161 sinfo->rx[chan].api_dcb_chain = dcb_chain; 2162 sinfo->rx[chan].api_active = 1; 2163 if (start_dma) { 2164 DBG_DCB_RX(("Start API Rx DMA, first DCB @ 0x%08x (%d DCBs).\n", 2165 (uint32_t)dcb_chain->dcb_dma, dcb_chain->dcb_cnt)); 2166 dev_dma_chan_clear(sinfo, XGS_DMA_RX_CHAN + chan); 2167 dev_irq_mask_enable(sinfo, XGS_DMA_RX_CHAN + chan, 1); 2168 dev_dma_chan_start(sinfo, XGS_DMA_RX_CHAN + chan, dcb_chain->dcb_dma); 2169 } 2170 2171 list_del(&dcb_chain->list); 2172 } 2173 } 2174 2175 static void 2176 bkn_api_rx_chain_done(bkn_switch_info_t *sinfo, int chan) 2177 { 2178 DBG_DCB_RX(("API Rx DMA chain done\n")); 2179 2180 if (!CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 2181 sinfo->rx[chan].api_active = 0; 2182 } 2183 if (sinfo->rx[chan].api_dcb_chain) { 2184 kfree(sinfo->rx[chan].api_dcb_chain); 2185 sinfo->rx[chan].api_dcb_chain = NULL; 2186 } 2187 bkn_api_rx_restart(sinfo, chan); 2188 } 2189 2190 static int 2191 bkn_api_rx_copy_from_skb(bkn_switch_info_t *sinfo, 2192 int chan, bkn_desc_info_t *desc) 2193 { 2194 bkn_dcb_chain_t *dcb_chain; 2195 uint32_t *dcb; 2196 uint32_t dcb_stat; 2197 uint8_t *pkt; 2198 uint64_t pkt_dma; 2199 int pktlen; 2200 int i; 2201 bkn_evt_resource_t *evt; 2202 2203 dcb_stat = desc->dcb_mem[sinfo->dcb_wsize-1]; 2204 pktlen = dcb_stat & SOC_DCB_KNET_COUNT_MASK; 2205 2206 dcb_chain = sinfo->rx[chan].api_dcb_chain; 2207 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan) && dcb_chain == NULL) { 2208 /* Last chain done, try to get a new one */ 2209 bkn_api_rx_chain_done(sinfo, chan); 2210 dcb_chain = sinfo->rx[chan].api_dcb_chain; 2211 } 2212 if (dcb_chain == NULL) { 2213 DBG_WARN(("No Rx API buffers\n")); 2214 sinfo->rx[chan].pkts_d_no_api_buf++; 2215 return -1; 2216 } 2217 dcb = &dcb_chain->dcb_mem[dcb_chain->dcb_cur * sinfo->dcb_wsize]; 2218 if ((sinfo->cmic_type == 'x' && (dcb[2] & 0xffff) < pktlen) || 2219 (sinfo->cmic_type != 'x' && (dcb[1] & 0xffff) < pktlen)) { 2220 DBG_WARN(("Rx API buffer too small\n")); 2221 return -1; 2222 } 2223 if (sinfo->cmic_type == 'x') { 2224 pkt_dma = BUS_TO_DMA_HI(dcb[1]); 2225 pkt_dma = pkt_dma << 32 | dcb[0]; 2226 } else { 2227 pkt_dma = dcb[0]; 2228 } 2229 pkt = (uint8_t *)kernel_bde->p2l(sinfo->dev_no, (sal_paddr_t)pkt_dma); 2230 if (pkt == NULL) { 2231 DBG_WARN(("Invalid Rx API buffer\n")); 2232 return -1; 2233 } 2234 2235 /* Copy packet data */ 2236 memcpy(pkt, desc->skb->data, pktlen); 2237 2238 /* Copy packet metadata and mark as done */ 2239 if (sinfo->cmic_type != 'x') { 2240 for (i = SOC_DCB_META_OFFSET; i < sinfo->dcb_wsize; i++) { 2241 dcb[i] = desc->dcb_mem[i]; 2242 } 2243 } 2244 dcb[sinfo->dcb_wsize-1] = dcb_stat | SOC_DCB_KNET_DONE; 2245 MEMORY_BARRIER; 2246 2247 dcb_chain->dcb_cur++; 2248 2249 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 2250 dcb = &dcb_chain->dcb_mem[dcb_chain->dcb_cur * sinfo->dcb_wsize]; 2251 if ((sinfo->cmic_type == 'x' && dcb[2] & (1 << 18)) || 2252 (sinfo->cmic_type != 'x' && dcb[1] & (1 << 18))) { 2253 /* Get the next chain if reload done */ 2254 dcb[sinfo->dcb_wsize-1] |= 1 << 31 | SOC_DCB_KNET_DONE; 2255 MEMORY_BARRIER; 2256 bkn_api_rx_chain_done(sinfo, chan); 2257 dcb_chain = sinfo->rx[chan].api_dcb_chain; 2258 if (dcb_chain == NULL) { 2259 sinfo->rx[chan].api_dcb_chain_end = NULL; 2260 } 2261 } 2262 } else { 2263 if ((sinfo->cmic_type == 'x' && (dcb[2] & (1 << 16)) == 0) || 2264 (sinfo->cmic_type != 'x' && (dcb[1] & (1 << 16)) == 0)) { 2265 bkn_api_rx_chain_done(sinfo, chan); 2266 } 2267 } 2268 2269 sinfo->dma_events |= KCOM_DMA_INFO_F_RX_DONE; 2270 2271 evt = &_bkn_evt[sinfo->evt_idx]; 2272 evt->evt_wq_put++; 2273 wake_up_interruptible(&evt->evt_wq); 2274 2275 return 0; 2276 } 2277 2278 static void 2279 bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) 2280 { 2281 struct sk_buff *skb; 2282 bkn_desc_info_t *desc; 2283 uint32_t *dcb; 2284 uint32_t resv_size = sinfo->cmic_type == 'x' ? RCPU_HDR_SIZE : RCPU_RX_ENCAP_SIZE; 2285 uint32_t meta_size = sinfo->cmic_type == 'x' ? RCPU_RX_META_SIZE : 0; 2286 int prev; 2287 2288 if (sinfo->rx[chan].use_rx_skb == 0) { 2289 /* Rx buffers are provided by BCM Rx API */ 2290 return; 2291 } 2292 2293 if (!CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan) && 2294 sinfo->rx[chan].tokens < MAX_RX_DCBS) { 2295 /* Pause DMA for now */ 2296 return; 2297 } 2298 2299 while (sinfo->rx[chan].free < MAX_RX_DCBS) { 2300 desc = &sinfo->rx[chan].desc[sinfo->rx[chan].cur]; 2301 if (desc->skb == NULL) { 2302 skb = dev_alloc_skb(rx_buffer_size + RCPU_RX_ENCAP_SIZE); 2303 if (skb == NULL) { 2304 break; 2305 } 2306 skb_reserve(skb, resv_size); 2307 desc->skb = skb; 2308 } else { 2309 DBG_DCB_RX(("Refill Rx%d SKB in DCB %d recycled.\n", 2310 chan, sinfo->rx[chan].cur)); 2311 } 2312 skb = desc->skb; 2313 desc->dma_size = rx_buffer_size + meta_size; 2314 #ifdef KNET_NO_AXI_DMA_INVAL 2315 /* 2316 * FIXME: Need to retain this code until iProc customers have been 2317 * migrated to updated u-boot. Old u-boot versions are unable to load 2318 * the kernel into non-ACP memory. 2319 */ 2320 /* 2321 * Cache invalidate may corrupt DMA memory on some iProc-based devices 2322 * if the kernel is mapped to ACP memory. 2323 */ 2324 if (sinfo->pdev == NULL) { 2325 desc->dma_size = 0; 2326 } 2327 #endif 2328 desc->skb_dma = DMA_MAP_SINGLE(sinfo->dma_dev, 2329 skb->data, desc->dma_size, 2330 DMA_FROMDEV); 2331 if (DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { 2332 dev_kfree_skb_any(skb); 2333 desc->skb = NULL; 2334 break; 2335 } 2336 DBG_DCB_RX(("Refill Rx%d DCB %d (0x%08x).\n", 2337 chan, sinfo->rx[chan].cur, (uint32_t)desc->skb_dma)); 2338 dcb = desc->dcb_mem; 2339 dcb[0] = desc->skb_dma; 2340 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 2341 if (sinfo->cmic_type == 'x') { 2342 dcb[2] |= 1 << 24 | 1 << 16; 2343 } else { 2344 dcb[1] |= 1 << 24 | 1 << 16; 2345 } 2346 } else { 2347 prev = PREV_IDX(sinfo->rx[chan].cur, MAX_RX_DCBS); 2348 if (prev < (MAX_RX_DCBS - 1)) { 2349 if (sinfo->cmic_type == 'x') { 2350 sinfo->rx[chan].desc[prev].dcb_mem[2] |= 1 << 16; 2351 } else { 2352 sinfo->rx[chan].desc[prev].dcb_mem[1] |= 1 << 16; 2353 } 2354 } 2355 } 2356 if (sinfo->cmic_type == 'x') { 2357 dcb[1] = DMA_TO_BUS_HI(desc->skb_dma >> 32); 2358 dcb[2] |= rx_buffer_size + meta_size; 2359 } else { 2360 dcb[1] |= rx_buffer_size; 2361 } 2362 2363 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan) && 2364 sinfo->rx[chan].tokens > MAX_RX_DCBS) { 2365 /* DMA run to the new halt location */ 2366 bkn_cdma_goto(sinfo, XGS_DMA_RX_CHAN + chan, desc->dcb_dma); 2367 } 2368 2369 if (++sinfo->rx[chan].cur >= MAX_RX_DCBS) { 2370 sinfo->rx[chan].cur = 0; 2371 } 2372 sinfo->rx[chan].free++; 2373 sinfo->rx[chan].tokens--; 2374 } 2375 } 2376 2377 static int 2378 bkn_rx_restart(bkn_switch_info_t *sinfo, int chan) 2379 { 2380 bkn_desc_info_t *desc; 2381 2382 if (sinfo->basedev_suspended) { 2383 return 0; 2384 } 2385 2386 if (sinfo->rx[chan].running) { 2387 return 0; 2388 } 2389 2390 if (sinfo->rx[chan].free < MAX_RX_DCBS) { 2391 return 1; 2392 } 2393 2394 desc = &sinfo->rx[chan].desc[sinfo->rx[chan].dirty]; 2395 sinfo->rx[chan].chain_complete = 0; 2396 DBG_DCB_RX(("Restart Rx%d DMA, DCB @ 0x%08x (%d).\n", 2397 chan, (uint32_t)desc->dcb_dma, sinfo->rx[chan].dirty)); 2398 dev_dma_chan_clear(sinfo, XGS_DMA_RX_CHAN + chan); 2399 dev_irq_mask_enable(sinfo, XGS_DMA_RX_CHAN + chan, 1); 2400 dev_dma_chan_start(sinfo, XGS_DMA_RX_CHAN + chan, desc->dcb_dma); 2401 sinfo->rx[chan].running = 1; 2402 2403 /* Request one extra poll if chain was restarted during poll */ 2404 if (sinfo->napi_poll_mode) { 2405 sinfo->napi_poll_again = 1; 2406 } 2407 2408 return 0; 2409 } 2410 2411 static int 2412 bkn_tx_dma_start(bkn_switch_info_t *sinfo) 2413 { 2414 bkn_desc_info_t *desc; 2415 2416 desc = &sinfo->tx.desc[sinfo->tx.cur]; 2417 if (sinfo->tx.free == MAX_TX_DCBS) { 2418 if (!sinfo->tx.api_active) { 2419 DBG_DCB_TX(("Start Tx DMA, DCB @ 0x%08x (%d).\n", 2420 (uint32_t)desc->dcb_dma, sinfo->tx.cur)); 2421 dev_dma_chan_clear(sinfo, XGS_DMA_TX_CHAN); 2422 dev_irq_mask_enable(sinfo, XGS_DMA_TX_CHAN, 1); 2423 dev_dma_chan_start(sinfo, XGS_DMA_TX_CHAN, desc->dcb_dma); 2424 } 2425 } 2426 2427 return 0; 2428 } 2429 2430 static int 2431 bkn_dma_init(bkn_switch_info_t *sinfo) 2432 { 2433 int chan; 2434 2435 dev_dma_chan_init(sinfo, XGS_DMA_TX_CHAN, 1); 2436 if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN)) { 2437 bkn_tx_dma_start(sinfo); 2438 } 2439 2440 for (chan = 0; chan < sinfo->rx_chans; chan++) { 2441 dev_dma_chan_init(sinfo, XGS_DMA_RX_CHAN + chan, 0); 2442 bkn_rx_refill(sinfo, chan); 2443 bkn_rx_restart(sinfo, chan); 2444 } 2445 2446 return 0; 2447 } 2448 2449 static int 2450 bkn_dma_abort_tx(bkn_switch_info_t *sinfo) 2451 { 2452 bkn_dcb_chain_t *dcb_chain; 2453 2454 DBG_VERB(("Aborting Tx DMA.\n")); 2455 2456 dev_irq_mask_disable(sinfo, XGS_DMA_TX_CHAN, 1); 2457 2458 dev_dma_chan_abort(sinfo, XGS_DMA_TX_CHAN, 10000); 2459 2460 if (sinfo->tx.api_dcb_chain) { 2461 DBG_DCB_TX(("Freeing active Tx DCB chain.\n")); 2462 kfree(sinfo->tx.api_dcb_chain); 2463 sinfo->tx.api_dcb_chain = NULL; 2464 } 2465 while (!list_empty(&sinfo->tx.api_dcb_list)) { 2466 dcb_chain = list_entry(sinfo->tx.api_dcb_list.next, 2467 bkn_dcb_chain_t, list); 2468 list_del(&dcb_chain->list); 2469 DBG_DCB_TX(("Freeing Tx DCB chain.\n")); 2470 kfree(dcb_chain); 2471 } 2472 sinfo->tx.api_dcb_chain_end = NULL; 2473 2474 return 0; 2475 } 2476 2477 static int 2478 bkn_dma_abort_rx(bkn_switch_info_t *sinfo, int chan) 2479 { 2480 bkn_dcb_chain_t *dcb_chain; 2481 2482 DBG_VERB(("Aborting Rx%d DMA.\n", chan)); 2483 2484 dev_irq_mask_disable(sinfo, XGS_DMA_RX_CHAN + chan, 1); 2485 2486 dev_dma_chan_abort(sinfo, XGS_DMA_RX_CHAN + chan, 10000); 2487 2488 if (sinfo->rx[chan].api_dcb_chain) { 2489 DBG_DCB_RX(("Freeing active Rx%d DCB chain.\n", chan)); 2490 kfree(sinfo->rx[chan].api_dcb_chain); 2491 sinfo->rx[chan].api_dcb_chain = NULL; 2492 } 2493 while (!list_empty(&sinfo->rx[chan].api_dcb_list)) { 2494 dcb_chain = list_entry(sinfo->rx[chan].api_dcb_list.next, 2495 bkn_dcb_chain_t, list); 2496 list_del(&dcb_chain->list); 2497 DBG_DCB_RX(("Freeing Rx%d DCB chain.\n", chan)); 2498 kfree(dcb_chain); 2499 } 2500 sinfo->rx[chan].api_dcb_chain_end = NULL; 2501 2502 return 0; 2503 } 2504 2505 static int 2506 bkn_dma_abort(bkn_switch_info_t *sinfo) 2507 { 2508 int chan; 2509 2510 bkn_dma_abort_tx(sinfo); 2511 2512 for (chan = 0; chan < sinfo->rx_chans; chan++) { 2513 bkn_dma_abort_rx(sinfo, chan); 2514 } 2515 2516 return 0; 2517 } 2518 2519 static int 2520 device_is_dpp(bkn_switch_info_t *sinfo) 2521 { 2522 int is_dpp = 0; 2523 2524 is_dpp = (sinfo->dcb_type == 28) ? 1 : 0; 2525 return is_dpp; 2526 } 2527 2528 static int 2529 device_is_dnx(bkn_switch_info_t *sinfo) 2530 { 2531 int is_dnx = 0; 2532 2533 /* No EP_TO_CPU header for DNX(JR2) */ 2534 is_dnx = ((sinfo->cmic_type == 'x') && (sinfo->pkt_hdr_size ==0)) ? 1 : 0; 2535 return is_dnx; 2536 } 2537 2538 /* is DPP or is DNX*/ 2539 static int 2540 device_is_sand(bkn_switch_info_t *sinfo) 2541 { 2542 int is_sand = 0; 2543 2544 if (device_is_dpp(sinfo) || device_is_dnx(sinfo)) { 2545 is_sand = 1; 2546 } 2547 return is_sand; 2548 } 2549 2550 static bkn_filter_t * 2551 bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, 2552 void *meta, int chan, bkn_filter_t *cbf) 2553 { 2554 struct list_head *list; 2555 bkn_filter_t *filter; 2556 kcom_filter_t scratch, *kf; 2557 uint8_t *oob = (uint8_t *)meta; 2558 int size, wsize; 2559 int idx, match; 2560 2561 list_for_each(list, &sinfo->rxpf_list) { 2562 filter = (bkn_filter_t *)list; 2563 kf = &filter->kf; 2564 memcpy(&scratch.data.b[0], 2565 &oob[kf->oob_data_offset], kf->oob_data_size); 2566 memcpy(&scratch.data.b[kf->oob_data_size], 2567 &pkt[kf->pkt_data_offset], kf->pkt_data_size); 2568 size = kf->oob_data_size + kf->pkt_data_size; 2569 wsize = BYTES2WORDS(size); 2570 DBG_VERB(("Filter: size = %d (%d), data = 0x%08x, mask = 0x%08x\n", 2571 size, wsize, kf->data.w[0], kf->mask.w[0])); 2572 2573 if (device_is_dnx(sinfo)) { 2574 DBG_DUNE(("Filter: size = %d (wsize %d)\n", size, wsize)); 2575 for (idx = 0; idx < wsize; idx++) 2576 { 2577 DBG_DUNE(("OOB[%d]: 0x%08x [0x%08x]\n", idx, kf->data.w[idx], kf->mask.w[idx])); 2578 } 2579 DBG_DUNE(("Meta Data [+ Selected Raw packet data]\n")); 2580 for (idx = 0; idx < wsize; idx++) 2581 { 2582 DBG_DUNE(("Scratch[%d]: 0x%08x\n", idx, scratch.data.w[idx])); 2583 } 2584 } 2585 2586 match = 1; 2587 if (match) { 2588 if (device_is_sand(sinfo)) 2589 { 2590 /** priority 0 means no priority check */ 2591 if (kf->priority && (kf->priority < (num_rx_prio * sinfo->rx_chans))) { 2592 if (kf->priority < (num_rx_prio * chan) || 2593 kf->priority >= (num_rx_prio * (chan + 1))) { 2594 match = 0; 2595 } 2596 } 2597 } 2598 else { 2599 if (kf->priority < (num_rx_prio * sinfo->rx_chans)) { 2600 if (kf->priority < (num_rx_prio * chan) || 2601 kf->priority >= (num_rx_prio * (chan + 1))) { 2602 match = 0; 2603 } 2604 } 2605 } 2606 } 2607 if (match) { 2608 for (idx = 0; idx < wsize; idx++) { 2609 scratch.data.w[idx] &= kf->mask.w[idx]; 2610 if (scratch.data.w[idx] != kf->data.w[idx]) { 2611 match = 0; 2612 break; 2613 } 2614 } 2615 } 2616 if (match) { 2617 if (kf->dest_type == KCOM_DEST_T_CB) { 2618 /* Check for custom filters */ 2619 if (knet_filter_cb != NULL && cbf != NULL) { 2620 memset(cbf, 0, sizeof(*cbf)); 2621 memcpy(&cbf->kf, kf, sizeof(cbf->kf)); 2622 if (knet_filter_cb(pkt, pktlen, sinfo->dev_no, 2623 meta, chan, &cbf->kf)) { 2624 filter->hits++; 2625 return cbf; 2626 } 2627 } else { 2628 DBG_FLTR(("Match, but not filter callback\n")); 2629 } 2630 } else { 2631 filter->hits++; 2632 return filter; 2633 } 2634 } 2635 } 2636 2637 return NULL; 2638 } 2639 2640 static bkn_priv_t * 2641 bkn_netif_lookup(bkn_switch_info_t *sinfo, int id) 2642 { 2643 struct list_head *list; 2644 bkn_priv_t *priv; 2645 int found; 2646 2647 /* Fast path */ 2648 if (id < sinfo->ndev_max) { 2649 if (sinfo->ndevs[id] != NULL) { 2650 DBG_NDEV(("Look up netif ID %d successful\n", id)); 2651 return netdev_priv(sinfo->ndevs[id]); 2652 } 2653 } 2654 2655 /* Slow path - should normally not get here */ 2656 found = 0; 2657 priv = NULL; 2658 list_for_each(list, &sinfo->ndev_list) { 2659 priv = (bkn_priv_t *)list; 2660 if (priv->id == id) { 2661 found = 1; 2662 break; 2663 } 2664 } 2665 if (found && priv != NULL) { 2666 return priv; 2667 } 2668 return NULL; 2669 } 2670 2671 static int 2672 bkn_hw_tstamp_rx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32 *meta) 2673 { 2674 struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); 2675 uint32_t *md = meta; 2676 uint64_t ts = 0; 2677 2678 switch (sinfo->dcb_type) { 2679 case 26: 2680 case 32: 2681 case 33: 2682 ts = md[14]; 2683 ts = ts << 32 | md[12]; 2684 break; 2685 case 36: 2686 ts = md[10]; 2687 break; 2688 case 38: 2689 ts = md[4] & 0xffff; 2690 ts = ts << 32 | md[5]; 2691 break; 2692 default: 2693 return -1; 2694 } 2695 2696 if (knet_hw_tstamp_rx_time_upscale_cb) { 2697 if (knet_hw_tstamp_rx_time_upscale_cb(sinfo->dev_no, &ts) < 0) { 2698 return -1; 2699 } 2700 } 2701 2702 memset(shhwtstamps, 0, sizeof(*shhwtstamps)); 2703 shhwtstamps->hwtstamp = ns_to_ktime(be64_to_cpu(ts)); 2704 2705 return 0; 2706 } 2707 2708 static int 2709 bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta) 2710 { 2711 int pktlen = skb->len; 2712 uint32_t *dmeta, *smeta, wsize, psize; 2713 int idx; 2714 2715 /* Add and clear RCPU encapsulation */ 2716 if (sinfo->cmic_type == 'x') { 2717 psize = RCPU_HDR_SIZE + sinfo->pkt_hdr_size; 2718 skb_push(skb, psize); 2719 memset(skb->data, 0, RCPU_HDR_SIZE); 2720 } else { 2721 psize = RCPU_RX_ENCAP_SIZE; 2722 skb_push(skb, psize); 2723 memset(skb->data, 0, RCPU_RX_ENCAP_SIZE); 2724 } 2725 2726 /* RCPU Header */ 2727 memcpy(skb->data, &skb->data[psize], 12); 2728 if (rcpu_dmac != NULL) { 2729 memcpy(skb->data, bkn_rcpu_dmac, 6); 2730 } 2731 if (rcpu_smac != NULL) { 2732 memcpy(&skb->data[6], bkn_rcpu_smac, 6); 2733 } 2734 skb->data[12] = 0x81; 2735 skb->data[14] = rcpu_vlan >> 8; 2736 skb->data[15] = rcpu_vlan & 0xff; 2737 skb->data[16] = rcpu_ethertype >> 8; 2738 skb->data[17] = rcpu_ethertype & 0xff; 2739 skb->data[18] = sinfo->rcpu_sig >> 8; 2740 skb->data[19] = sinfo->rcpu_sig & 0xff; 2741 skb->data[20] = RCPU_OPCODE_RX; 2742 skb->data[21] = RCPU_F_MODHDR; 2743 skb->data[24] = pktlen >> 8; 2744 skb->data[25] = pktlen & 0xff; 2745 2746 /* Meta data */ 2747 dmeta = (uint32_t *)&skb->data[RCPU_HDR_SIZE]; 2748 smeta = sinfo->cmic_type == 'x' ? (uint32_t *)meta : (uint32_t *)meta + 2; 2749 wsize = sinfo->cmic_type == 'x' ? sinfo->pkt_hdr_size / 4 : sinfo->dcb_wsize - 3; 2750 for (idx = 0; idx < wsize; idx++) { 2751 dmeta[idx] = htonl(smeta[idx]); 2752 } 2753 2754 return 0; 2755 } 2756 2757 static void 2758 bkn_eth_type_update(struct sk_buff *skb, int ethertype) 2759 { 2760 #if defined(PM_ETH_TYPE) && defined(PM_FC_TYPE) 2761 /* Optionally override standard protocol */ 2762 skb->protocol = PM_ETH_TYPE; 2763 if (ethertype == ETH_P_FCOE) { 2764 skb->protocol = PM_FC_TYPE; 2765 } 2766 #endif 2767 } 2768 2769 #define BKN_DNX_BIT(x) (1<<(x)) 2770 #define BKN_DNX_RBIT(x) (~(1<<(x))) 2771 #ifdef __LITTLE_ENDIAN 2772 #define BKN_DNX_BYTE_SWAP(x) (x) 2773 #else 2774 #define BKN_DNX_BYTE_SWAP(x) ((((x) << 24)) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24))) 2775 #endif 2776 2777 static int 2778 packet_is_untagged(uint16_t tpid) 2779 { 2780 int is_untagged = 0; 2781 2782 /* Fixme SDK-111398 */ 2783 /* 0x8100 is used in 802.1Q */ 2784 /* 0x8848 is used in 802.11ad, the dtag tpid can be set to anything besides 0x8848, 0x9100 is a typical value, but couldn't cover all scenarios. */ 2785 is_untagged = ((tpid != 0x8100) && (tpid != 0x8848) && (tpid != 0x9100)); 2786 return is_untagged; 2787 } 2788 2789 static void 2790 bkn_bitstream_set_field(uint32_t *input_buffer, uint32_t start_bit, uint32_t nof_bits, uint32_t field) 2791 { 2792 uint32_t place; 2793 uint32_t field_bit_i; 2794 uint32_t bit_indicator; 2795 2796 if( nof_bits > 32) 2797 { 2798 return; 2799 } 2800 2801 for( place=start_bit, field_bit_i = 0; field_bit_i< nof_bits; ++place, ++field_bit_i) 2802 { 2803 bit_indicator = field & BKN_DNX_BIT(nof_bits-field_bit_i-1); 2804 if(bit_indicator) 2805 { 2806 input_buffer[place>>5] |= (0x80000000 >> (place & 0x0000001F)); 2807 } 2808 else 2809 { 2810 input_buffer[place>>5] &= ~(0x80000000 >> (place & 0x0000001F)); 2811 } 2812 } 2813 return; 2814 } 2815 2816 static void 2817 bkn_bitstream_get_field(uint8_t *input_buffer, uint32_t start_bit, uint32_t nof_bits, uint32_t *output_value) 2818 { 2819 uint32_t idx; 2820 uint32_t buf_sizes=0; 2821 uint32_t tmp_output_value[2]={0}; 2822 uint32_t first_byte_ndx; 2823 uint32_t last_byte_ndx; 2824 uint32_t place; 2825 uint32_t field_bit_i; 2826 uint8_t *tmp_output_value_u8_ptr = (uint8_t*)&tmp_output_value; 2827 uint32_t bit_indicator; 2828 2829 if (nof_bits > 32) 2830 { 2831 return; 2832 } 2833 2834 first_byte_ndx = start_bit / 8; 2835 last_byte_ndx = ((start_bit + nof_bits - 1) / 8); 2836 *output_value=0; 2837 2838 /* get 32 bit value, MSB */ 2839 for (idx = first_byte_ndx; idx <= last_byte_ndx; ++idx) 2840 { 2841 tmp_output_value_u8_ptr[last_byte_ndx - idx] = input_buffer[idx]; 2842 buf_sizes += 8; 2843 } 2844 tmp_output_value[0] = BKN_DNX_BYTE_SWAP(tmp_output_value[0]); 2845 if (last_byte_ndx > 4) 2846 { 2847 tmp_output_value[1] = BKN_DNX_BYTE_SWAP(tmp_output_value[1]); 2848 } 2849 2850 place = buf_sizes - (start_bit % 8 + nof_bits); 2851 for (field_bit_i = 0; field_bit_i< nof_bits; ++place, ++field_bit_i) 2852 { 2853 uint32_t result; 2854 result = tmp_output_value[place>>5] & BKN_DNX_BIT(place & 0x0000001F); 2855 if (result) 2856 { 2857 bit_indicator = 1; 2858 } else { 2859 bit_indicator = 0; 2860 } 2861 *output_value |= bit_indicator << field_bit_i; 2862 } 2863 return; 2864 } 2865 2866 static void 2867 bkn_dpp_packet_parse_ftmh(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) 2868 { 2869 uint32_t header_ptr = 0; 2870 uint32_t dsp_ext_exist=0; 2871 uint32_t fld_val; 2872 2873 header_ptr = packet_info->ntwrk_header_ptr; 2874 2875 /* Packet-size */ 2876 bkn_bitstream_get_field( 2877 &hdr_buff[header_ptr], 2878 BKN_DPP_FTMH_PKT_SIZE_MSB, 2879 BKN_DPP_FTMH_PKT_SIZE_NOF_BITS, 2880 &fld_val); 2881 packet_info->ftmh.packet_size = fld_val; 2882 /* Traffic-class */ 2883 bkn_bitstream_get_field( 2884 &hdr_buff[header_ptr], 2885 BKN_DPP_FTMH_TC_MSB, 2886 BKN_DPP_FTMH_TC_NOF_BITS, 2887 &fld_val); 2888 packet_info->ftmh.prio = fld_val; 2889 /* Source-system-port-aggregate */ 2890 bkn_bitstream_get_field( 2891 &hdr_buff[header_ptr], 2892 BKN_DPP_FTMH_SRC_SYS_PORT_MSB, 2893 BKN_DPP_FTMH_SRC_SYS_PORT_NOF_BITS, 2894 &fld_val); 2895 packet_info->ftmh.src_sys_port = fld_val; 2896 /* TM-action-type */ 2897 bkn_bitstream_get_field( 2898 &hdr_buff[header_ptr], 2899 BKN_DPP_FTMH_ACTION_TYPE_MSB, 2900 BKN_DPP_FTMH_ACTION_TYPE_NOF_BITS, 2901 &fld_val); 2902 packet_info->ftmh.action_type = fld_val; 2903 /* PPH-type */ 2904 bkn_bitstream_get_field( 2905 &hdr_buff[header_ptr], 2906 BKN_DPP_FTMH_PPH_TYPE_MSB, 2907 BKN_DPP_FTMH_PPH_TYPE_NOF_BITS, 2908 &fld_val); 2909 packet_info->ftmh.pph_type = fld_val; 2910 2911 packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_SIZE_BYTE; 2912 DBG_DUNE(("FTMH(%d) Packet-size %d Action-type %d PPH-type %d Source-system-port 0x%x Traffic-class %d\n", 2913 packet_info->ntwrk_header_ptr, packet_info->ftmh.packet_size, packet_info->ftmh.action_type, 2914 packet_info->ftmh.pph_type, packet_info->ftmh.src_sys_port, packet_info->ftmh.prio)); 2915 2916 /* LB-Key ext */ 2917 if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_LB_EXT_EN) == BKN_DPP_FTMH_LB_EXT_EN) 2918 { 2919 packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_LB_EXT_SIZE_BYTE; 2920 DBG_DUNE(("FTMH(%d) FTMH LB-Key Extension is present\n", packet_info->ntwrk_header_ptr)); 2921 } 2922 /* DSP ext*/ 2923 fld_val = 0; 2924 bkn_bitstream_get_field( 2925 &hdr_buff[header_ptr], 2926 BKN_DPP_FTMH_EXT_DSP_EXIST_MSB, 2927 BKN_DPP_FTMH_EXT_DSP_EXIST_NOF_BITS, 2928 &dsp_ext_exist); 2929 if (dsp_ext_exist) 2930 { 2931 packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_DEST_EXT_SIZE_BYTE; 2932 DBG_DUNE(("FTMH(%d) DSP-extension-present 1\n", packet_info->ntwrk_header_ptr)); 2933 } 2934 2935 /* stacking ext */ 2936 if ((sinfo->pkt_hdr_size & BKN_DPP_FTMH_STACKING_EXT_EN) == BKN_DPP_FTMH_STACKING_EXT_EN) 2937 { 2938 packet_info->ntwrk_header_ptr += BKN_DPP_FTMH_STACKING_SIZE_BYTE; 2939 DBG_DUNE(("FTMH(%d) FTMH Stacking Extension is present\n", packet_info->ntwrk_header_ptr)); 2940 } 2941 return; 2942 } 2943 2944 static void 2945 bkn_dpp_packet_parse_internal(bkn_switch_info_t *sinfo, uint8_t hdr_buff[], bkn_dune_system_header_info_t *packet_info) 2946 { 2947 uint32_t header_ptr = 0; 2948 uint32_t fld_val; 2949 uint32_t eei_extension_present = 0; 2950 uint32_t learn_extension_present = 0; 2951 uint32_t fhei_size = 0; 2952 uint32_t forward_code; 2953 uint8_t is_trapped = 0; 2954 2955 header_ptr = packet_info->ntwrk_header_ptr; 2956 2957 bkn_bitstream_get_field( 2958 &hdr_buff[header_ptr], 2959 BKN_DPP_PPH_EEI_EXTENSION_PRESENT_MSB, 2960 BKN_DPP_PPH_EEI_EXTENSION_PRESENT_NOF_BITS, 2961 &eei_extension_present); 2962 bkn_bitstream_get_field( 2963 &hdr_buff[header_ptr], 2964 BKN_DPP_PPH_LEARN_EXENSION_PRESENT_MSB, 2965 BKN_DPP_PPH_LEARN_EXENSION_PRESENT_NOF_BITS, 2966 &learn_extension_present); 2967 bkn_bitstream_get_field( 2968 &hdr_buff[header_ptr], 2969 BKN_DPP_PPH_FHEI_SIZE_MSB, 2970 BKN_DPP_PPH_FHEI_SIZE_NOF_BITS, 2971 &fhei_size); 2972 bkn_bitstream_get_field( 2973 &hdr_buff[header_ptr], 2974 BKN_DPP_PPH_FORWARD_CODE_MSB, 2975 BKN_DPP_PPH_FORWARD_CODE_NOF_BITS, 2976 &forward_code); 2977 /* 7: CPU-Trap */ 2978 is_trapped = (uint8_t)(forward_code == 7); 2979 2980 bkn_bitstream_get_field( 2981 &hdr_buff[header_ptr], 2982 BKN_DPP_PPH_VSI_MSB, 2983 BKN_DPP_PPH_VSI_NOF_BITS, 2984 &fld_val); 2985 packet_info->internal.vsi = fld_val; 2986 2987 /* size of PPH base is 7 */ 2988 packet_info->ntwrk_header_ptr += BKN_DPP_PPH_SIZE_BYTE; 2989 header_ptr = packet_info->ntwrk_header_ptr; 2990 2991 DBG_DUNE(("PPH(%d) Forward-Code %d EEI-Extension %d Learn-Extension %d VSI %d FHEI-size %d\n", packet_info->ntwrk_header_ptr, 2992 forward_code, eei_extension_present, learn_extension_present, packet_info->internal.vsi, fhei_size)); 2993 2994 /* PPH extension */ 2995 if (is_trapped && (fhei_size == 1)) 2996 { 2997 /* CPU trap code qualifier */ 2998 bkn_bitstream_get_field( 2999 &hdr_buff[header_ptr], 3000 BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_MSB, 3001 BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_QUALIFIER_NOF_BITS, 3002 &fld_val); 3003 packet_info->internal.trap_qualifier = fld_val; 3004 /* CPU trap code */ 3005 bkn_bitstream_get_field( 3006 &hdr_buff[header_ptr], 3007 BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_MSB, 3008 BKN_DPP_PPH_FHEI_TRAP_SNOOP_3B_CPU_TRAP_CODE_NOF_BITS, 3009 &fld_val); 3010 packet_info->internal.trap_id = fld_val; 3011 } 3012 switch(fhei_size) { 3013 case 1: 3014 packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_3B_SIZE_BYTE; 3015 break; 3016 case 2: 3017 packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_5B_SIZE_BYTE; 3018 break; 3019 case 3: 3020 packet_info->ntwrk_header_ptr += BKN_DPP_PPH_FHEI_8B_SIZE_BYTE; 3021 break; 3022 default: 3023 break; 3024 } 3025 if (eei_extension_present) { 3026 packet_info->ntwrk_header_ptr += BKN_DPP_PPH_EXPLICIT_EDITING_INFOMATION_EXTENSION_SIZE_BYTE; 3027 } 3028 if (learn_extension_present) { 3029 packet_info->ntwrk_header_ptr += BKN_DPP_PPH_LEARN_EXTENSION_SIZE_BYTE; 3030 } 3031 3032 DBG_DUNE(("FHEI(%d) trap_qualifier 0x%x trap_id 0x%x\n", packet_info->ntwrk_header_ptr, packet_info->internal.trap_qualifier, packet_info->internal.trap_id)); 3033 return; 3034 } 3035 3036 static int 3037 bkn_dpp_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buff, uint32_t buff_len, bkn_dune_system_header_info_t *packet_info) 3038 { 3039 uint8_t hdr_buff[BKN_DPP_HDR_MAX_SIZE]; 3040 uint32_t hdr_size; 3041 uint8_t has_internal = 0; 3042 3043 if ((buff == NULL) || (packet_info == NULL)) { 3044 return -1; 3045 } 3046 hdr_size = buff_len < BKN_DPP_HDR_MAX_SIZE ? buff_len: BKN_DPP_HDR_MAX_SIZE; 3047 memcpy(hdr_buff, buff, hdr_size); 3048 3049 /* FTMH */ 3050 bkn_dpp_packet_parse_ftmh(sinfo, hdr_buff, packet_info); 3051 if (packet_info->ftmh.packet_size != (buff_len + 2)) { 3052 DBG_DUNE(("FTMH packet size verfication failed, %d-%d\n", packet_info->ftmh.packet_size, buff_len)); 3053 memset(packet_info, 0, sizeof(bkn_dune_system_header_info_t)); 3054 return -1; 3055 } 3056 switch (packet_info->ftmh.pph_type) { 3057 case 0: 3058 has_internal = 0; 3059 break; 3060 case 1: 3061 has_internal = 1; 3062 break; 3063 case 2: /* PPH OAM-TS only */ 3064 case 3: /* PPH Base + OAM-TS */ 3065 /* OTSH immediately follows the FTMH when present */ 3066 packet_info->ntwrk_header_ptr += 6; 3067 DBG_DUNE(("FTMH + OAM-TS(%d)\n", packet_info->ntwrk_header_ptr)); 3068 has_internal = 1; 3069 break; 3070 default: 3071 break; 3072 } 3073 3074 if (has_internal) { 3075 bkn_dpp_packet_parse_internal(sinfo, &hdr_buff[0], packet_info); 3076 } 3077 3078 /* FIXME: */ 3079 /* ignore packets with a double set of FTMH,internals */ 3080 /* ignore the user header size */ 3081 return 0; 3082 } 3083 3084 static int 3085 bkn_dnx_packet_header_parse(bkn_switch_info_t *sinfo, uint8 *buf, uint32_t buf_len, bkn_dune_system_header_info_t *packet_info) 3086 { 3087 uint32_t fld_val; 3088 uint32_t hdr_size = 0; 3089 uint32_t pkt_offset_ingress_untrapped =0; 3090 uint8_t tm_dst_ext_present = 0; 3091 uint8_t app_specific_ext_size = 0; 3092 uint8_t flow_id_ext_size = 0; 3093 uint8_t bier_bfr_ext_size = 0; 3094 uint8_t is_pph_en = 0; 3095 uint8_t is_tsh_en = 0; 3096 3097 if ((buf == NULL) || (packet_info == NULL)) { 3098 return -1; 3099 } 3100 3101 /* FTMH: Source-System-Port-Aggregate */ 3102 bkn_bitstream_get_field( 3103 &buf[hdr_size], 3104 BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_MSB, 3105 BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_NOF_BITS, 3106 &fld_val); 3107 packet_info->ftmh_spa = fld_val; 3108 /* FTMH: PPH-Type TSH */ 3109 bkn_bitstream_get_field( 3110 &buf[hdr_size], 3111 BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_MSB, 3112 BKN_DNX_FTMH_PPH_TYPE_IS_TSH_EN_NOF_BITS, 3113 &fld_val); 3114 is_tsh_en = fld_val; 3115 /* FTMH: PPH-Type PPH base */ 3116 bkn_bitstream_get_field( 3117 &buf[hdr_size], 3118 BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_MSB, 3119 BKN_DNX_FTMH_PPH_TYPE_IS_PPH_EN_NOF_BITS, 3120 &fld_val); 3121 is_pph_en = fld_val; 3122 /* FTMH: TM-Destination-Extension-Present */ 3123 bkn_bitstream_get_field( 3124 &buf[hdr_size], 3125 BKN_DNX_FTMH_TM_DST_EXT_PRESENT_MSB, 3126 BKN_DNX_FTMH_TM_DST_EXT_PRESENT_NOF_BITS, 3127 &fld_val); 3128 tm_dst_ext_present = fld_val; 3129 /* FTMH: Application-Specific-Extension-Size */ 3130 bkn_bitstream_get_field( 3131 &buf[hdr_size], 3132 BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_MSB, 3133 BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE_NOF_BITS, 3134 &fld_val); 3135 app_specific_ext_size = fld_val; 3136 /* FTMH: Flow-ID-Extension-Size */ 3137 bkn_bitstream_get_field( 3138 &buf[hdr_size], 3139 BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_MSB, 3140 BKN_DNX_FTMH_FLOW_ID_EXT_SIZE_NOF_BITS, 3141 &fld_val); 3142 flow_id_ext_size = fld_val; 3143 /* FTMH: BIER-BFR-Extension-Size */ 3144 bkn_bitstream_get_field( 3145 &buf[hdr_size], 3146 BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_MSB, 3147 BKN_DNX_FTMH_BIER_BFR_EXT_SIZE_NOF_BITS, 3148 &fld_val); 3149 bier_bfr_ext_size = fld_val; 3150 3151 hdr_size = BKN_DNX_FTMH_BASE_SIZE; 3152 pkt_offset_ingress_untrapped = BKN_DNX_FTMH_BASE_SIZE; 3153 3154 DBG_DUNE(("FTMH(%d) source-system-port 0x%x is_tsh_en %d is_pph_en %d\n", 3155 hdr_size, packet_info->ftmh_spa, is_tsh_en, is_pph_en)); 3156 3157 /* FTMH LB-Key Extension */ 3158 if (sinfo->ftmh_lb_key_ext_size > 0) 3159 { 3160 hdr_size += sinfo->ftmh_lb_key_ext_size; 3161 DBG_DUNE(("FTMH LB-Key Extension(%d) is present\n", sinfo->ftmh_lb_key_ext_size)); 3162 } 3163 /* FTMH Stacking Extension */ 3164 if (sinfo->ftmh_stacking_ext_size > 0) 3165 { 3166 hdr_size += sinfo->ftmh_stacking_ext_size; 3167 DBG_DUNE(("FTMH Stacking Extension(%d) is present\n", sinfo->ftmh_stacking_ext_size)); 3168 } 3169 /* FTMH BIER BFR Extension */ 3170 if (bier_bfr_ext_size > 0) 3171 { 3172 hdr_size += BKN_DNX_FTMH_BIER_BFR_EXT_SIZE; 3173 DBG_DUNE(("FTMH BIER BFR Extension(2) is present\n")); 3174 } 3175 /* FTMH TM Destination Extension */ 3176 if (tm_dst_ext_present > 0) 3177 { 3178 hdr_size += BKN_DNX_FTMH_TM_DST_EXT_SIZE; 3179 DBG_DUNE(("FTMH TM Destination Extension(3) is present\n")); 3180 } 3181 /* FTMH Application Specific Extension */ 3182 if (app_specific_ext_size > 0) 3183 { 3184 hdr_size += BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE; 3185 DBG_DUNE(("FTMH Application Specific Extension(6) is present\n")); 3186 } 3187 /* FTMH Flow-ID Extension */ 3188 if (flow_id_ext_size > 0) 3189 { 3190 hdr_size += BKN_DNX_FTMH_FLOW_ID_EXT_SIZE; 3191 DBG_DUNE(("FTMH Flow-ID Extension(3) is present\n")); 3192 } 3193 3194 /* Given the packet is trapped to CPU */ 3195 3196 /* Time-Stamp Header */ 3197 if (is_tsh_en == TRUE) 3198 { 3199 hdr_size += BKN_DNX_TSH_SIZE; 3200 DBG_DUNE(("Time-Stamp Header(4) is present\n")); 3201 } 3202 3203 /* Packet Processing Header */ 3204 if (is_pph_en) 3205 { 3206 uint8_t learn_ext_present; 3207 uint8_t fhei_size; 3208 uint8_t lif_ext_type; 3209 3210 switch (sinfo->pph_base_size) 3211 { 3212 case BKN_DNX_PPH_BASE_TYPE_9: 3213 /* FTMH: Forward-Domain */ 3214 bkn_bitstream_get_field( 3215 &buf[hdr_size], 3216 BKN_DNX_PPH_9_FORWARD_DOMAIN_MSB, 3217 BKN_DNX_PPH_9_FORWARD_DOMAIN_NOF_BITS, 3218 &fld_val); 3219 packet_info->pph_forward_domain = fld_val; 3220 /* FTMH: Learn-Extension-Present */ 3221 bkn_bitstream_get_field( 3222 &buf[hdr_size], 3223 BKN_DNX_PPH_9_LEARN_EXT_PRESENT_MSB, 3224 BKN_DNX_PPH_9_LEARN_EXT_PRESENT_NOF_BITS, 3225 &fld_val); 3226 learn_ext_present = fld_val; 3227 /* FTMH: FHEI-Size */ 3228 bkn_bitstream_get_field( 3229 &buf[hdr_size], 3230 BKN_DNX_PPH_9_FHEI_SIZE_MSB, 3231 BKN_DNX_PPH_9_FHEI_SIZE_NOF_BITS, 3232 &fld_val); 3233 fhei_size = fld_val; 3234 /* FTMH: LIF-Extension-Type */ 3235 bkn_bitstream_get_field( 3236 &buf[hdr_size], 3237 BKN_DNX_PPH_9_LIF_EXT_TYPE_MSB, 3238 BKN_DNX_PPH_9_LIF_EXT_TYPE_NOF_BITS, 3239 &fld_val); 3240 lif_ext_type = fld_val; 3241 3242 hdr_size += BKN_DNX_PPH_BASE_TYPE_9; 3243 DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", 3244 packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); 3245 break; 3246 case BKN_DNX_PPH_BASE_TYPE_10: 3247 /* FTMH: Forward-Domain */ 3248 bkn_bitstream_get_field( 3249 &buf[hdr_size], 3250 BKN_DNX_PPH_10_FORWARD_DOMAIN_MSB, 3251 BKN_DNX_PPH_10_FORWARD_DOMAIN_NOF_BITS, 3252 &fld_val); 3253 packet_info->pph_forward_domain = fld_val; 3254 /* FTMH: Learn-Extension-Present */ 3255 bkn_bitstream_get_field( 3256 &buf[hdr_size], 3257 BKN_DNX_PPH_10_LEARN_EXT_PRESENT_MSB, 3258 BKN_DNX_PPH_10_LEARN_EXT_PRESENT_NOF_BITS, 3259 &fld_val); 3260 learn_ext_present = fld_val; 3261 /* FTMH: FHEI-Size */ 3262 bkn_bitstream_get_field( 3263 &buf[hdr_size], 3264 BKN_DNX_PPH_10_FHEI_SIZE_MSB, 3265 BKN_DNX_PPH_10_FHEI_SIZE_NOF_BITS, 3266 &fld_val); 3267 fhei_size = fld_val; 3268 /* FTMH: LIF-Extension-Type */ 3269 bkn_bitstream_get_field( 3270 &buf[hdr_size], 3271 BKN_DNX_PPH_10_LIF_EXT_TYPE_MSB, 3272 BKN_DNX_PPH_10_LIF_EXT_TYPE_NOF_BITS, 3273 &fld_val); 3274 lif_ext_type = fld_val; 3275 3276 hdr_size += BKN_DNX_PPH_BASE_TYPE_10; 3277 DBG_DUNE(("PPH(10) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", 3278 packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); 3279 break; 3280 case BKN_DNX_PPH_BASE_TYPE_12: 3281 /* FTMH: Forward-Domain */ 3282 bkn_bitstream_get_field( 3283 &buf[hdr_size], 3284 BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, 3285 BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, 3286 &fld_val); 3287 packet_info->pph_forward_domain = fld_val; 3288 /* FTMH: Learn-Extension-Present */ 3289 bkn_bitstream_get_field( 3290 &buf[hdr_size], 3291 BKN_DNX_PPH_12_LEARN_EXT_PRESENT_MSB, 3292 BKN_DNX_PPH_12_LEARN_EXT_PRESENT_NOF_BITS, 3293 &fld_val); 3294 learn_ext_present = fld_val; 3295 /* FTMH: FHEI-Size */ 3296 bkn_bitstream_get_field( 3297 &buf[hdr_size], 3298 BKN_DNX_PPH_12_FHEI_SIZE_MSB, 3299 BKN_DNX_PPH_12_FHEI_SIZE_NOF_BITS, 3300 &fld_val); 3301 fhei_size = fld_val; 3302 /* FTMH: LIF-Extension-Type */ 3303 bkn_bitstream_get_field( 3304 &buf[hdr_size], 3305 BKN_DNX_PPH_12_LIF_EXT_TYPE_MSB, 3306 BKN_DNX_PPH_12_LIF_EXT_TYPE_NOF_BITS, 3307 &fld_val); 3308 lif_ext_type = fld_val; 3309 3310 hdr_size += BKN_DNX_PPH_BASE_TYPE_12; 3311 DBG_DUNE(("PPH(12) FWD_DOMAIN %d, LEARN_EXT %d, FHEI_SIZE %d, LIF_EXT %d \n", 3312 packet_info->pph_forward_domain, learn_ext_present, fhei_size, lif_ext_type)); 3313 break; 3314 default: 3315 fhei_size = 0; 3316 lif_ext_type = 0; 3317 learn_ext_present = 0; 3318 break; 3319 } 3320 if (fhei_size) 3321 { 3322 switch (fhei_size) 3323 { 3324 case BKN_DNX_PPH_FHEI_TYPE_SZ0: 3325 hdr_size += BKN_DNX_PPH_FHEI_SZ0_SIZE; 3326 DBG_DUNE(("FHEI(3) is present\n")); 3327 break; 3328 case BKN_DNX_PPH_FHEI_TYPE_SZ1: 3329 /* FHEI: Code */ 3330 bkn_bitstream_get_field( 3331 &buf[hdr_size], 3332 BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_MSB, 3333 BKN_DNX_PPH_FHEI_TRAP_5B_TYPE_NOF_BITS, 3334 &fld_val); 3335 packet_info->fhei_type = fld_val; 3336 /* FHEI-Size == 5B, FHEI-Type == Trap/Sniff */ 3337 if (packet_info->fhei_type == 0x5) 3338 { 3339 /* FHEI: Qualifier */ 3340 bkn_bitstream_get_field( 3341 &buf[hdr_size], 3342 BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_MSB, 3343 BKN_DNX_PPH_FHEI_TRAP_5B_QUALIFIER_NOF_BITS, 3344 &fld_val); 3345 packet_info->fhei_qualifier = fld_val; 3346 /* FHEI: Code */ 3347 bkn_bitstream_get_field( 3348 &buf[hdr_size], 3349 BKN_DNX_PPH_FHEI_TRAP_5B_CODE_MSB, 3350 BKN_DNX_PPH_FHEI_TRAP_5B_CODE_NOF_BITS, 3351 &fld_val); 3352 packet_info->fhei_code = fld_val; 3353 } 3354 hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; 3355 DBG_DUNE(("FHEI(5) is present code 0x%x qualifier 0x%x\n", packet_info->fhei_code, packet_info->fhei_qualifier)); 3356 break; 3357 case BKN_DNX_PPH_FHEI_TYPE_SZ2: 3358 hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; 3359 DBG_DUNE(("FHEI(8) is present\n")); 3360 break; 3361 } 3362 } 3363 3364 /* PPH LIF Extension */ 3365 if (lif_ext_type) 3366 { 3367 hdr_size += sinfo->pph_lif_ext_size[lif_ext_type]; 3368 DBG_DUNE(("PPH LIF Extension(%d) is present\n", sinfo->pph_lif_ext_size[lif_ext_type])); 3369 } 3370 3371 /* PPH Learn Extension */ 3372 if (learn_ext_present) 3373 { 3374 hdr_size += BKN_DNX_PPH_LEARN_EXT_SIZE; 3375 DBG_DUNE(("PPH Learn Extension(19) is present\n")); 3376 } 3377 } 3378 3379 /* UDH Header */ 3380 if (sinfo->udh_enable) 3381 { 3382 uint8 data_type_0; 3383 uint8 data_type_1; 3384 uint8 data_type_2; 3385 uint8 data_type_3; 3386 3387 DBG_DUNE(("UDH base(1) is present\n")); 3388 3389 /* UDH: UDH-Data-Type[0] */ 3390 bkn_bitstream_get_field( 3391 &buf[hdr_size], 3392 BKN_DNX_UDH_DATA_TYPE_0_MSB, 3393 BKN_DNX_UDH_DATA_TYPE_0_NOF_BITS, 3394 &fld_val); 3395 data_type_0 = fld_val; 3396 hdr_size += sinfo->udh_length_type[data_type_0]; 3397 /* UDH: UDH-Data-Type[1] */ 3398 bkn_bitstream_get_field( 3399 &buf[hdr_size], 3400 BKN_DNX_UDH_DATA_TYPE_1_MSB, 3401 BKN_DNX_UDH_DATA_TYPE_1_NOF_BITS, 3402 &fld_val); 3403 data_type_1 = fld_val; 3404 hdr_size += sinfo->udh_length_type[data_type_1]; 3405 /* UDH: UDH-Data-Type[2] */ 3406 bkn_bitstream_get_field( 3407 &buf[hdr_size], 3408 BKN_DNX_UDH_DATA_TYPE_2_MSB, 3409 BKN_DNX_UDH_DATA_TYPE_2_NOF_BITS, 3410 &fld_val); 3411 data_type_2 = fld_val; 3412 hdr_size += sinfo->udh_length_type[data_type_2]; 3413 /* UDH: UDH-Data-Type[3] */ 3414 bkn_bitstream_get_field( 3415 &buf[hdr_size], 3416 BKN_DNX_UDH_DATA_TYPE_3_MSB, 3417 BKN_DNX_UDH_DATA_TYPE_3_NOF_BITS, 3418 &fld_val); 3419 data_type_3 = fld_val; 3420 hdr_size += sinfo->udh_length_type[data_type_3]; 3421 hdr_size += BKN_DNX_UDH_BASE_SIZE; 3422 } 3423 3424 /* 3425 * Check if fhei_type if of type trap 3426 * There is a RISK that raw packet data is parsed and fhei_type is 0x5 by chance 3427 */ 3428 if (packet_info->fhei_type == 0x5) 3429 { 3430 /* Done for ingress trapped packets */ 3431 packet_info->system_header_size = hdr_size; 3432 DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); 3433 return 0; 3434 } 3435 else 3436 { 3437 /* New generated header will be FTMH(80b), TSH(32b), PPH(96b), FHEI(40b) */ 3438 3439 /* Revert packet_info except info from FTHM base header */ 3440 packet_info->fhei_qualifier = 0; 3441 packet_info->fhei_code = 0; 3442 packet_info->fhei_type = 0; 3443 hdr_size = pkt_offset_ingress_untrapped; 3444 3445 /* Time-Stamp Header */ 3446 hdr_size += BKN_DNX_TSH_SIZE; 3447 DBG_DUNE(("Time-Stamp Header(4) is present\n")); 3448 3449 /** Packet Processing Header */ 3450 bkn_bitstream_get_field( 3451 &buf[hdr_size], 3452 BKN_DNX_PPH_12_FORWARD_DOMAIN_MSB, 3453 BKN_DNX_PPH_12_FORWARD_DOMAIN_NOF_BITS, 3454 &fld_val); 3455 packet_info->pph_forward_domain = fld_val; 3456 hdr_size += BKN_DNX_PPH_BASE_TYPE_12; 3457 DBG_DUNE(("PPH(12) is present\n")); 3458 3459 /* 3460 * FHEI(Trap,40) 3461 * 5B-FHEI format for sys_hdr_generation_profile:J2-OAM 3462 * 8b' 0 3463 * 19b'oam_id 3464 * 9b' cpu_trap_code: INGRESS_TRAP_ID is always 0 here 3465 * 4b' type(0x5): J2-Configuration FHEI Type for CPU trap 3466 */ 3467 hdr_size += BKN_DNX_PPH_FHEI_SZ1_SIZE; 3468 DBG_DUNE(("FHEI(5) is present\n")); 3469 } 3470 packet_info->system_header_size = hdr_size; 3471 DBG_DUNE(("Total Size of Headers is %d\n", packet_info->system_header_size)); 3472 return 0; 3473 } 3474 3475 3476 static int 3477 bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) 3478 { 3479 bkn_priv_t *priv; 3480 bkn_dcb_chain_t *dcb_chain; 3481 struct sk_buff *skb; 3482 bkn_filter_t cbf; 3483 bkn_filter_t *filter; 3484 uint32_t err_woff; 3485 uint32_t *dcb, *meta; 3486 uint8_t *pkt; 3487 uint64_t pkt_dma; 3488 int drop_api; 3489 int ethertype; 3490 int pktlen; 3491 int idx; 3492 int dcbs_done = 0; 3493 bkn_dune_system_header_info_t packet_info = {0}; 3494 uint32_t dnx_meta_data[3] = {0}; 3495 3496 dcb_chain = sinfo->rx[chan].api_dcb_chain; 3497 if (dcb_chain == NULL) { 3498 /* No active chains */ 3499 return 0; 3500 } 3501 3502 while (dcb_chain->dcb_cur < dcb_chain->dcb_cnt) { 3503 dcb = &dcb_chain->dcb_mem[dcb_chain->dcb_cur * sinfo->dcb_wsize]; 3504 DBG_VERB(("DCB %2d: 0x%08x\n", 3505 dcb_chain->dcb_cur, dcb[sinfo->dcb_wsize-1])); 3506 if ((dcb[sinfo->dcb_wsize-1] & (1 << 31)) == 0) { 3507 break; 3508 } 3509 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 3510 /* Handle for Continuous DMA mode */ 3511 if (dcbs_done >= budget) { 3512 break; 3513 } 3514 if ((sinfo->cmic_type == 'x' && dcb[2] & (1 << 18)) || 3515 (sinfo->cmic_type != 'x' && dcb[1] & (1 << 18))) { 3516 dcb[sinfo->dcb_wsize-1] |= SOC_DCB_KNET_DONE; 3517 bkn_api_rx_chain_done(sinfo, chan); 3518 dcb_chain = sinfo->rx[chan].api_dcb_chain; 3519 if (dcb_chain == NULL) { 3520 break; 3521 } 3522 continue; 3523 } 3524 } 3525 if ((sinfo->cmic_type == 'x' && (dcb[2] & (1 << 16)) == 0) || 3526 (sinfo->cmic_type != 'x' && (dcb[1] & (1 << 16)) == 0)) { 3527 sinfo->rx[chan].chain_complete = 1; 3528 } 3529 sinfo->rx[chan].pkts++; 3530 if (sinfo->cmic_type == 'x') { 3531 pkt_dma = BUS_TO_DMA_HI(dcb[1]); 3532 pkt_dma = pkt_dma << 32 | dcb[0]; 3533 } else { 3534 pkt_dma = dcb[0]; 3535 } 3536 pkt = (uint8_t *)kernel_bde->p2l(sinfo->dev_no, (sal_paddr_t)pkt_dma); 3537 if (sinfo->cmic_type == 'x') { 3538 if (device_is_dnx(sinfo)){ 3539 meta = &dnx_meta_data[0]; 3540 /* get error bit from last DCB words */ 3541 err_woff = 2; 3542 meta[err_woff] = dcb[sinfo->dcb_wsize-1]; 3543 } else { 3544 meta = (uint32_t *)pkt; 3545 err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; 3546 meta[err_woff] = dcb[sinfo->dcb_wsize-1]; 3547 } 3548 } else { 3549 meta = dcb; 3550 err_woff = sinfo->dcb_wsize - 1; 3551 } 3552 pktlen = dcb[sinfo->dcb_wsize-1] & SOC_DCB_KNET_COUNT_MASK; 3553 bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); 3554 3555 if (device_is_dpp(sinfo)) { 3556 uint16_t tpid = 0; 3557 uint16_t vid = 0; 3558 int res = -1; 3559 3560 memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); 3561 res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); 3562 if (res == 0) { 3563 if (packet_info.ftmh.action_type == 0x2) { 3564 bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); 3565 } else if (packet_info.ftmh.action_type == 0x1) { 3566 bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); 3567 } 3568 bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); 3569 bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); 3570 bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); 3571 pkt += packet_info.ntwrk_header_ptr; 3572 pktlen -= packet_info.ntwrk_header_ptr; 3573 bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); 3574 /* check if vlan tag exists */ 3575 tpid = (uint16_t)((pkt[12] << 8) | pkt[13]); 3576 vid = (uint16_t)(packet_info.internal.vsi & 0xfff); 3577 if (packet_is_untagged(tpid)) { 3578 if ((pktlen + 4) < rx_buffer_size) { 3579 DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); 3580 for (idx = (pktlen-1); idx >= 12; idx--) { 3581 pkt[idx+4] = pkt[idx]; 3582 } 3583 pkt[12] = 0x81; 3584 pkt[13] = 0x00; 3585 pkt[14] = (vid >> 8); 3586 pkt[15] = (vid & 0xff); 3587 /* reset packet length in DCB */ 3588 pktlen += 4; 3589 dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; 3590 dcb[sinfo->dcb_wsize-1] |= ((pktlen + packet_info.ntwrk_header_ptr) & SOC_DCB_KNET_COUNT_MASK); 3591 bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); 3592 } 3593 } 3594 } 3595 } 3596 else if (device_is_dnx(sinfo)) { 3597 int res = -1; 3598 res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); 3599 if (res == 0) { 3600 bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); 3601 bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); 3602 bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); 3603 bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); 3604 3605 pkt += packet_info.system_header_size; 3606 pktlen -= packet_info.system_header_size; 3607 bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); 3608 } 3609 } 3610 3611 if (device_is_dpp(sinfo)) { 3612 filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, dcb, chan, &cbf); 3613 } else if (device_is_dnx(sinfo)) { 3614 filter = bkn_match_rx_pkt(sinfo, pkt, pktlen, meta, chan, &cbf); 3615 } else { 3616 filter = bkn_match_rx_pkt(sinfo, pkt + sinfo->pkt_hdr_size, 3617 pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); 3618 } 3619 if ((dcb[sinfo->dcb_wsize-1] & 0xf0000) != 0x30000) { 3620 /* Fragment or error */ 3621 if (filter && filter->kf.mask.w[err_woff] == 0) { 3622 /* Drop unless DCB status is part of filter */ 3623 filter = NULL; 3624 } 3625 } 3626 drop_api = 1; 3627 if (filter) { 3628 DBG_FLTR(("Match filter ID %d\n", filter->kf.id)); 3629 switch (filter->kf.dest_type) { 3630 case KCOM_DEST_T_API: 3631 DBG_FLTR(("Send to Rx API\n")); 3632 sinfo->rx[chan].pkts_f_api++; 3633 drop_api = 0; 3634 break; 3635 case KCOM_DEST_T_NETIF: 3636 priv = bkn_netif_lookup(sinfo, filter->kf.dest_id); 3637 if (priv) { 3638 /* Check that software link is up */ 3639 if (!netif_carrier_ok(priv->dev)) { 3640 sinfo->rx[chan].pkts_d_no_link++; 3641 break; 3642 } 3643 3644 if (sinfo->cmic_type == 'x') { 3645 pkt += sinfo->pkt_hdr_size; 3646 pktlen -= sinfo->pkt_hdr_size; 3647 } 3648 3649 /* Add 2 bytes for IP header alignment (see below) */ 3650 skb = dev_alloc_skb(pktlen + RCPU_RX_ENCAP_SIZE + 2); 3651 if (skb == NULL) { 3652 sinfo->rx[chan].pkts_d_no_skb++; 3653 break; 3654 } 3655 skb_reserve(skb, RCPU_RX_ENCAP_SIZE); 3656 3657 DBG_FLTR(("Send to netif %d (%s)\n", 3658 priv->id, priv->dev->name)); 3659 sinfo->rx[chan].pkts_f_netif++; 3660 skb->dev = priv->dev; 3661 skb_reserve(skb, 2); /* 16 byte align the IP fields. */ 3662 3663 /* Save for RCPU before stripping tag */ 3664 ethertype = (pkt[16] << 8) | pkt[17]; 3665 if ((priv->flags & KCOM_NETIF_F_KEEP_RX_TAG) == 0) { 3666 if (filter->kf.flags & KCOM_FILTER_F_STRIP_TAG) { 3667 /* Strip the VLAN tag */ 3668 uint16_t vlan_proto = (uint16_t)((pkt[12] << 8) | pkt[13]); 3669 if (vlan_proto == 0x8100 || vlan_proto == 0x88a8) { 3670 DBG_FLTR(("Strip VLAN tag\n")); 3671 for (idx = 11; idx >= 0; idx--) { 3672 pkt[idx+4] = pkt[idx]; 3673 } 3674 pktlen -= 4; 3675 pkt += 4; 3676 } 3677 } else { 3678 /* 3679 * Mark packet as VLAN-tagged, otherwise newer 3680 * kernels will strip the tag. 3681 */ 3682 uint16_t tci = (pkt[14] << 8) | pkt[15]; 3683 if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { 3684 bkn_vlan_hwaccel_put_tag(skb, ETH_P_8021Q, tci); 3685 } else { 3686 bkn_vlan_hwaccel_put_tag(skb, 3687 ((skb->data[12] << 8) | skb->data[13]), tci); 3688 } 3689 } 3690 } 3691 3692 skb_copy_to_linear_data(skb, pkt, pktlen); 3693 if (device_is_sand(sinfo)) { 3694 /* CRC has been stripped */ 3695 skb_put(skb, pktlen); 3696 } else { 3697 skb_put(skb, pktlen - 4); /* Strip CRC */ 3698 } 3699 priv->stats.rx_packets++; 3700 priv->stats.rx_bytes += skb->len; 3701 3702 /* Optional SKB updates */ 3703 if (knet_rx_cb != NULL) { 3704 KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; 3705 KNET_SKB_CB(skb)->filter_user_data = filter->kf.cb_user_data; 3706 KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; 3707 skb = knet_rx_cb(skb, sinfo->dev_no, meta); 3708 if (skb == NULL) { 3709 /* Consumed by call-back */ 3710 sinfo->rx[chan].pkts_d_callback++; 3711 break; 3712 } 3713 } 3714 3715 /* Do Rx timestamping */ 3716 if (sinfo->rx_hwts) { 3717 bkn_hw_tstamp_rx_set(sinfo, skb, meta); 3718 } 3719 3720 if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { 3721 bkn_add_rcpu_encap(sinfo, skb, meta); 3722 DBG_PDMP(("After add RCPU ENCAP\n")); 3723 bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, XGS_DMA_RX_CHAN); 3724 } 3725 skb->protocol = eth_type_trans(skb, skb->dev); 3726 if (filter->kf.dest_proto) { 3727 skb->protocol = filter->kf.dest_proto; 3728 } 3729 if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { 3730 bkn_eth_type_update(skb, ethertype); 3731 } 3732 DBG_DUNE(("skb protocol 0x%04x\n",skb->protocol)); 3733 3734 /* Unlock while calling up network stack */ 3735 spin_unlock(&sinfo->lock); 3736 if (use_napi) { 3737 netif_receive_skb(skb); 3738 } else { 3739 netif_rx(skb); 3740 } 3741 spin_lock(&sinfo->lock); 3742 3743 if (filter->kf.mirror_type == KCOM_DEST_T_API || 3744 dbg_pkt_enable) { 3745 DBG_FLTR(("Mirror to Rx API\n")); 3746 sinfo->rx[chan].pkts_m_api++; 3747 drop_api = 0; 3748 } 3749 } else { 3750 DBG_FLTR(("Unknown netif %d\n", 3751 filter->kf.dest_id)); 3752 sinfo->rx[chan].pkts_d_unkn_netif++; 3753 } 3754 break; 3755 default: 3756 /* Drop packet */ 3757 DBG_FLTR(("Unknown dest type %d\n", 3758 filter->kf.dest_type)); 3759 sinfo->rx[chan].pkts_d_unkn_dest++; 3760 break; 3761 } 3762 } else { 3763 DBG_PKT(("Rx packet dropped.\n")); 3764 sinfo->rx[chan].pkts_d_no_match++; 3765 } 3766 if (drop_api) { 3767 /* If count is zero, the DCB will just be recycled */ 3768 dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; 3769 } 3770 dcb[sinfo->dcb_wsize-1] |= SOC_DCB_KNET_DONE; 3771 dcb_chain->dcb_cur++; 3772 dcbs_done++; 3773 } 3774 3775 return dcbs_done; 3776 } 3777 3778 static int 3779 bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) 3780 { 3781 bkn_priv_t *priv; 3782 bkn_desc_info_t *desc; 3783 struct sk_buff *skb; 3784 bkn_filter_t cbf; 3785 bkn_filter_t *filter; 3786 uint32_t err_woff; 3787 uint32_t *dcb, *meta; 3788 int ethertype; 3789 int pktlen; 3790 int idx; 3791 int dcbs_done = 0; 3792 bkn_dune_system_header_info_t packet_info = {0}; 3793 uint32_t dnx_meta_data[3] = {0}; 3794 3795 if (!sinfo->rx[chan].running) { 3796 /* Rx not ready */ 3797 return 0; 3798 } 3799 3800 while (dcbs_done < budget) { 3801 char str[32]; 3802 sprintf(str, "Rx DCB (%d)", sinfo->rx[chan].dirty); 3803 desc = &sinfo->rx[chan].desc[sinfo->rx[chan].dirty]; 3804 dcb = desc->dcb_mem; 3805 bkn_dump_dcb(str, dcb, sinfo->dcb_wsize, XGS_DMA_RX_CHAN); 3806 if ((dcb[sinfo->dcb_wsize-1] & (1 << 31)) == 0) { 3807 break; 3808 } 3809 if ((sinfo->cmic_type == 'x' && (dcb[2] & (1 << 16)) == 0) || 3810 (sinfo->cmic_type != 'x' && (dcb[1] & (1 << 16)) == 0)) { 3811 sinfo->rx[chan].chain_complete = 1; 3812 /* Request one extra poll to check for chain done interrupt */ 3813 if (sinfo->napi_poll_mode) { 3814 sinfo->napi_poll_again = 1; 3815 } 3816 } 3817 sinfo->rx[chan].pkts++; 3818 skb = desc->skb; 3819 if (sinfo->cmic_type == 'x') { 3820 if (device_is_dnx(sinfo)){ 3821 meta = &dnx_meta_data[0]; 3822 /* get error bit from last DCB words */ 3823 err_woff = 2; 3824 meta[err_woff] = dcb[sinfo->dcb_wsize-1]; 3825 } else { 3826 meta = (uint32_t *)skb->data; 3827 err_woff = sinfo->pkt_hdr_size / sizeof(uint32_t) - 1; 3828 meta[err_woff] = dcb[sinfo->dcb_wsize-1]; 3829 } 3830 } else { 3831 meta = dcb; 3832 err_woff = sinfo->dcb_wsize - 1; 3833 } 3834 pktlen = dcb[sinfo->dcb_wsize-1] & 0xffff; 3835 priv = netdev_priv(sinfo->dev); 3836 DBG_DCB_RX(("Rx%d SKB DMA done (%d).\n", chan, sinfo->rx[chan].dirty)); 3837 DMA_UNMAP_SINGLE(sinfo->dma_dev, 3838 desc->skb_dma, desc->dma_size, 3839 DMA_FROMDEV); 3840 desc->skb_dma = 0; 3841 bkn_dump_pkt(skb->data, pktlen, XGS_DMA_RX_CHAN); 3842 3843 if (device_is_dpp(sinfo)) { 3844 uint16_t tpid = 0; 3845 uint16_t vid = 0; 3846 uint8_t *pkt = skb->data; 3847 int res = 0; 3848 3849 memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); 3850 res = bkn_dpp_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); 3851 if (res == 0) { 3852 if (packet_info.ftmh.action_type == 0x2) { 3853 bkn_bitstream_set_field((uint32_t *)dcb, 192, 32, 0x8); 3854 } else if (packet_info.ftmh.action_type == 0x1) { 3855 bkn_bitstream_set_field((uint32_t *)dcb, 231, 25, 0x20); 3856 } 3857 bkn_bitstream_set_field((uint32_t *)dcb, 112, 16, packet_info.ftmh.src_sys_port); 3858 bkn_bitstream_set_field((uint32_t *)dcb, 296, 12, packet_info.internal.vsi); 3859 bkn_bitstream_set_field((uint32_t *)dcb, 64, 32, (packet_info.internal.trap_id << 16 | packet_info.internal.trap_qualifier)); 3860 pkt = skb->data + packet_info.ntwrk_header_ptr; 3861 /* check if vlan tag exists */ 3862 tpid = (uint16_t)((pkt[12] << 8) | pkt[13]); 3863 vid = (uint16_t)(packet_info.internal.vsi & 0xfff); 3864 if (packet_is_untagged(tpid)) { 3865 if ((pktlen + 4) < rx_buffer_size) { 3866 DBG_DUNE(("add vlan tag to untagged packets\n")); 3867 for (idx = (pktlen-packet_info.ntwrk_header_ptr-1); idx >= 12; idx--) { 3868 pkt[idx+4] = pkt[idx]; 3869 } 3870 pkt[12] = 0x81; 3871 pkt[13] = 0x00; 3872 pkt[14] = (vid >> 8); 3873 pkt[15] = (vid & 0xff); 3874 pktlen += 4; 3875 /* reset packet length in DCB */ 3876 dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; 3877 dcb[sinfo->dcb_wsize-1] |= (pktlen & SOC_DCB_KNET_COUNT_MASK); 3878 bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); 3879 } 3880 } 3881 } 3882 } 3883 else if (device_is_dnx(sinfo)) { 3884 uint8_t *pkt = skb->data; 3885 int res = -1; 3886 3887 res = bkn_dnx_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); 3888 if (res == 0) { 3889 bkn_bitstream_set_field(meta, 0, 16, packet_info.fhei_code); 3890 bkn_bitstream_set_field(meta, 16, 16, packet_info.fhei_qualifier); 3891 bkn_bitstream_set_field(meta, 32, 16, packet_info.ftmh_spa); 3892 bkn_bitstream_set_field(meta, 48, 16, (packet_info.pph_forward_domain & 0xffff)); 3893 3894 pkt += packet_info.system_header_size; 3895 pktlen -= packet_info.ntwrk_header_ptr; 3896 bkn_dump_pkt(pkt, 32, XGS_DMA_RX_CHAN); 3897 } 3898 } 3899 3900 if (device_is_dpp(sinfo)) { 3901 filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.ntwrk_header_ptr, 3902 pktlen, dcb, chan, &cbf); 3903 } else if (device_is_dnx(sinfo)) { 3904 filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.system_header_size, 3905 pktlen, meta, chan, &cbf); 3906 } else { 3907 filter = bkn_match_rx_pkt(sinfo, skb->data + sinfo->pkt_hdr_size, 3908 pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); 3909 } 3910 if ((dcb[sinfo->dcb_wsize-1] & 0xf0000) != 0x30000) { 3911 /* Fragment or error */ 3912 priv->stats.rx_errors++; 3913 if (filter && filter->kf.mask.w[err_woff] == 0) { 3914 /* Drop unless DCB status is part of filter */ 3915 filter = NULL; 3916 } 3917 } 3918 DBG_PKT(("Rx packet (%d bytes).\n", pktlen)); 3919 if (filter) { 3920 DBG_FLTR(("Match filter ID %d\n", filter->kf.id)); 3921 switch (filter->kf.dest_type) { 3922 case KCOM_DEST_T_API: 3923 DBG_FLTR(("Send to Rx API\n")); 3924 sinfo->rx[chan].pkts_f_api++; 3925 bkn_api_rx_copy_from_skb(sinfo, chan, desc); 3926 break; 3927 case KCOM_DEST_T_NETIF: 3928 priv = bkn_netif_lookup(sinfo, filter->kf.dest_id); 3929 if (priv) { 3930 /* Check that software link is up */ 3931 if (!netif_carrier_ok(priv->dev)) { 3932 sinfo->rx[chan].pkts_d_no_link++; 3933 break; 3934 } 3935 DBG_FLTR(("Send to netif %d (%s)\n", 3936 priv->id, priv->dev->name)); 3937 sinfo->rx[chan].pkts_f_netif++; 3938 3939 if (((filter->kf.mirror_type == KCOM_DEST_T_API) && 3940 (!device_is_sand(sinfo))) || dbg_pkt_enable) { 3941 sinfo->rx[chan].pkts_m_api++; 3942 bkn_api_rx_copy_from_skb(sinfo, chan, desc); 3943 } 3944 3945 if (device_is_dpp(sinfo)) { 3946 if (filter->kf.mirror_type == KCOM_DEST_T_API) { 3947 sinfo->rx[chan].pkts_m_api++; 3948 bkn_api_rx_copy_from_skb(sinfo, chan, desc); 3949 } 3950 /* Strip Dune headers */ 3951 skb->data += packet_info.ntwrk_header_ptr; 3952 pktlen -= packet_info.ntwrk_header_ptr; 3953 bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); 3954 /* CRC has been stripped on Dune*/ 3955 skb_put(skb, pktlen); 3956 } else if (device_is_dnx(sinfo)) { 3957 if (filter->kf.mirror_type == KCOM_DEST_T_API) { 3958 sinfo->rx[chan].pkts_m_api++; 3959 bkn_api_rx_copy_from_skb(sinfo, chan, desc); 3960 } 3961 /* Strip Dune headers */ 3962 skb->data += packet_info.system_header_size; 3963 pktlen -= packet_info.system_header_size; 3964 bkn_dump_pkt(skb->data, 32, XGS_DMA_RX_CHAN); 3965 /* CRC has been stripped on Dune*/ 3966 skb_put(skb, pktlen); 3967 } else { 3968 skb_put(skb, pktlen - 4); /* Strip CRC */ 3969 } 3970 3971 if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { 3972 skb_pull(skb, sinfo->pkt_hdr_size); 3973 } 3974 3975 /* Save for RCPU before stripping tag */ 3976 ethertype = (skb->data[16] << 8) | skb->data[17]; 3977 if ((priv->flags & KCOM_NETIF_F_KEEP_RX_TAG) == 0) { 3978 if (filter->kf.flags & KCOM_FILTER_F_STRIP_TAG) { 3979 /* Strip VLAN tag */ 3980 uint16_t vlan_proto = (uint16_t)((skb->data[12] << 8) | skb->data[13]); 3981 if (vlan_proto == 0x8100 || vlan_proto == 0x88a8) { 3982 DBG_FLTR(("Strip VLAN tag\n")); 3983 ((u32*)skb->data)[3] = ((u32*)skb->data)[2]; 3984 ((u32*)skb->data)[2] = ((u32*)skb->data)[1]; 3985 ((u32*)skb->data)[1] = ((u32*)skb->data)[0]; 3986 skb_pull(skb, 4); 3987 if (sinfo->cmic_type == 'x' && !device_is_dnx(sinfo)) { 3988 for (idx = sinfo->pkt_hdr_size / sizeof(uint32_t); idx; idx--) { 3989 meta[idx] = meta[idx - 1]; 3990 } 3991 meta++; 3992 } 3993 } 3994 } else { 3995 /* 3996 * Mark packet as VLAN-tagged, otherwise newer 3997 * kernels will strip the tag. 3998 */ 3999 uint16_t tci = (skb->data[14] << 8) | skb->data[15]; 4000 if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { 4001 bkn_vlan_hwaccel_put_tag(skb, ETH_P_8021Q, tci); 4002 } else { 4003 bkn_vlan_hwaccel_put_tag(skb, 4004 ((skb->data[12] << 8) | skb->data[13]), tci); 4005 } 4006 } 4007 } 4008 priv->stats.rx_packets++; 4009 priv->stats.rx_bytes += skb->len; 4010 skb->dev = priv->dev; 4011 4012 /* Optional SKB updates */ 4013 if (knet_rx_cb != NULL) { 4014 KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; 4015 KNET_SKB_CB(skb)->filter_user_data = filter->kf.cb_user_data; 4016 KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; 4017 skb = knet_rx_cb(skb, sinfo->dev_no, meta); 4018 if (skb == NULL) { 4019 /* Consumed by call-back */ 4020 sinfo->rx[chan].pkts_d_callback++; 4021 priv->stats.rx_dropped++; 4022 desc->skb = NULL; 4023 break; 4024 } 4025 } 4026 4027 /* Do Rx timestamping */ 4028 if (sinfo->rx_hwts) { 4029 bkn_hw_tstamp_rx_set(sinfo, skb, meta); 4030 } 4031 4032 if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { 4033 bkn_add_rcpu_encap(sinfo, skb, meta); 4034 DBG_PDMP(("After add RCPU ENCAP\n")); 4035 bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, XGS_DMA_RX_CHAN); 4036 } 4037 skb->protocol = eth_type_trans(skb, skb->dev); 4038 if (filter->kf.dest_proto) { 4039 skb->protocol = filter->kf.dest_proto; 4040 } 4041 if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { 4042 bkn_eth_type_update(skb, ethertype); 4043 } 4044 DBG_DUNE(("skb protocol 0x%04x\n",skb->protocol)); 4045 4046 if (filter->kf.mirror_type == KCOM_DEST_T_NETIF) { 4047 bkn_priv_t *mpriv; 4048 struct sk_buff *mskb; 4049 mpriv = bkn_netif_lookup(sinfo, filter->kf.mirror_id); 4050 if (mpriv && netif_carrier_ok(mpriv->dev)) { 4051 mskb = skb_clone(skb, GFP_ATOMIC); 4052 if (mskb == NULL) { 4053 sinfo->rx[chan].pkts_d_no_skb++; 4054 } else { 4055 sinfo->rx[chan].pkts_m_netif++; 4056 mpriv->stats.rx_packets++; 4057 mpriv->stats.rx_bytes += mskb->len; 4058 skb->dev = mpriv->dev; 4059 if (filter->kf.mirror_proto) { 4060 skb->protocol = filter->kf.mirror_proto; 4061 } 4062 /* Unlock while calling up network stack */ 4063 spin_unlock(&sinfo->lock); 4064 if (use_napi) { 4065 netif_receive_skb(mskb); 4066 } else { 4067 netif_rx(mskb); 4068 } 4069 spin_lock(&sinfo->lock); 4070 } 4071 } 4072 } 4073 4074 /* Unlock while calling up network stack */ 4075 spin_unlock(&sinfo->lock); 4076 if (use_napi) { 4077 netif_receive_skb(skb); 4078 } else { 4079 netif_rx(skb); 4080 } 4081 spin_lock(&sinfo->lock); 4082 4083 /* Ensure that we reallocate SKB for this DCB */ 4084 desc->skb = NULL; 4085 } else { 4086 DBG_FLTR(("Unknown netif %d\n", 4087 filter->kf.dest_id)); 4088 sinfo->rx[chan].pkts_d_unkn_netif++; 4089 } 4090 break; 4091 default: 4092 /* Drop packet */ 4093 DBG_FLTR(("Unknown dest type %d\n", 4094 filter->kf.dest_type)); 4095 sinfo->rx[chan].pkts_d_unkn_dest++; 4096 break; 4097 } 4098 } else { 4099 DBG_PKT(("Rx packet dropped.\n")); 4100 sinfo->rx[chan].pkts_d_no_match++; 4101 priv->stats.rx_dropped++; 4102 } 4103 dcb[sinfo->dcb_wsize-1] &= ~(1 << 31); 4104 if (++sinfo->rx[chan].dirty >= MAX_RX_DCBS) { 4105 sinfo->rx[chan].dirty = 0; 4106 } 4107 sinfo->rx[chan].free--; 4108 dcbs_done++; 4109 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 4110 /* Right now refill for Continuous DMA mode */ 4111 bkn_rx_refill(sinfo, chan); 4112 } 4113 } 4114 4115 return dcbs_done; 4116 } 4117 4118 static int 4119 bkn_do_rx(bkn_switch_info_t *sinfo, int chan, int budget) 4120 { 4121 if (sinfo->rx[chan].use_rx_skb == 0) { 4122 /* Rx buffers are provided by BCM Rx API */ 4123 return bkn_do_api_rx(sinfo, chan, budget); 4124 } else { 4125 /* Rx buffers are provided by Linux kernel */ 4126 return bkn_do_skb_rx(sinfo, chan, budget); 4127 } 4128 } 4129 4130 static void 4131 bkn_rx_desc_done(bkn_switch_info_t *sinfo, int chan) 4132 { 4133 bkn_evt_resource_t *evt; 4134 evt = &_bkn_evt[sinfo->evt_idx]; 4135 DBG_IRQ(("Rx%d desc done\n", chan)); 4136 4137 if (sinfo->rx[chan].use_rx_skb == 0) { 4138 sinfo->dma_events |= KCOM_DMA_INFO_F_RX_DONE; 4139 evt->evt_wq_put++; 4140 wake_up_interruptible(&evt->evt_wq); 4141 } 4142 } 4143 4144 static void 4145 bkn_rx_chain_done(bkn_switch_info_t *sinfo, int chan) 4146 { 4147 DBG_IRQ(("Rx%d chain done\n", chan)); 4148 4149 if (sinfo->rx[chan].chain_complete == 0) { 4150 /* 4151 * In certain environments the DCB memory is updated after 4152 * the corresponding interrupt has been received. 4153 * The following code will ensure that this situation is 4154 * handled properly. 4155 */ 4156 int maxloop = 0; 4157 while (sinfo->rx[chan].chain_complete == 0) { 4158 sinfo->rx[chan].sync_retry++; 4159 if (maxloop == 0) { 4160 sinfo->rx[chan].sync_err++; 4161 } 4162 if (maxloop > sinfo->rx[chan].sync_maxloop) { 4163 sinfo->rx[chan].sync_maxloop = maxloop; 4164 } 4165 if (bkn_do_rx(sinfo, chan, MAX_RX_DCBS) > 0) { 4166 bkn_rx_desc_done(sinfo, chan); 4167 } 4168 if (++maxloop > rx_sync_retry) { 4169 gprintk("Fatal error: Incomplete chain\n"); 4170 sinfo->rx[chan].chain_complete = 1; 4171 break; 4172 } 4173 } 4174 } 4175 4176 sinfo->rx[chan].running = 0; 4177 4178 if (sinfo->rx[chan].use_rx_skb == 0) { 4179 bkn_api_rx_chain_done(sinfo, chan); 4180 } else { 4181 bkn_rx_refill(sinfo, chan); 4182 4183 if (bkn_rx_restart(sinfo, chan) != 0) { 4184 /* Presumably out of resources */ 4185 sinfo->timer.expires = jiffies + 1; 4186 if (!sinfo->timer_queued) { 4187 sinfo->timer_queued = 1; 4188 add_timer(&sinfo->timer); 4189 } 4190 } 4191 } 4192 } 4193 4194 static void 4195 bkn_suspend_tx(bkn_switch_info_t *sinfo) 4196 { 4197 struct list_head *list; 4198 bkn_priv_t *priv = netdev_priv(sinfo->dev); 4199 4200 /* Stop main device */ 4201 netif_stop_queue(priv->dev); 4202 sinfo->tx.suspends++; 4203 /* Stop associated virtual devices */ 4204 list_for_each(list, &sinfo->ndev_list) { 4205 priv = (bkn_priv_t *)list; 4206 netif_stop_queue(priv->dev); 4207 } 4208 } 4209 4210 static void 4211 bkn_resume_tx(bkn_switch_info_t *sinfo) 4212 { 4213 struct list_head *list; 4214 bkn_priv_t *priv = netdev_priv(sinfo->dev); 4215 4216 /* Check main device */ 4217 if (netif_queue_stopped(priv->dev) && sinfo->tx.free > 1) { 4218 netif_wake_queue(priv->dev); 4219 } 4220 /* Check associated virtual devices */ 4221 list_for_each(list, &sinfo->ndev_list) { 4222 priv = (bkn_priv_t *)list; 4223 if (netif_queue_stopped(priv->dev) && sinfo->tx.free > 1) { 4224 netif_wake_queue(priv->dev); 4225 } 4226 } 4227 } 4228 4229 static int 4230 bkn_hw_tstamp_tx_set(bkn_switch_info_t *sinfo, struct sk_buff *skb) 4231 { 4232 struct skb_shared_hwtstamps shhwtstamps; 4233 uint64_t ts = 0; 4234 uint32_t hdrlen = sinfo->cmic_type == 'x' ? PKT_TX_HDR_SIZE : 0; 4235 int port; 4236 4237 if (!knet_hw_tstamp_tx_time_get_cb) { 4238 return -1; 4239 } 4240 4241 port = KNET_SKB_CB(skb)->port; 4242 if (knet_hw_tstamp_tx_time_get_cb(sinfo->dev_no, port, skb->data + hdrlen, &ts) < 0) { 4243 return -1; 4244 } 4245 4246 memset(&shhwtstamps, 0, sizeof(shhwtstamps)); 4247 shhwtstamps.hwtstamp = ns_to_ktime(be64_to_cpu(ts)); 4248 skb_tstamp_tx(skb, &shhwtstamps); 4249 4250 return 0; 4251 } 4252 4253 static void 4254 bkn_hw_tstamp_tx_work(struct work_struct *work) 4255 { 4256 bkn_switch_info_t *sinfo = container_of(work, bkn_switch_info_t, tx_ptp_work); 4257 struct sk_buff *skb; 4258 4259 while (skb_queue_len(&sinfo->tx_ptp_queue)) { 4260 skb = skb_dequeue(&sinfo->tx_ptp_queue); 4261 if (bkn_hw_tstamp_tx_set(sinfo, skb) < 0) { 4262 gprintk("Timestamp has not been taken for the current skb.\n"); 4263 } 4264 dev_kfree_skb_any(skb); 4265 } 4266 } 4267 4268 static int 4269 bkn_do_tx(bkn_switch_info_t *sinfo) 4270 { 4271 bkn_desc_info_t *desc; 4272 int dcbs_done = 0; 4273 4274 if (!CDMA_CH(sinfo, XGS_DMA_TX_CHAN) && sinfo->tx.api_active) { 4275 return dcbs_done; 4276 } 4277 4278 while (dcbs_done < MAX_TX_DCBS) { 4279 char str[32]; 4280 if (sinfo->tx.free == MAX_TX_DCBS) { 4281 break; 4282 } 4283 sprintf(str, "Tx DCB (%d)", sinfo->tx.dirty); 4284 desc = &sinfo->tx.desc[sinfo->tx.dirty]; 4285 bkn_dump_dcb(str, desc->dcb_mem, sinfo->dcb_wsize, XGS_DMA_TX_CHAN); 4286 if ((desc->dcb_mem[sinfo->dcb_wsize-1] & (1 << 31)) == 0) { 4287 break; 4288 } 4289 if (desc->skb) { 4290 DBG_DCB_TX(("Tx SKB DMA done (%d).\n", sinfo->tx.dirty)); 4291 DMA_UNMAP_SINGLE(sinfo->dma_dev, 4292 desc->skb_dma, desc->dma_size, 4293 DMA_TODEV); 4294 if (bkn_skb_tx_flags(desc->skb) & SKBTX_IN_PROGRESS) { 4295 skb_queue_tail(&sinfo->tx_ptp_queue, desc->skb); 4296 schedule_work(&sinfo->tx_ptp_work); 4297 } else { 4298 dev_kfree_skb_any(desc->skb); 4299 } 4300 desc->skb = NULL; 4301 desc->skb_dma = 0; 4302 } 4303 desc->dcb_mem[sinfo->dcb_wsize-1] &= ~(1 << 31); 4304 if (++sinfo->tx.dirty >= MAX_TX_DCBS) { 4305 sinfo->tx.dirty = 0; 4306 } 4307 if (++sinfo->tx.free > MAX_TX_DCBS) { 4308 gprintk("Too many free Tx DCBs(%d).\n", sinfo->tx.free); 4309 } 4310 dcbs_done++; 4311 } 4312 4313 return dcbs_done; 4314 } 4315 4316 static void 4317 bkn_tx_cdma_chain_switch(bkn_switch_info_t *sinfo) 4318 { 4319 bkn_dcb_chain_t *dcb_chain = sinfo->tx.api_dcb_chain; 4320 uint32_t *dcb_mem; 4321 uint64_t dcb_dma; 4322 int woffset; 4323 4324 /* Switch between SKB Tx and API Tx for Continuous DMA mode */ 4325 if (!sinfo->tx.api_active) { 4326 /* 4327 * Set the current SKB DCB as reload DCB and the last DCB of 4328 * the pending API chain as the new halt location. 4329 */ 4330 sinfo->tx.api_active = 1; 4331 dcb_mem = sinfo->tx.desc[sinfo->tx.cur].dcb_mem; 4332 memset(dcb_mem, 0, sinfo->dcb_wsize * sizeof(uint32_t)); 4333 dcb_mem[0] = dcb_chain->dcb_dma; 4334 if (sinfo->cmic_type == 'x') { 4335 dcb_mem[1] = DMA_TO_BUS_HI(dcb_chain->dcb_dma >> 32); 4336 dcb_mem[2] |= 1 << 24 | 1 << 18 | 1 << 16; 4337 } else { 4338 dcb_mem[1] |= 1 << 24 | 1 << 18 | 1 << 16; 4339 } 4340 if (++sinfo->tx.cur >= MAX_TX_DCBS) { 4341 sinfo->tx.cur = 0; 4342 } 4343 sinfo->tx.free--; 4344 woffset = (dcb_chain->dcb_cnt - 1) * sinfo->dcb_wsize; 4345 dcb_dma = dcb_chain->dcb_dma + woffset * sizeof(uint32_t); 4346 /* DMA run to the new halt location */ 4347 bkn_cdma_goto(sinfo, XGS_DMA_TX_CHAN, dcb_dma); 4348 } else { 4349 /* Only need to set the current SKB DCB as the new halt location */ 4350 sinfo->tx.api_active = 0; 4351 woffset = (dcb_chain->dcb_cnt - 1) * sinfo->dcb_wsize; 4352 dcb_mem = &dcb_chain->dcb_mem[woffset]; 4353 dcb_mem[0] = sinfo->tx.desc[sinfo->tx.dirty].dcb_dma; 4354 if (sinfo->cmic_type == 'x') { 4355 dcb_mem[1] = DMA_TO_BUS_HI(sinfo->tx.desc[sinfo->tx.dirty].dcb_dma >> 32); 4356 } 4357 dcb_dma = sinfo->tx.desc[sinfo->tx.cur].dcb_dma; 4358 /* DMA run to the new halt location */ 4359 bkn_cdma_goto(sinfo, XGS_DMA_TX_CHAN, dcb_dma); 4360 } 4361 } 4362 4363 static void 4364 bkn_skb_tx(bkn_switch_info_t *sinfo) 4365 { 4366 if (sinfo->tx.api_active) { 4367 /* Switch from API Tx to SKB Tx */ 4368 bkn_tx_cdma_chain_switch(sinfo); 4369 } 4370 } 4371 4372 static void 4373 bkn_api_tx(bkn_switch_info_t *sinfo) 4374 { 4375 bkn_dcb_chain_t *dcb_chain; 4376 uint64_t pkt_dma; 4377 unsigned char *pktdata; 4378 int pktlen; 4379 int i; 4380 4381 /* Assume that driver lock is held */ 4382 if (list_empty(&sinfo->tx.api_dcb_list)) { 4383 sinfo->tx.api_active = 0; 4384 } else { 4385 sinfo->tx.pkts++; 4386 dcb_chain = list_entry(sinfo->tx.api_dcb_list.next, 4387 bkn_dcb_chain_t, list); 4388 DBG_DCB_TX(("Start API Tx DMA, first DCB @ 0x%08x (%d DCBs).\n", 4389 (uint32_t)dcb_chain->dcb_dma, dcb_chain->dcb_cnt)); 4390 for (i = 0; i < dcb_chain->dcb_cnt && debug & DBG_LVL_PDMP; i++) { 4391 if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN) && i == dcb_chain->dcb_cnt - 1) { 4392 break; 4393 } 4394 if (sinfo->cmic_type == 'x') { 4395 pkt_dma = BUS_TO_DMA_HI(dcb_chain->dcb_mem[sinfo->dcb_wsize * i + 1]); 4396 pkt_dma = pkt_dma << 32 | dcb_chain->dcb_mem[sinfo->dcb_wsize * i]; 4397 } else { 4398 pkt_dma = dcb_chain->dcb_mem[sinfo->dcb_wsize * i]; 4399 } 4400 pktdata = kernel_bde->p2l(sinfo->dev_no, pkt_dma); 4401 if (sinfo->cmic_type == 'x') { 4402 pktlen = dcb_chain->dcb_mem[sinfo->dcb_wsize * i + 2] & 0xffff; 4403 } else { 4404 pktlen = dcb_chain->dcb_mem[sinfo->dcb_wsize * i + 1] & 0xffff; 4405 } 4406 bkn_dump_pkt(pktdata, pktlen, XGS_DMA_TX_CHAN); 4407 } 4408 4409 if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN)) { 4410 sinfo->tx.api_dcb_chain = dcb_chain; 4411 if (!sinfo->tx.api_active) { 4412 /* Switch from SKB Tx to API Tx */ 4413 bkn_tx_cdma_chain_switch(sinfo); 4414 } 4415 list_del(&dcb_chain->list); 4416 } else { 4417 sinfo->tx.api_active = 1; 4418 dev_dma_chan_clear(sinfo, XGS_DMA_TX_CHAN); 4419 dev_irq_mask_enable(sinfo, XGS_DMA_TX_CHAN, 1); 4420 dev_dma_chan_start(sinfo, XGS_DMA_TX_CHAN, dcb_chain->dcb_dma); 4421 list_del(&dcb_chain->list); 4422 kfree(dcb_chain); 4423 } 4424 } 4425 } 4426 4427 static void 4428 bkn_tx_cdma_chain_done(bkn_switch_info_t *sinfo, int done) 4429 { 4430 int woffset; 4431 int dcbs_done = 0; 4432 bkn_evt_resource_t *evt; 4433 4434 DBG_IRQ(("Tx CDMA chain done \n")); 4435 4436 evt = &_bkn_evt[sinfo->evt_idx]; 4437 4438 if (sinfo->tx.api_active) { 4439 /* Drain API Tx chains */ 4440 while (sinfo->tx.api_dcb_chain != sinfo->tx.api_dcb_chain_end) { 4441 woffset = sinfo->tx.api_dcb_chain->dcb_cnt * sinfo->dcb_wsize - 1; 4442 if (!(sinfo->tx.api_dcb_chain->dcb_mem[woffset] & (1 << 31))) { 4443 return; 4444 } 4445 sinfo->tx.api_dcb_chain->dcb_mem[woffset - sinfo->dcb_wsize] |= SOC_DCB_KNET_DONE; 4446 sinfo->dma_events |= KCOM_DMA_INFO_F_TX_DONE; 4447 evt->evt_wq_put++; 4448 wake_up_interruptible(&evt->evt_wq); 4449 kfree(sinfo->tx.api_dcb_chain); 4450 sinfo->tx.api_dcb_chain = NULL; 4451 bkn_api_tx(sinfo); 4452 if ((++dcbs_done + done) >= MAX_TX_DCBS) { 4453 if (sinfo->napi_poll_mode) { 4454 /* Request one extra poll to reschedule Tx */ 4455 sinfo->napi_poll_again = 1; 4456 } else { 4457 /* Request to yield for Continuous DMA mode */ 4458 sinfo->tx_yield = 1; 4459 } 4460 return; 4461 } 4462 } 4463 woffset = (sinfo->tx.api_dcb_chain->dcb_cnt - 1) * sinfo->dcb_wsize - 1; 4464 if (!(sinfo->tx.api_dcb_chain->dcb_mem[woffset] & (1 << 31))) { 4465 return; 4466 } 4467 sinfo->tx.api_dcb_chain->dcb_mem[woffset] |= SOC_DCB_KNET_DONE; 4468 /* Try and park at SKB Tx if API Tx done */ 4469 bkn_skb_tx(sinfo); 4470 sinfo->dma_events |= KCOM_DMA_INFO_F_TX_DONE; 4471 evt->evt_wq_put++; 4472 wake_up_interruptible(&evt->evt_wq); 4473 kfree(sinfo->tx.api_dcb_chain); 4474 sinfo->tx.api_dcb_chain = NULL; 4475 sinfo->tx.api_dcb_chain_end = NULL; 4476 if (!sinfo->napi_poll_mode) { 4477 /* Not need to yield for Continuous DMA mode */ 4478 sinfo->tx_yield = 0; 4479 } 4480 } else { 4481 if (sinfo->tx.free == MAX_TX_DCBS) { 4482 /* Try API Tx if SKB Tx done */ 4483 bkn_api_tx(sinfo); 4484 if (sinfo->tx.api_active) { 4485 return; 4486 } 4487 } 4488 } 4489 4490 /* Resume if netif Tx resources available and API Tx not active */ 4491 bkn_resume_tx(sinfo); 4492 } 4493 4494 static void 4495 bkn_tx_chain_done(bkn_switch_info_t *sinfo, int done) 4496 { 4497 bkn_desc_info_t *desc; 4498 int idx, pending; 4499 bkn_evt_resource_t *evt; 4500 4501 if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN)) { 4502 return bkn_tx_cdma_chain_done(sinfo, done); 4503 } 4504 4505 DBG_IRQ(("Tx chain done (%d/%d)\n", sinfo->tx.cur, sinfo->tx.dirty)); 4506 4507 dev_irq_mask_disable(sinfo, XGS_DMA_TX_CHAN, 0); 4508 4509 evt = &_bkn_evt[sinfo->evt_idx]; 4510 4511 if (sinfo->tx.api_active) { 4512 sinfo->dma_events |= KCOM_DMA_INFO_F_TX_DONE; 4513 evt->evt_wq_put++; 4514 wake_up_interruptible(&evt->evt_wq); 4515 /* Check if BCM API has more to send */ 4516 bkn_api_tx(sinfo); 4517 if (sinfo->tx.api_active) { 4518 return; 4519 } 4520 } 4521 4522 if (sinfo->tx.free == MAX_TX_DCBS) { 4523 /* If netif Tx is idle then allow BCM API to send */ 4524 bkn_api_tx(sinfo); 4525 if (sinfo->tx.api_active) { 4526 return; 4527 } 4528 } else { 4529 /* If two or more DCBs are pending, chain them */ 4530 pending = MAX_TX_DCBS - sinfo->tx.free; 4531 idx = sinfo->tx.dirty; 4532 while (--pending && idx < (MAX_TX_DCBS - 1)) { 4533 if (sinfo->cmic_type == 'x') { 4534 sinfo->tx.desc[idx++].dcb_mem[2] |= 1 << 16; 4535 } else { 4536 sinfo->tx.desc[idx++].dcb_mem[1] |= 1 << 16; 4537 } 4538 DBG_DCB_TX(("Chain Tx DCB %d (%d)\n", idx, pending)); 4539 } 4540 /* Restart DMA from where we stopped */ 4541 desc = &sinfo->tx.desc[sinfo->tx.dirty]; 4542 DBG_DCB_TX(("Restart Tx DMA, DCB @ 0x%08x (%d).\n", 4543 (uint32_t)desc->dcb_dma, sinfo->tx.dirty)); 4544 dev_dma_chan_clear(sinfo, XGS_DMA_TX_CHAN); 4545 dev_irq_mask_enable(sinfo, XGS_DMA_TX_CHAN, 0); 4546 dev_dma_chan_start(sinfo, XGS_DMA_TX_CHAN, desc->dcb_dma); 4547 } 4548 4549 /* Resume if netif Tx resources available and API Tx not active */ 4550 bkn_resume_tx(sinfo); 4551 } 4552 4553 static void 4554 bkn_schedule_napi_poll(bkn_switch_info_t *sinfo) 4555 { 4556 /* Schedule NAPI poll */ 4557 DBG_NAPI(("Schedule NAPI poll on %s.\n", sinfo->dev->name)); 4558 /* Disable interrupts until poll job is complete */ 4559 sinfo->napi_poll_mode = 1; 4560 /* Unlock while calling up network stack */ 4561 spin_unlock(&sinfo->lock); 4562 if (bkn_napi_schedule_prep(sinfo->dev, &sinfo->napi)) { 4563 __bkn_napi_schedule(sinfo->dev, &sinfo->napi); 4564 DBG_NAPI(("Schedule prep OK on %s.\n", sinfo->dev->name)); 4565 } else { 4566 /* Most likely the base device is has not been opened */ 4567 gprintk("Warning: Unable to schedule NAPI - base device not up?\n"); 4568 } 4569 spin_lock(&sinfo->lock); 4570 } 4571 4572 static void 4573 bkn_napi_poll_complete(bkn_switch_info_t *sinfo) 4574 { 4575 /* Unlock while calling up network stack */ 4576 spin_unlock(&sinfo->lock); 4577 bkn_napi_complete(sinfo->dev, &sinfo->napi); 4578 spin_lock(&sinfo->lock); 4579 /* Re-enable interrupts */ 4580 sinfo->napi_poll_mode = 0; 4581 dev_irq_mask_set(sinfo, sinfo->irq_mask); 4582 } 4583 4584 static int 4585 xgs_do_dma(bkn_switch_info_t *sinfo, int budget) 4586 { 4587 int rx_dcbs_done = 0, tx_dcbs_done = 0; 4588 int chan_done, budget_chans = 0; 4589 uint32_t dma_stat; 4590 int chan; 4591 4592 DEV_READ32(sinfo, CMIC_DMA_STATr, &dma_stat); 4593 4594 for (chan = 0; chan < sinfo->rx_chans; chan++) { 4595 if (dma_stat & DS_DESC_DONE_TST(XGS_DMA_RX_CHAN + chan)) { 4596 xgs_dma_desc_clear(sinfo, XGS_DMA_RX_CHAN + chan); 4597 sinfo->poll_channels |= 1 << chan; 4598 } 4599 } 4600 if (!sinfo->poll_channels) { 4601 sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; 4602 budget_chans = budget / sinfo->rx_chans; 4603 } else { 4604 for (chan = 0; chan < sinfo->rx_chans; chan++) { 4605 if (1 << chan & sinfo->poll_channels) { 4606 budget_chans++; 4607 } 4608 } 4609 budget_chans = budget / budget_chans; 4610 } 4611 4612 for (chan = 0; chan < sinfo->rx_chans; chan++) { 4613 if (1 << chan & sinfo->poll_channels) { 4614 chan_done = bkn_do_rx(sinfo, chan, budget_chans); 4615 rx_dcbs_done += chan_done; 4616 if (chan_done < budget_chans) { 4617 sinfo->poll_channels &= ~(1 << chan); 4618 } 4619 bkn_rx_desc_done(sinfo, chan); 4620 } 4621 4622 if (dma_stat & DS_CHAIN_DONE_TST(XGS_DMA_RX_CHAN + chan)) { 4623 xgs_dma_chain_clear(sinfo, XGS_DMA_RX_CHAN + chan); 4624 bkn_rx_chain_done(sinfo, chan); 4625 } 4626 } 4627 4628 if (dma_stat & DS_CHAIN_DONE_TST(XGS_DMA_TX_CHAN)) { 4629 xgs_dma_chain_clear(sinfo, XGS_DMA_TX_CHAN); 4630 tx_dcbs_done = bkn_do_tx(sinfo); 4631 bkn_tx_chain_done(sinfo, tx_dcbs_done); 4632 } 4633 4634 return sinfo->poll_channels ? budget : rx_dcbs_done; 4635 } 4636 4637 static int 4638 xgsm_do_dma(bkn_switch_info_t *sinfo, int budget) 4639 { 4640 int rx_dcbs_done = 0, tx_dcbs_done = 0; 4641 int chan_done, budget_chans = 0; 4642 uint32_t dma_stat, irq_stat = 0; 4643 int chan; 4644 4645 /* Get Controlled interrupt states for Continuous DMA mode */ 4646 if (sinfo->cdma_channels) { 4647 DEV_READ32(sinfo, CMICM_IRQ_STATr, &irq_stat); 4648 } 4649 4650 DEV_READ32(sinfo, CMICM_DMA_STATr, &dma_stat); 4651 4652 for (chan = 0; chan < sinfo->rx_chans; chan++) { 4653 if (dma_stat & (0x10 << (XGS_DMA_RX_CHAN + chan)) || 4654 irq_stat & (0x08000000 << (XGS_DMA_RX_CHAN + chan))) { 4655 xgsm_dma_desc_clear(sinfo, XGS_DMA_RX_CHAN + chan); 4656 sinfo->poll_channels |= 1 << chan; 4657 } 4658 } 4659 if (!sinfo->poll_channels) { 4660 sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; 4661 budget_chans = budget / sinfo->rx_chans; 4662 } else { 4663 for (chan = 0; chan < sinfo->rx_chans; chan++) { 4664 if (1 << chan & sinfo->poll_channels) { 4665 budget_chans++; 4666 } 4667 } 4668 budget_chans = budget / budget_chans; 4669 } 4670 4671 for (chan = 0; chan < sinfo->rx_chans; chan++) { 4672 if (1 << chan & sinfo->poll_channels) { 4673 chan_done = bkn_do_rx(sinfo, chan, budget_chans); 4674 rx_dcbs_done += chan_done; 4675 if (chan_done < budget_chans) { 4676 sinfo->poll_channels &= ~(1 << chan); 4677 } 4678 bkn_rx_desc_done(sinfo, chan); 4679 } 4680 4681 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 4682 continue; 4683 } 4684 4685 if (dma_stat & (0x1 << (XGS_DMA_RX_CHAN + chan))) { 4686 xgsm_dma_chain_clear(sinfo, XGS_DMA_RX_CHAN + chan); 4687 bkn_rx_chain_done(sinfo, chan); 4688 } 4689 } 4690 4691 if (dma_stat & (0x1 << XGS_DMA_TX_CHAN) || 4692 irq_stat & (0x08000000 << XGS_DMA_TX_CHAN)) { 4693 if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN)) { 4694 xgsm_dma_desc_clear(sinfo, XGS_DMA_TX_CHAN); 4695 } else { 4696 xgsm_dma_chain_clear(sinfo, XGS_DMA_TX_CHAN); 4697 } 4698 tx_dcbs_done = bkn_do_tx(sinfo); 4699 bkn_tx_chain_done(sinfo, tx_dcbs_done); 4700 } 4701 4702 return sinfo->poll_channels ? budget : rx_dcbs_done; 4703 } 4704 4705 static int 4706 xgsx_do_dma(bkn_switch_info_t *sinfo, int budget) 4707 { 4708 int rx_dcbs_done = 0, tx_dcbs_done = 0; 4709 int chan_done, budget_chans = 0; 4710 uint32_t irq_stat, tx_dma_stat, rx_dma_stat[NUM_CMICX_RX_CHAN]; 4711 int chan; 4712 4713 DEV_READ32(sinfo, CMICX_IRQ_STATr, &irq_stat); 4714 DEV_READ32(sinfo, CMICX_DMA_STATr + 0x80 * XGS_DMA_TX_CHAN, &tx_dma_stat); 4715 for (chan = 0; chan < sinfo->rx_chans; chan++) { 4716 DEV_READ32(sinfo, 4717 CMICX_DMA_STATr + 0x80 * (XGS_DMA_RX_CHAN + chan), 4718 &rx_dma_stat[chan]); 4719 } 4720 4721 for (chan = 0; chan < sinfo->rx_chans; chan++) { 4722 if ((irq_stat & CMICX_DS_CMC_CTRLD_INT(XGS_DMA_RX_CHAN + chan)) || 4723 (irq_stat & CMICX_DS_CMC_DESC_DONE(XGS_DMA_RX_CHAN + chan))) { 4724 xgsx_dma_desc_clear(sinfo, XGS_DMA_RX_CHAN + chan); 4725 sinfo->poll_channels |= 1 << chan; 4726 } 4727 } 4728 if (!sinfo->poll_channels) { 4729 sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; 4730 budget_chans = budget / sinfo->rx_chans; 4731 } else { 4732 for (chan = 0; chan < sinfo->rx_chans; chan++) { 4733 if (1 << chan & sinfo->poll_channels) { 4734 budget_chans++; 4735 } 4736 } 4737 budget_chans = budget / budget_chans; 4738 } 4739 4740 for (chan = 0; chan < sinfo->rx_chans; chan++) { 4741 if (1 << chan & sinfo->poll_channels) { 4742 chan_done = bkn_do_rx(sinfo, chan, budget_chans); 4743 rx_dcbs_done += chan_done; 4744 if (chan_done < budget_chans) { 4745 sinfo->poll_channels &= ~(1 << chan); 4746 } 4747 bkn_rx_desc_done(sinfo, chan); 4748 } 4749 4750 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 4751 continue; 4752 } 4753 4754 if (rx_dma_stat[chan] & CMICX_DS_CMC_DMA_CHAIN_DONE) { 4755 xgsx_dma_chain_clear(sinfo, XGS_DMA_RX_CHAN + chan); 4756 bkn_rx_chain_done(sinfo, chan); 4757 } 4758 } 4759 4760 if ((irq_stat & CMICX_DS_CMC_CTRLD_INT(XGS_DMA_TX_CHAN)) || 4761 (tx_dma_stat & CMICX_DS_CMC_DMA_CHAIN_DONE)) { 4762 if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN)) { 4763 xgsx_dma_desc_clear(sinfo, XGS_DMA_TX_CHAN); 4764 } else { 4765 xgsx_dma_chain_clear(sinfo, XGS_DMA_TX_CHAN); 4766 } 4767 tx_dcbs_done = bkn_do_tx(sinfo); 4768 bkn_tx_chain_done(sinfo, tx_dcbs_done); 4769 } 4770 4771 return sinfo->poll_channels ? budget : rx_dcbs_done; 4772 } 4773 4774 static int 4775 dev_do_dma(bkn_switch_info_t *sinfo, int budget) 4776 { 4777 if (DEV_IS_CMICX(sinfo)) { 4778 return xgsx_do_dma(sinfo, budget); 4779 } else if (DEV_IS_CMICM(sinfo)) { 4780 return xgsm_do_dma(sinfo, budget); 4781 } else { 4782 return xgs_do_dma(sinfo, budget); 4783 } 4784 } 4785 4786 static void 4787 xgs_isr(bkn_switch_info_t *sinfo) 4788 { 4789 uint32_t irq_stat; 4790 int rx_dcbs_done; 4791 4792 DEV_READ32(sinfo, CMIC_IRQ_STATr, &irq_stat); 4793 if ((irq_stat & sinfo->irq_mask) == 0) { 4794 /* Not ours */ 4795 return; 4796 } 4797 sinfo->interrupts++; 4798 4799 DBG_IRQ(("Got interrupt on device %d (0x%08x)\n", 4800 sinfo->dev_no, irq_stat)); 4801 4802 if (use_napi) { 4803 bkn_schedule_napi_poll(sinfo); 4804 } else { 4805 xgs_irq_mask_set(sinfo, 0); 4806 do { 4807 rx_dcbs_done = xgs_do_dma(sinfo, MAX_RX_DCBS); 4808 } while (rx_dcbs_done); 4809 } 4810 4811 xgs_irq_mask_set(sinfo, sinfo->irq_mask); 4812 } 4813 4814 static void 4815 xgsm_isr(bkn_switch_info_t *sinfo) 4816 { 4817 uint32_t irq_stat; 4818 int rx_dcbs_done; 4819 4820 DEV_READ32(sinfo, CMICM_IRQ_STATr, &irq_stat); 4821 if ((irq_stat & sinfo->irq_mask) == 0) { 4822 /* Not ours */ 4823 return; 4824 } 4825 sinfo->interrupts++; 4826 4827 DBG_IRQ(("Got interrupt on device %d (0x%08x)\n", 4828 sinfo->dev_no, irq_stat)); 4829 4830 if (use_napi) { 4831 bkn_schedule_napi_poll(sinfo); 4832 } else { 4833 xgsm_irq_mask_set(sinfo, 0); 4834 do { 4835 rx_dcbs_done = xgsm_do_dma(sinfo, MAX_RX_DCBS); 4836 if (sinfo->cdma_channels) { 4837 if (rx_dcbs_done >= MAX_RX_DCBS || sinfo->tx_yield) { 4838 /* Continuous DMA mode requires to yield timely */ 4839 break; 4840 } 4841 } 4842 } while (rx_dcbs_done); 4843 } 4844 4845 xgsm_irq_mask_set(sinfo, sinfo->irq_mask); 4846 } 4847 4848 static void 4849 xgsx_isr(bkn_switch_info_t *sinfo) 4850 { 4851 uint32_t irq_stat; 4852 int rx_dcbs_done; 4853 4854 DEV_READ32(sinfo, CMICX_IRQ_STATr, &irq_stat); 4855 if ((irq_stat & sinfo->irq_mask) == 0) { 4856 /* Not ours */ 4857 return; 4858 } 4859 sinfo->interrupts++; 4860 4861 DBG_IRQ(("Got interrupt on device %d (0x%08x)\n", 4862 sinfo->dev_no, irq_stat)); 4863 4864 if (use_napi) { 4865 bkn_schedule_napi_poll(sinfo); 4866 } else { 4867 xgsx_irq_mask_set(sinfo, 0); 4868 do { 4869 rx_dcbs_done = xgsx_do_dma(sinfo, MAX_RX_DCBS); 4870 if (sinfo->cdma_channels) { 4871 if (rx_dcbs_done >= MAX_RX_DCBS || sinfo->tx_yield) { 4872 /* Continuous DMA mode requires to yield timely */ 4873 break; 4874 } 4875 } 4876 } while (rx_dcbs_done); 4877 } 4878 4879 xgsx_irq_mask_set(sinfo, sinfo->irq_mask); 4880 } 4881 4882 static void 4883 bkn_isr(void *isr_data) 4884 { 4885 bkn_switch_info_t *sinfo = isr_data; 4886 4887 /* Safe exit on SMP systems */ 4888 if (!module_initialized) { 4889 return; 4890 } 4891 4892 /* Ensure that we do not touch registers during device reset */ 4893 if (sinfo->irq_mask == 0) { 4894 /* Not ours */ 4895 return; 4896 } 4897 4898 spin_lock(&sinfo->lock); 4899 4900 if (sinfo->napi_poll_mode) { 4901 /* Not ours */ 4902 spin_unlock(&sinfo->lock); 4903 return; 4904 } 4905 4906 if (DEV_IS_CMICX(sinfo)) { 4907 xgsx_isr(sinfo); 4908 } else if (DEV_IS_CMICM(sinfo)) { 4909 xgsm_isr(sinfo); 4910 } else { 4911 xgs_isr(sinfo); 4912 } 4913 4914 spin_unlock(&sinfo->lock); 4915 } 4916 4917 #ifdef CONFIG_NET_POLL_CONTROLLER 4918 static void 4919 bkn_poll_controller(struct net_device *dev) 4920 { 4921 bkn_priv_t *priv = netdev_priv(dev); 4922 4923 disable_irq(dev->irq); 4924 bkn_isr(priv->sinfo); 4925 enable_irq(dev->irq); 4926 } 4927 #endif 4928 4929 static void 4930 bkn_resume_rx(bkn_switch_info_t *sinfo) 4931 { 4932 bkn_desc_info_t *desc; 4933 bkn_dcb_chain_t *dcb_chain; 4934 uint64_t cur_halt, last_dcb, dcb_dma; 4935 int woffset, chan, cdma_running; 4936 4937 /* Resume Rx DMA on all channels */ 4938 for (chan = 0; chan < sinfo->rx_chans; chan++) { 4939 if (sinfo->rx[chan].use_rx_skb) { 4940 cdma_running = 0; 4941 bkn_api_rx_restart(sinfo, chan); 4942 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 4943 cur_halt = sinfo->halt_addr[XGS_DMA_RX_CHAN + chan]; 4944 last_dcb = sinfo->rx[chan].desc[MAX_RX_DCBS].dcb_dma; 4945 if (cur_halt != last_dcb) { 4946 desc = &sinfo->rx[chan].desc[sinfo->rx[chan].dirty + 1]; 4947 bkn_cdma_goto(sinfo, XGS_DMA_RX_CHAN + chan, desc->dcb_dma); 4948 cdma_running = 1; 4949 } 4950 } 4951 if (!cdma_running) { 4952 bkn_rx_restart(sinfo, chan); 4953 } 4954 } else { 4955 cdma_running = 0; 4956 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 4957 if (sinfo->rx[chan].api_active) { 4958 dcb_chain = sinfo->rx[chan].api_dcb_chain_end; 4959 woffset = (dcb_chain->dcb_cnt - 1) * sinfo->dcb_wsize; 4960 dcb_dma = dcb_chain->dcb_dma + woffset * sizeof(uint32_t); 4961 bkn_cdma_goto(sinfo, XGS_DMA_RX_CHAN + chan, dcb_dma); 4962 cdma_running = 1; 4963 } 4964 } 4965 if (!cdma_running) { 4966 bkn_api_rx_restart(sinfo, chan); 4967 } 4968 } 4969 } 4970 } 4971 4972 static int 4973 bkn_open(struct net_device *dev) 4974 { 4975 bkn_priv_t *priv = netdev_priv(dev); 4976 bkn_switch_info_t *sinfo = priv->sinfo; 4977 unsigned long flags; 4978 4979 /* Check if base device */ 4980 if (priv->id <= 0) { 4981 /* NAPI used only on base device */ 4982 if (use_napi) { 4983 bkn_napi_enable(dev, &sinfo->napi); 4984 } 4985 4986 /* Start DMA when base device is started */ 4987 if (sinfo->basedev_suspended) { 4988 spin_lock_irqsave(&sinfo->lock, flags); 4989 dev_do_dma(sinfo, MAX_RX_DCBS); 4990 sinfo->basedev_suspended = 0; 4991 bkn_api_tx(sinfo); 4992 if (!sinfo->tx.api_active) { 4993 bkn_resume_tx(sinfo); 4994 } 4995 bkn_resume_rx(sinfo); 4996 spin_unlock_irqrestore(&sinfo->lock, flags); 4997 } 4998 } 4999 5000 if (!sinfo->basedev_suspended) { 5001 netif_start_queue(dev); 5002 } 5003 5004 return 0; 5005 } 5006 5007 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) 5008 static int 5009 bkn_set_mac_address(struct net_device *dev, void *addr) 5010 { 5011 if (!is_valid_ether_addr(((struct sockaddr *)addr)->sa_data)) { 5012 return -EINVAL; 5013 } 5014 memcpy(dev->dev_addr, ((struct sockaddr *)addr)->sa_data, dev->addr_len); 5015 return 0; 5016 } 5017 #endif 5018 5019 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) 5020 static int 5021 bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 5022 { 5023 bkn_priv_t *priv = netdev_priv(dev); 5024 bkn_switch_info_t *sinfo = priv->sinfo; 5025 struct hwtstamp_config config; 5026 5027 if (cmd == SIOCSHWTSTAMP) { 5028 if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) { 5029 return -EFAULT; 5030 } 5031 5032 if (!knet_hw_tstamp_enable_cb || !knet_hw_tstamp_disable_cb || 5033 priv->type != KCOM_NETIF_T_PORT) { 5034 return -ERANGE; 5035 } 5036 5037 switch (config.tx_type) { 5038 case HWTSTAMP_TX_OFF: 5039 knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); 5040 sinfo->tx_hwts = 0; 5041 break; 5042 case HWTSTAMP_TX_ON: 5043 knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); 5044 sinfo->tx_hwts = 1; 5045 break; 5046 default: 5047 return -ERANGE; 5048 } 5049 5050 switch (config.rx_filter) { 5051 case HWTSTAMP_FILTER_NONE: 5052 if (sinfo->rx_hwts) { 5053 knet_hw_tstamp_disable_cb(sinfo->dev_no, priv->port); 5054 sinfo->rx_hwts = 0; 5055 } 5056 break; 5057 default: 5058 if (!sinfo->rx_hwts) { 5059 knet_hw_tstamp_enable_cb(sinfo->dev_no, priv->port); 5060 sinfo->rx_hwts = 1; 5061 } 5062 config.rx_filter = HWTSTAMP_FILTER_ALL; 5063 break; 5064 } 5065 5066 return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; 5067 } 5068 5069 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) 5070 if (cmd == SIOCGHWTSTAMP) { 5071 config.flags = 0; 5072 config.tx_type = sinfo->tx_hwts ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; 5073 config.rx_filter = sinfo->rx_hwts ? HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; 5074 5075 return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; 5076 } 5077 #endif 5078 5079 return -EINVAL; 5080 } 5081 #endif 5082 5083 static int 5084 bkn_change_mtu(struct net_device *dev, int new_mtu) 5085 { 5086 int max_size = new_mtu + ETH_HLEN + VLAN_HLEN + 4; 5087 5088 if (new_mtu < 68 || max_size > rx_buffer_size) { 5089 return -EINVAL; 5090 } 5091 dev->mtu = new_mtu; 5092 return 0; 5093 } 5094 5095 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 5096 static int 5097 bkn_poll(struct net_device *dev, int *budget) 5098 { 5099 bkn_priv_t *priv = netdev_priv(dev); 5100 bkn_switch_info_t *sinfo = priv->sinfo; 5101 int cur_budget = *budget; 5102 int poll_again = 0; 5103 int rx_dcbs_done; 5104 unsigned long flags; 5105 5106 spin_lock_irqsave(&sinfo->lock, flags); 5107 5108 DBG_NAPI(("NAPI poll on %s.\n", dev->name)); 5109 5110 sinfo->napi_poll_again = 0; 5111 5112 if (cur_budget > dev->quota) { 5113 cur_budget = dev->quota; 5114 } 5115 5116 rx_dcbs_done = dev_do_dma(sinfo, cur_budget); 5117 5118 *budget -= rx_dcbs_done; 5119 cur_budget -= rx_dcbs_done; 5120 dev->quota -= rx_dcbs_done; 5121 5122 if (sinfo->napi_poll_again || cur_budget <= 0) { 5123 poll_again = 1; 5124 sinfo->napi_not_done++; 5125 } else { 5126 bkn_napi_poll_complete(sinfo); 5127 } 5128 5129 spin_unlock_irqrestore(&sinfo->lock, flags); 5130 5131 return poll_again; 5132 } 5133 #else 5134 static int 5135 bkn_poll(struct napi_struct *napi, int budget) 5136 { 5137 bkn_switch_info_t *sinfo = container_of(napi, bkn_switch_info_t, napi); 5138 int rx_dcbs_done; 5139 unsigned long flags; 5140 5141 spin_lock_irqsave(&sinfo->lock, flags); 5142 5143 DBG_NAPI(("NAPI poll on %s.\n", sinfo->dev->name)); 5144 5145 sinfo->napi_poll_again = 0; 5146 5147 rx_dcbs_done = dev_do_dma(sinfo, budget); 5148 5149 if (sinfo->napi_poll_again || rx_dcbs_done >= budget) { 5150 /* Force poll again */ 5151 rx_dcbs_done = budget; 5152 sinfo->napi_not_done++; 5153 } else { 5154 bkn_napi_poll_complete(sinfo); 5155 } 5156 5157 spin_unlock_irqrestore(&sinfo->lock, flags); 5158 5159 return rx_dcbs_done; 5160 } 5161 #endif 5162 5163 static int 5164 bkn_stop(struct net_device *dev) 5165 { 5166 bkn_priv_t *priv = netdev_priv(dev); 5167 bkn_switch_info_t *sinfo = priv->sinfo; 5168 unsigned long flags; 5169 5170 netif_stop_queue(dev); 5171 5172 /* Check if base device */ 5173 if (priv->id <= 0) { 5174 /* NAPI used only on base device */ 5175 if (use_napi) { 5176 bkn_napi_disable(dev, &sinfo->napi); 5177 } 5178 /* Suspend all devices if base device is stopped */ 5179 if (basedev_suspend) { 5180 spin_lock_irqsave(&sinfo->lock, flags); 5181 bkn_suspend_tx(sinfo); 5182 sinfo->basedev_suspended = 1; 5183 spin_unlock_irqrestore(&sinfo->lock, flags); 5184 } 5185 } 5186 5187 return 0; 5188 } 5189 5190 /* 5191 * Network Device Statistics. 5192 * Cleared at init time. 5193 */ 5194 static struct net_device_stats * 5195 bkn_get_stats(struct net_device *dev) 5196 { 5197 bkn_priv_t *priv = netdev_priv(dev); 5198 5199 return &priv->stats; 5200 } 5201 5202 /* Fake multicast ability */ 5203 static void 5204 bkn_set_multicast_list(struct net_device *dev) 5205 { 5206 } 5207 5208 static int 5209 bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, struct sk_buff *skb, uint32_t *meta) 5210 { 5211 uint32_t *md = NULL; 5212 5213 if (!knet_hw_tstamp_tx_meta_get_cb) { 5214 return -1; 5215 } 5216 5217 KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; 5218 knet_hw_tstamp_tx_meta_get_cb(sinfo->dev_no, skb, &md); 5219 if (!md) { 5220 return -1; 5221 } 5222 5223 switch (sinfo->dcb_type) { 5224 case 26: 5225 case 32: 5226 case 33: 5227 meta[2] |= md[0]; 5228 meta[3] |= md[1]; 5229 meta[4] |= md[2]; 5230 meta[5] |= md[3]; 5231 break; 5232 case 36: 5233 case 38: 5234 meta[0] |= md[0]; 5235 meta[1] |= md[1]; 5236 meta[2] |= md[2]; 5237 meta[3] |= md[3]; 5238 break; 5239 default: 5240 return -1; 5241 } 5242 5243 return 0; 5244 } 5245 5246 static int 5247 bkn_tx(struct sk_buff *skb, struct net_device *dev) 5248 { 5249 bkn_priv_t *priv = netdev_priv(dev); 5250 bkn_switch_info_t *sinfo = priv->sinfo; 5251 struct sk_buff *new_skb = NULL; 5252 unsigned char *pktdata; 5253 int pktlen, hdrlen, taglen, rcpulen, metalen; 5254 int sop, idx; 5255 uint16_t tpid; 5256 uint32_t *metadata; 5257 unsigned long flags; 5258 5259 DBG_VERB(("Netif Tx: Len=%d\n", skb->len)); 5260 5261 if (priv->id <= 0) { 5262 /* Do not transmit on base device */ 5263 priv->stats.tx_dropped++; 5264 dev_kfree_skb_any(skb); 5265 return 0; 5266 } 5267 5268 if (!netif_carrier_ok(dev)) { 5269 DBG_WARN(("Tx drop: Invalid RCPU encapsulation\n")); 5270 priv->stats.tx_dropped++; 5271 sinfo->tx.pkts_d_no_link++; 5272 dev_kfree_skb_any(skb); 5273 return 0; 5274 } 5275 5276 spin_lock_irqsave(&sinfo->lock, flags); 5277 5278 if (sinfo->tx.free > 1) { 5279 bkn_desc_info_t *desc = &sinfo->tx.desc[sinfo->tx.cur]; 5280 uint32_t *dcb, *meta; 5281 5282 pktdata = skb->data; 5283 pktlen = skb->len; 5284 hdrlen = (sinfo->cmic_type == 'x' ) ? ((device_is_dnx(sinfo)) ? priv->system_headers_size: PKT_TX_HDR_SIZE) : 0; 5285 rcpulen = 0; 5286 sop = 0; 5287 5288 if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { 5289 rcpulen = RCPU_HDR_SIZE; 5290 if (skb->len < (rcpulen + 14)) { 5291 DBG_WARN(("Tx drop: Invalid RCPU encapsulation\n")); 5292 priv->stats.tx_dropped++; 5293 sinfo->tx.pkts_d_rcpu_encap++; 5294 dev_kfree_skb_any(skb); 5295 spin_unlock_irqrestore(&sinfo->lock, flags); 5296 return 0; 5297 } 5298 if (check_rcpu_signature && 5299 ((skb->data[18] << 8) | skb->data[19]) != sinfo->rcpu_sig) { 5300 DBG_WARN(("Tx drop: Invalid RCPU signature\n")); 5301 priv->stats.tx_dropped++; 5302 sinfo->tx.pkts_d_rcpu_sig++; 5303 dev_kfree_skb_any(skb); 5304 spin_unlock_irqrestore(&sinfo->lock, flags); 5305 return 0; 5306 } 5307 if (skb->data[21] & RCPU_F_MODHDR) { 5308 sop = skb->data[RCPU_HDR_SIZE]; 5309 switch (sop) { 5310 case 0xff: 5311 case 0x81: 5312 case 0xfb: 5313 case 0xfc: 5314 break; 5315 default: 5316 DBG_WARN(("Tx drop: Invalid RCPU meta data\n")); 5317 priv->stats.tx_dropped++; 5318 sinfo->tx.pkts_d_rcpu_meta++; 5319 dev_kfree_skb_any(skb); 5320 spin_unlock_irqrestore(&sinfo->lock, flags); 5321 return 0; 5322 } 5323 if (sinfo->cmic_type != 'x') { 5324 rcpulen += RCPU_TX_META_SIZE; 5325 } 5326 } 5327 /* Skip over RCPU encapsulation */ 5328 pktdata = &skb->data[rcpulen]; 5329 pktlen -= rcpulen; 5330 5331 /* CPU packets require tag */ 5332 if (sop == 0) { 5333 hdrlen = 0; 5334 tpid = (pktdata[12] << 8) | pktdata[13]; 5335 if (tpid != 0x8100) { 5336 if (skb_header_cloned(skb)) { 5337 /* Current SKB cannot be modified */ 5338 DBG_SKB(("Realloc Tx SKB\n")); 5339 new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); 5340 if (new_skb == NULL) { 5341 DBG_WARN(("Tx drop: No SKB memory\n")); 5342 priv->stats.tx_dropped++; 5343 sinfo->tx.pkts_d_no_skb++; 5344 dev_kfree_skb_any(skb); 5345 spin_unlock_irqrestore(&sinfo->lock, flags); 5346 return 0; 5347 } 5348 memcpy(new_skb->data, pktdata, 12); 5349 memcpy(&new_skb->data[16], &pktdata[12], pktlen - 12); 5350 skb_put(new_skb, pktlen + TAG_SZ); 5351 dev_kfree_skb_any(skb); 5352 skb = new_skb; 5353 pktdata = skb->data; 5354 rcpulen = 0; 5355 } else { 5356 /* Add tag to RCPU header space */ 5357 DBG_SKB(("Expand into unused RCPU header\n")); 5358 rcpulen -= TAG_SZ; 5359 pktdata = &skb->data[rcpulen]; 5360 for (idx = 0; idx < 12; idx++) { 5361 pktdata[idx] = pktdata[idx + TAG_SZ]; 5362 } 5363 } 5364 pktdata[12] = 0x81; 5365 pktdata[13] = 0x00; 5366 pktdata[14] = (priv->vlan >> 8) & 0xf; 5367 pktdata[15] = priv->vlan & 0xff; 5368 pktlen += TAG_SZ; 5369 } 5370 } 5371 } else { 5372 if (sinfo->cmic_type == 'x' && priv->port >= 0) { 5373 if (skb_header_cloned(skb) || skb_headroom(skb) < hdrlen + 4) { 5374 /* Current SKB cannot be modified */ 5375 DBG_SKB(("Realloc Tx SKB\n")); 5376 new_skb = dev_alloc_skb(pktlen + hdrlen + 4 + FCS_SZ); 5377 if (new_skb == NULL) { 5378 DBG_WARN(("Tx drop: No SKB memory\n")); 5379 priv->stats.tx_dropped++; 5380 sinfo->tx.pkts_d_no_skb++; 5381 dev_kfree_skb_any(skb); 5382 spin_unlock_irqrestore(&sinfo->lock, flags); 5383 return 0; 5384 } 5385 if (!device_is_dnx(sinfo)) 5386 { 5387 skb_reserve(new_skb, 4); 5388 } 5389 memcpy(new_skb->data + hdrlen, skb->data, pktlen); 5390 skb_put(new_skb, pktlen + hdrlen); 5391 dev_kfree_skb_any(skb); 5392 skb = new_skb; 5393 } else { 5394 DBG_SKB(("Expand Tx SKB\n")); 5395 skb_push(skb, hdrlen); 5396 } 5397 memset(skb->data, 0, hdrlen); 5398 pktdata = skb->data; 5399 pktlen += hdrlen; 5400 } else { 5401 hdrlen = 0; 5402 } 5403 5404 if (priv->port < 0 || (priv->flags & KCOM_NETIF_F_ADD_TAG)) { 5405 DBG_DUNE(("ADD VLAN TAG\n")); 5406 /* Need to add VLAN tag if packet is untagged */ 5407 tpid = (skb->data[hdrlen + 12] << 8) | skb->data[hdrlen + 13]; 5408 if (tpid != 0x8100) { 5409 if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { 5410 /* Current SKB cannot be modified */ 5411 DBG_SKB(("Realloc Tx SKB\n")); 5412 new_skb = dev_alloc_skb(pktlen + TAG_SZ + FCS_SZ); 5413 if (new_skb == NULL) { 5414 DBG_WARN(("Tx drop: No SKB memory\n")); 5415 priv->stats.tx_dropped++; 5416 sinfo->tx.pkts_d_no_skb++; 5417 dev_kfree_skb_any(skb); 5418 spin_unlock_irqrestore(&sinfo->lock, flags); 5419 return 0; 5420 } 5421 memcpy(new_skb->data, skb->data, hdrlen + 12); 5422 memcpy(&new_skb->data[hdrlen + 16], &skb->data[hdrlen + 12], 5423 pktlen - hdrlen - 12); 5424 skb_put(new_skb, pktlen + TAG_SZ); 5425 dev_kfree_skb_any(skb); 5426 skb = new_skb; 5427 } else { 5428 /* Add tag to existing buffer */ 5429 DBG_SKB(("Expand Tx SKB\n")); 5430 skb_push(skb, TAG_SZ); 5431 for (idx = 0; idx < hdrlen + 12; idx++) { 5432 skb->data[idx] = skb->data[idx + TAG_SZ]; 5433 } 5434 } 5435 pktdata = skb->data; 5436 pktdata[hdrlen + 12] = 0x81; 5437 pktdata[hdrlen + 13] = 0x00; 5438 pktdata[hdrlen + 14] = (priv->vlan >> 8) & 0xf; 5439 pktdata[hdrlen + 15] = priv->vlan & 0xff; 5440 pktlen += TAG_SZ; 5441 } 5442 } 5443 } 5444 5445 /* Pad packet if needed */ 5446 taglen = 0; 5447 tpid = (pktdata[hdrlen + 12] << 8) | pktdata[hdrlen + 13]; 5448 if (tpid == 0x8100) { 5449 taglen = 4; 5450 } 5451 if (pktlen < (60 + taglen + hdrlen)) { 5452 pktlen = (60 + taglen + hdrlen); 5453 if (SKB_PADTO(skb, pktlen) != 0) { 5454 DBG_WARN(("Tx drop: skb_padto failed\n")); 5455 priv->stats.tx_dropped++; 5456 sinfo->tx.pkts_d_pad_fail++; 5457 dev_kfree_skb_any(skb); 5458 spin_unlock_irqrestore(&sinfo->lock, flags); 5459 return 0; 5460 } 5461 /* skb_padto may update the skb->data pointer */ 5462 pktdata = &skb->data[rcpulen]; 5463 } 5464 5465 if ((pktlen + FCS_SZ) > SOC_DCB_KNET_COUNT_MASK) { 5466 DBG_WARN(("Tx drop: size of pkt (%d) is out of range(%d)\n", 5467 (pktlen + FCS_SZ), SOC_DCB_KNET_COUNT_MASK)); 5468 sinfo->tx.pkts_d_over_limit++; 5469 priv->stats.tx_dropped++; 5470 dev_kfree_skb_any(skb); 5471 spin_unlock_irqrestore(&sinfo->lock, flags); 5472 return 0; 5473 } 5474 5475 dcb = desc->dcb_mem; 5476 meta = (sinfo->cmic_type == 'x') ? (uint32_t *)pktdata : dcb; 5477 memset(dcb, 0, sinfo->dcb_wsize * sizeof(uint32_t)); 5478 if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { 5479 /* If module header SOP is non-zero, use RCPU meta data */ 5480 if (sop != 0) { 5481 if (sinfo->cmic_type == 'x') { 5482 dcb[2] |= 1 << 19; 5483 } else { 5484 metalen = (sinfo->dcb_wsize - 3) * sizeof(uint32_t); 5485 if (metalen > RCPU_TX_META_SIZE) { 5486 metalen = RCPU_TX_META_SIZE; 5487 } 5488 metadata = (uint32_t *)&skb->data[RCPU_HDR_SIZE]; 5489 for (idx = 0; idx < BYTES2WORDS(metalen); idx++) { 5490 dcb[idx + 2] = ntohl(metadata[idx]); 5491 } 5492 dcb[1] |= 1 << 19; 5493 } 5494 } 5495 } else if (priv->port >= 0) { 5496 /* Send to physical port */ 5497 if (sinfo->cmic_type == 'x') { 5498 dcb[2] |= 1 << 19; 5499 } else { 5500 dcb[1] |= 1 << 19; 5501 } 5502 switch (sinfo->dcb_type) { 5503 case 23: 5504 case 26: 5505 case 30: 5506 case 31: 5507 case 34: 5508 case 37: 5509 dcb[2] = 0x81000000; 5510 dcb[3] = priv->port; 5511 dcb[3] |= (priv->qnum & 0xc00) << 20; 5512 dcb[4] = 0x00040000; 5513 dcb[4] |= (priv->qnum & 0x3ff) << 8; 5514 break; 5515 case 24: 5516 dcb[2] = 0xff000000; 5517 dcb[3] = 0x00000100; 5518 dcb[4] = priv->port; 5519 dcb[4] |= (priv->qnum & 0xfff) << 14; 5520 break; 5521 case 28: 5522 { 5523 if (priv->type == KCOM_NETIF_T_PORT) { 5524 /* add PTCH ITMH header */ 5525 if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { 5526 /* Current SKB cannot be modified */ 5527 DBG_SKB(("Realloc Tx SKB for DNX ITMH header\n")); 5528 new_skb = dev_alloc_skb(pktlen + 4 + 2 + FCS_SZ); 5529 if (new_skb == NULL) { 5530 DBG_WARN(("Tx drop: No SKB memory for DNX ITMH header\n")); 5531 priv->stats.tx_dropped++; 5532 sinfo->tx.pkts_d_no_skb++; 5533 dev_kfree_skb_any(skb); 5534 spin_unlock_irqrestore(&sinfo->lock, flags); 5535 return 0; 5536 } 5537 memcpy(&new_skb->data[6], skb->data, pktlen); 5538 skb_put(new_skb, pktlen + 6); 5539 dev_kfree_skb_any(skb); 5540 skb = new_skb; 5541 } else { 5542 /* Add tag to existing buffer */ 5543 DBG_SKB(("Expand Tx SKB for DNX ITMH header\n")); 5544 skb_push(skb, 6); 5545 } 5546 pktdata = skb->data; 5547 pktdata[0] = 0x50; 5548 pktdata[1] = 0x00; 5549 memcpy(&pktdata[2], priv->itmh, 4); 5550 pktlen += 6; 5551 } 5552 else if (priv->type == KCOM_NETIF_T_VLAN) { 5553 /* add PTCH header */ 5554 if (skb_header_cloned(skb) || skb_headroom(skb) < 4) { 5555 /* Current SKB cannot be modified */ 5556 DBG_SKB(("Realloc Tx SKB for DNX header\n")); 5557 new_skb = dev_alloc_skb(pktlen + 2 + FCS_SZ); 5558 if (new_skb == NULL) { 5559 DBG_WARN(("Tx drop: No SKB memory for DNX header\n")); 5560 priv->stats.tx_dropped++; 5561 sinfo->tx.pkts_d_no_skb++; 5562 dev_kfree_skb_any(skb); 5563 spin_unlock_irqrestore(&sinfo->lock, flags); 5564 return 0; 5565 } 5566 memcpy(&new_skb->data[2], skb->data, pktlen); 5567 skb_put(new_skb, pktlen + 2); 5568 dev_kfree_skb_any(skb); 5569 skb = new_skb; 5570 } else { 5571 /* Add tag to existing buffer */ 5572 DBG_SKB(("Expand Tx SKB for DNX header\n")); 5573 skb_push(skb, 2); 5574 } 5575 pktdata = skb->data; 5576 pktdata[0] = 0xd0; 5577 pktdata[1] = priv->port; 5578 pktlen += 2; 5579 } 5580 dcb[1] = pktlen; 5581 break; 5582 } 5583 case 29: 5584 dcb[2] = 0x81000000; 5585 dcb[3] = priv->port; 5586 dcb[4] = 0x00100000; 5587 dcb[4] |= (priv->qnum & 0xfff) << 8; 5588 break; 5589 case 32: 5590 dcb[2] = 0x81000000; 5591 dcb[3] = priv->port; 5592 dcb[4] = 0x00004000; 5593 dcb[4] |= (priv->qnum & 0x3f) << 8; 5594 break; 5595 case 33: 5596 dcb[2] = 0x81000000; 5597 dcb[3] = (priv->port) << 2; 5598 dcb[4] = 0x00100000; 5599 dcb[4] |= (priv->qnum & 0xfff) << 8; 5600 break; 5601 case 35: 5602 dcb[2] = 0x81000000; 5603 dcb[3] = (priv->port) << 4; 5604 dcb[4] = 0x00400000; 5605 dcb[4] |= (priv->qnum & 0x3fff) << 8; 5606 break; 5607 case 36: 5608 if (sinfo->cmic_type == 'x') { 5609 meta[0] = htonl(0x81000000); 5610 meta[1] = htonl(priv->port); 5611 meta[2] = htonl(0x00008000 | (priv->qnum & 0x3f) << 9); 5612 } else { 5613 dcb[2] = 0x81000000; 5614 dcb[3] = priv->port; 5615 dcb[4] = 0x00008000; 5616 dcb[4] |= (priv->qnum & 0x3f) << 9; 5617 } 5618 break; 5619 case 38: 5620 if (sinfo->cmic_type == 'x') { 5621 meta[0] = htonl(0x81000000); 5622 meta[1] = htonl(priv->port); 5623 meta[2] = htonl(0x00004000 | (priv->qnum & 0x3f) << 8); 5624 } else { 5625 dcb[2] = 0x81000000; 5626 dcb[3] = priv->port; 5627 dcb[4] = 0x00004000; 5628 dcb[4] |= (priv->qnum & 0x3f) << 8; 5629 } 5630 break; 5631 case 39: 5632 if (device_is_dnx(sinfo)) { 5633 /* 5634 * if KCOM_NETIF_T_PORT, add MH+PTCH+ITMH header 5635 * if KCOM_NETIF_T_VLAN, add MH+PTCH+header 5636 */ 5637 pktdata = skb->data; 5638 memcpy(&pktdata[0], priv->system_headers, priv->system_headers_size); 5639 } 5640 break; 5641 default: 5642 dcb[2] = 0xff000000; 5643 dcb[3] = 0x00000100; 5644 dcb[4] = priv->port; 5645 break; 5646 } 5647 } 5648 5649 /* Optional SKB updates */ 5650 if (knet_tx_cb != NULL) { 5651 KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; 5652 KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; 5653 skb = knet_tx_cb(skb, sinfo->dev_no, meta); 5654 if (skb == NULL) { 5655 /* Consumed by call-back */ 5656 DBG_WARN(("Tx drop: Consumed by call-back\n")); 5657 priv->stats.tx_dropped++; 5658 sinfo->tx.pkts_d_callback++; 5659 spin_unlock_irqrestore(&sinfo->lock, flags); 5660 return 0; 5661 } 5662 /* Restore (possibly) altered packet variables 5663 * bit0 -bit15 of dcb[1] is used to save requested byte count 5664 */ 5665 if ((skb->len + FCS_SZ) <= SOC_DCB_KNET_COUNT_MASK) { 5666 pktlen = skb->len; 5667 if (pktlen < (60 + taglen + hdrlen)) { 5668 pktlen = (60 + taglen + hdrlen); 5669 if (SKB_PADTO(skb, pktlen) != 0) { 5670 DBG_WARN(("Tx drop: skb_padto failed\n")); 5671 priv->stats.tx_dropped++; 5672 sinfo->tx.pkts_d_pad_fail++; 5673 dev_kfree_skb_any(skb); 5674 spin_unlock_irqrestore(&sinfo->lock, flags); 5675 return 0; 5676 } 5677 DBG_SKB(("Packet padded to %d bytes after tx callback\n", pktlen)); 5678 } 5679 pktdata = skb->data; 5680 if (sinfo->cmic_type == 'x') { 5681 meta = (uint32_t *)pktdata; 5682 } 5683 } else { 5684 DBG_WARN(("Tx drop: size of pkt (%d) is out of range(%d)\n", 5685 (pktlen + FCS_SZ), SOC_DCB_KNET_COUNT_MASK)); 5686 sinfo->tx.pkts_d_over_limit++; 5687 priv->stats.tx_dropped++; 5688 sinfo->tx.pkts_d_callback++; 5689 dev_kfree_skb_any(skb); 5690 spin_unlock_irqrestore(&sinfo->lock, flags); 5691 return 0; 5692 } 5693 } 5694 5695 /* Do Tx timestamping */ 5696 if (priv->port >= 0) { 5697 if (bkn_skb_tx_flags(skb) & SKBTX_HW_TSTAMP && sinfo->tx_hwts) { 5698 KNET_SKB_CB(skb)->port = priv->port; 5699 bkn_hw_tstamp_tx_config(sinfo, skb, meta); 5700 bkn_skb_tx_flags(skb) |= SKBTX_IN_PROGRESS; 5701 } 5702 bkn_skb_tx_timestamp(skb); 5703 } 5704 5705 /* Prepare for DMA */ 5706 desc->skb = skb; 5707 /* Add FCS bytes */ 5708 pktlen = pktlen + FCS_SZ; 5709 desc->dma_size = pktlen; 5710 desc->skb_dma = DMA_MAP_SINGLE(sinfo->dma_dev, 5711 pktdata, desc->dma_size, 5712 DMA_TODEV); 5713 if (DMA_MAPPING_ERROR(sinfo->dma_dev, desc->skb_dma)) { 5714 priv->stats.tx_dropped++; 5715 dev_kfree_skb_any(skb); 5716 spin_unlock_irqrestore(&sinfo->lock, flags); 5717 return 0; 5718 } 5719 dcb[0] = desc->skb_dma; 5720 if (sinfo->cmic_type == 'x') { 5721 dcb[1] = DMA_TO_BUS_HI(desc->skb_dma >> 32); 5722 dcb[2] &= ~SOC_DCB_KNET_COUNT_MASK; 5723 dcb[2] |= pktlen; 5724 } else { 5725 dcb[1] &= ~SOC_DCB_KNET_COUNT_MASK; 5726 dcb[1] |= pktlen; 5727 } 5728 5729 bkn_dump_dcb("Tx RCPU", dcb, sinfo->dcb_wsize, XGS_DMA_TX_CHAN); 5730 DBG_DCB_TX(("Add Tx DCB @ 0x%08x (%d) [%d free] (%d bytes).\n", 5731 (uint32_t)desc->dcb_dma, sinfo->tx.cur, 5732 sinfo->tx.free, pktlen)); 5733 bkn_dump_pkt(pktdata, pktlen, XGS_DMA_TX_CHAN); 5734 5735 if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN)) { 5736 if (sinfo->cmic_type == 'x') { 5737 dcb[2] |= 1 << 24 | 1 << 16; 5738 } else { 5739 dcb[1] |= 1 << 24 | 1 << 16; 5740 } 5741 } else { 5742 bkn_tx_dma_start(sinfo); 5743 } 5744 if (++sinfo->tx.cur >= MAX_TX_DCBS) { 5745 sinfo->tx.cur = 0; 5746 } 5747 sinfo->tx.free--; 5748 5749 if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN) && !sinfo->tx.api_active) { 5750 /* DMA run to the new halt location */ 5751 bkn_cdma_goto(sinfo, XGS_DMA_TX_CHAN, 5752 sinfo->tx.desc[sinfo->tx.cur].dcb_dma); 5753 } 5754 5755 priv->stats.tx_packets++; 5756 priv->stats.tx_bytes += pktlen; 5757 sinfo->tx.pkts++; 5758 } else { 5759 DBG_WARN(("Tx drop: No DMA resources\n")); 5760 priv->stats.tx_dropped++; 5761 sinfo->tx.pkts_d_dma_resrc++; 5762 dev_kfree_skb_any(skb); 5763 } 5764 5765 /* Check our Tx resources */ 5766 if (sinfo->tx.free <= 1) { 5767 bkn_suspend_tx(sinfo); 5768 } 5769 5770 NETDEV_UPDATE_TRANS_START_TIME(dev); 5771 5772 spin_unlock_irqrestore(&sinfo->lock, flags); 5773 5774 return 0; 5775 } 5776 5777 static void 5778 bkn_timer_func(bkn_switch_info_t *sinfo) 5779 { 5780 unsigned long flags; 5781 int chan; 5782 int restart_timer; 5783 5784 spin_lock_irqsave(&sinfo->lock, flags); 5785 5786 sinfo->timer_runs++; 5787 5788 restart_timer = 0; 5789 for (chan = 0; chan < sinfo->rx_chans; chan++) { 5790 /* Restart channel if not running */ 5791 if (sinfo->rx[chan].running == 0) { 5792 bkn_rx_refill(sinfo, chan); 5793 if (bkn_rx_restart(sinfo, chan) != 0) { 5794 restart_timer = 1; 5795 } 5796 } 5797 } 5798 5799 if (restart_timer) { 5800 /* Presumably still out of memory */ 5801 sinfo->timer.expires = jiffies + 1; 5802 add_timer(&sinfo->timer); 5803 } else { 5804 sinfo->timer_queued = 0; 5805 } 5806 5807 spin_unlock_irqrestore(&sinfo->lock, flags); 5808 } 5809 5810 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) 5811 static void 5812 bkn_timer(unsigned long context) 5813 { 5814 bkn_switch_info_t *sinfo = (bkn_switch_info_t *)context; 5815 return bkn_timer_func(sinfo); 5816 } 5817 #else 5818 static void 5819 bkn_timer(struct timer_list *t) 5820 { 5821 bkn_switch_info_t *sinfo = from_timer(sinfo, t, timer); 5822 return bkn_timer_func(sinfo); 5823 } 5824 #endif 5825 5826 static void 5827 bkn_rx_add_tokens(bkn_switch_info_t *sinfo, int chan) 5828 { 5829 unsigned long cur_jif, ticks; 5830 uint32_t tokens_per_tick; 5831 bkn_desc_info_t *desc; 5832 5833 tokens_per_tick = sinfo->rx[chan].rate_max / HZ; 5834 cur_jif = jiffies; 5835 ticks = cur_jif - sinfo->rx[chan].tok_jif; 5836 sinfo->rx[chan].tokens += ticks * tokens_per_tick; 5837 sinfo->rx[chan].tok_jif = cur_jif; 5838 if (sinfo->rx[chan].tokens > sinfo->rx[chan].burst_max) { 5839 sinfo->rx[chan].tokens = sinfo->rx[chan].burst_max; 5840 } 5841 5842 /* Restart channel if Rx is suppressed */ 5843 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 5844 bkn_rx_refill(sinfo, chan); 5845 desc = &sinfo->rx[chan].desc[sinfo->rx[chan].dirty]; 5846 if (desc->dcb_dma == sinfo->halt_addr[XGS_DMA_RX_CHAN + chan]) { 5847 desc = &sinfo->rx[chan].desc[MAX_RX_DCBS]; 5848 bkn_cdma_goto(sinfo, XGS_DMA_RX_CHAN + chan, desc->dcb_dma); 5849 } 5850 } else { 5851 if (sinfo->rx[chan].running == 0) { 5852 bkn_rx_refill(sinfo, chan); 5853 bkn_rx_restart(sinfo, chan); 5854 } 5855 } 5856 } 5857 5858 static void 5859 bkn_rxtick_func(bkn_switch_info_t *sinfo) 5860 { 5861 unsigned long flags; 5862 unsigned long cur_jif, ticks; 5863 uint32_t pkt_diff; 5864 int chan; 5865 5866 spin_lock_irqsave(&sinfo->lock, flags); 5867 5868 sinfo->rxtick.expires = jiffies + sinfo->rxtick_jiffies; 5869 5870 /* For debug purposes we maintain a rough actual packet rate */ 5871 if (++sinfo->rxticks >= sinfo->rxticks_per_sec) { 5872 for (chan = 0; chan < sinfo->rx_chans; chan++) { 5873 pkt_diff = sinfo->rx[chan].pkts - sinfo->rx[chan].pkts_ref; 5874 cur_jif = jiffies; 5875 ticks = cur_jif - sinfo->rx[chan].rate_jif; 5876 sinfo->rx[chan].rate = (pkt_diff * HZ) / ticks; 5877 sinfo->rx[chan].rate_jif = cur_jif; 5878 sinfo->rx[chan].pkts_ref = sinfo->rx[chan].pkts; 5879 } 5880 sinfo->rxticks = 0; 5881 } 5882 5883 /* Update tokens for Rx rate control */ 5884 for (chan = 0; chan < sinfo->rx_chans; chan++) { 5885 if (sinfo->rx[chan].tokens < sinfo->rx[chan].burst_max) { 5886 bkn_rx_add_tokens(sinfo, chan); 5887 } 5888 } 5889 5890 spin_unlock_irqrestore(&sinfo->lock, flags); 5891 5892 add_timer(&sinfo->rxtick); 5893 } 5894 5895 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) 5896 static void 5897 bkn_rxtick(unsigned long context) 5898 { 5899 bkn_switch_info_t *sinfo = (bkn_switch_info_t *)context; 5900 return bkn_rxtick_func(sinfo); 5901 } 5902 #else 5903 static void 5904 bkn_rxtick(struct timer_list *t) 5905 { 5906 bkn_switch_info_t *sinfo = from_timer(sinfo, t, rxtick); 5907 return bkn_rxtick_func(sinfo); 5908 } 5909 #endif 5910 5911 static void 5912 bkn_rx_rate_config(bkn_switch_info_t *sinfo) 5913 { 5914 unsigned long flags; 5915 int chan; 5916 uint32_t rxticks_per_sec, rps; 5917 uint32_t jiffies_per_rxtick; 5918 uint32_t tokens_per_rxtick; 5919 5920 spin_lock_irqsave(&sinfo->lock, flags); 5921 5922 /* Calculate the minimum update frequency across all channels */ 5923 rxticks_per_sec = 1; 5924 for (chan = 0; chan < NUM_RX_CHAN; chan++) { 5925 if (sinfo->rx[chan].burst_max == 0) { 5926 sinfo->rx[chan].burst_max = sinfo->rx[chan].rate_max / 10; 5927 } 5928 rps = sinfo->rx[chan].rate_max / sinfo->rx[chan].burst_max; 5929 if (rxticks_per_sec < rps) { 5930 rxticks_per_sec = rps; 5931 } 5932 } 5933 5934 /* Convert update frequency to system ticks */ 5935 jiffies_per_rxtick = HZ / rxticks_per_sec; 5936 if (jiffies_per_rxtick == 0) { 5937 jiffies_per_rxtick = 1; 5938 } 5939 rxticks_per_sec = HZ / jiffies_per_rxtick; 5940 5941 for (chan = 0; chan < NUM_RX_CHAN; chan++) { 5942 /* Ensure that burst size satifies overall rate */ 5943 tokens_per_rxtick = sinfo->rx[chan].rate_max / rxticks_per_sec; 5944 if (sinfo->rx[chan].burst_max < tokens_per_rxtick) { 5945 sinfo->rx[chan].burst_max = tokens_per_rxtick; 5946 } 5947 /* Ensure that rate has a sane value */ 5948 if (sinfo->rx[chan].rate_max != 0) { 5949 if (sinfo->rx[chan].rate_max < rxticks_per_sec) { 5950 sinfo->rx[chan].rate_max = rxticks_per_sec; 5951 } 5952 } 5953 sinfo->rx[chan].tokens = sinfo->rx[chan].burst_max; 5954 } 5955 5956 /* Update timer controls */ 5957 sinfo->rxticks_per_sec = rxticks_per_sec; 5958 sinfo->rxtick_jiffies = jiffies_per_rxtick; 5959 5960 spin_unlock_irqrestore(&sinfo->lock, flags); 5961 } 5962 5963 static void 5964 bkn_destroy_sinfo(bkn_switch_info_t *sinfo) 5965 { 5966 list_del(&sinfo->list); 5967 bkn_free_dcbs(sinfo); 5968 kfree(sinfo); 5969 } 5970 5971 static bkn_switch_info_t * 5972 bkn_create_sinfo(int dev_no) 5973 { 5974 bkn_switch_info_t *sinfo; 5975 int chan; 5976 5977 if ((sinfo = kmalloc(sizeof(*sinfo), GFP_KERNEL)) == NULL) { 5978 return NULL; 5979 } 5980 memset(sinfo, 0, sizeof(*sinfo)); 5981 INIT_LIST_HEAD(&sinfo->ndev_list); 5982 INIT_LIST_HEAD(&sinfo->rxpf_list); 5983 sinfo->base_addr = lkbde_get_dev_virt(dev_no); 5984 sinfo->dma_dev = lkbde_get_dma_dev(dev_no); 5985 sinfo->pdev = lkbde_get_hw_dev(dev_no); 5986 sinfo->dev_no = dev_no; 5987 sinfo->evt_idx = -1; 5988 5989 spin_lock_init(&sinfo->lock); 5990 skb_queue_head_init(&sinfo->tx_ptp_queue); 5991 INIT_WORK(&sinfo->tx_ptp_work, bkn_hw_tstamp_tx_work); 5992 5993 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) 5994 init_timer(&sinfo->timer); 5995 sinfo->timer.data = (unsigned long)sinfo; 5996 sinfo->timer.function = bkn_timer; 5997 #else 5998 timer_setup(&sinfo->timer, bkn_timer, 0); 5999 #endif 6000 sinfo->timer.expires = jiffies + 1; 6001 6002 INIT_LIST_HEAD(&sinfo->tx.api_dcb_list); 6003 6004 for (chan = 0; chan < NUM_RX_CHAN; chan++) { 6005 INIT_LIST_HEAD(&sinfo->rx[chan].api_dcb_list); 6006 sinfo->rx[chan].use_rx_skb = use_rx_skb; 6007 } 6008 6009 /* 6010 * Check for dual DMA mode where Rx DMA channel 0 uses DMA buffers 6011 * provided by the BCM API, and the remaining Rx DMA channel(s) 6012 * use socket buffers (SKB) provided by the Linux kernel. 6013 */ 6014 if (use_rx_skb == 2) { 6015 sinfo->rx[0].use_rx_skb = 0; 6016 } 6017 6018 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) 6019 init_timer(&sinfo->rxtick); 6020 sinfo->rxtick.data = (unsigned long)sinfo; 6021 sinfo->rxtick.function = bkn_rxtick; 6022 #else 6023 timer_setup(&sinfo->rxtick, bkn_rxtick, 0); 6024 #endif 6025 sinfo->rxtick.expires = jiffies + 1; 6026 6027 for (chan = 0; chan < NUM_RX_CHAN; chan++) { 6028 sinfo->rx[chan].rate_max = rx_rate[chan]; 6029 sinfo->rx[chan].burst_max = rx_burst[chan]; 6030 } 6031 bkn_rx_rate_config(sinfo); 6032 6033 add_timer(&sinfo->rxtick); 6034 6035 list_add_tail(&sinfo->list, &_sinfo_list); 6036 6037 return sinfo; 6038 } 6039 6040 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) 6041 static const struct net_device_ops bkn_netdev_ops = { 6042 .ndo_open = bkn_open, 6043 .ndo_stop = bkn_stop, 6044 .ndo_start_xmit = bkn_tx, 6045 .ndo_get_stats = bkn_get_stats, 6046 .ndo_validate_addr = eth_validate_addr, 6047 .ndo_set_rx_mode = bkn_set_multicast_list, 6048 .ndo_set_mac_address = bkn_set_mac_address, 6049 .ndo_do_ioctl = bkn_ioctl, 6050 .ndo_tx_timeout = NULL, 6051 .ndo_change_mtu = bkn_change_mtu, 6052 #ifdef CONFIG_NET_POLL_CONTROLLER 6053 .ndo_poll_controller = bkn_poll_controller, 6054 #endif 6055 }; 6056 #endif 6057 6058 static void 6059 bkn_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) 6060 { 6061 strlcpy(drvinfo->driver, "bcm-knet", sizeof(drvinfo->driver)); 6062 snprintf(drvinfo->version, sizeof(drvinfo->version), "%d", KCOM_VERSION); 6063 strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); 6064 strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info)); 6065 } 6066 6067 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) 6068 static int 6069 bkn_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) 6070 { 6071 bkn_priv_t *priv = netdev_priv(dev); 6072 bkn_switch_info_t *sinfo = priv->sinfo; 6073 6074 switch (sinfo->dcb_type) { 6075 case 26: 6076 case 32: 6077 case 33: 6078 case 36: 6079 case 38: 6080 info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | 6081 SOF_TIMESTAMPING_TX_SOFTWARE | 6082 SOF_TIMESTAMPING_RX_HARDWARE | 6083 SOF_TIMESTAMPING_RX_SOFTWARE | 6084 SOF_TIMESTAMPING_SOFTWARE | 6085 SOF_TIMESTAMPING_RAW_HARDWARE; 6086 info->tx_types = 1 << HWTSTAMP_TX_OFF | 1 << HWTSTAMP_TX_ON; 6087 info->rx_filters = 1 << HWTSTAMP_FILTER_NONE | 1 << HWTSTAMP_FILTER_ALL; 6088 if (knet_hw_tstamp_ptp_clock_index_cb) { 6089 info->phc_index = knet_hw_tstamp_ptp_clock_index_cb(sinfo->dev_no); 6090 } else { 6091 info->phc_index = -1; 6092 } 6093 break; 6094 default: 6095 info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | 6096 SOF_TIMESTAMPING_RX_SOFTWARE | 6097 SOF_TIMESTAMPING_SOFTWARE; 6098 info->phc_index = -1; 6099 break; 6100 } 6101 6102 return 0; 6103 } 6104 #endif 6105 6106 static const struct ethtool_ops bkn_ethtool_ops = { 6107 .get_drvinfo = bkn_get_drvinfo, 6108 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) 6109 .get_ts_info = bkn_get_ts_info, 6110 #endif 6111 }; 6112 6113 static struct net_device * 6114 bkn_init_ndev(u8 *mac, char *name) 6115 { 6116 struct net_device *dev; 6117 6118 /* Create Ethernet device */ 6119 dev = alloc_etherdev(sizeof(bkn_priv_t)); 6120 6121 if (dev == NULL) { 6122 DBG_WARN(("Error allocating Ethernet device.\n")); 6123 return NULL; 6124 } 6125 #ifdef SET_MODULE_OWNER 6126 SET_MODULE_OWNER(dev); 6127 #endif 6128 6129 /* Set the device MAC address */ 6130 memcpy(dev->dev_addr, mac, 6); 6131 6132 /* Device information -- not available right now */ 6133 dev->irq = 0; 6134 dev->base_addr = 0; 6135 6136 /* Default MTU should not exceed MTU of switch front-panel ports */ 6137 dev->mtu = default_mtu; 6138 if (dev->mtu == 0) { 6139 dev->mtu = rx_buffer_size; 6140 } 6141 6142 /* Device vectors */ 6143 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) 6144 dev->netdev_ops = &bkn_netdev_ops; 6145 #else 6146 dev->open = bkn_open; 6147 dev->hard_start_xmit = bkn_tx; 6148 dev->stop = bkn_stop; 6149 dev->set_multicast_list = bkn_set_multicast_list; 6150 dev->do_ioctl = NULL; 6151 dev->get_stats = bkn_get_stats; 6152 dev->change_mtu = bkn_change_mtu; 6153 #ifdef CONFIG_NET_POLL_CONTROLLER 6154 dev->poll_controller = bkn_poll_controller; 6155 #endif 6156 #endif 6157 dev->ethtool_ops = &bkn_ethtool_ops; 6158 if (name && *name) { 6159 strncpy(dev->name, name, IFNAMSIZ-1); 6160 } 6161 6162 /* Register the kernel Ethernet device */ 6163 if (register_netdev(dev)) { 6164 DBG_WARN(("Error registering Ethernet device.\n")); 6165 free_netdev(dev); 6166 return NULL; 6167 } 6168 DBG_VERB(("Created Ethernet device %s.\n", dev->name)); 6169 6170 return dev; 6171 } 6172 6173 /* 6174 * Device Link Control Proc Read Entry 6175 */ 6176 static int 6177 bkn_proc_link_show(struct seq_file *m, void *v) 6178 { 6179 struct list_head *slist, *dlist; 6180 struct net_device *dev; 6181 bkn_priv_t *priv; 6182 bkn_switch_info_t *sinfo; 6183 unsigned long flags; 6184 6185 seq_printf(m, "Software link status:\n"); 6186 list_for_each(slist, &_sinfo_list) { 6187 sinfo = (bkn_switch_info_t *)slist; 6188 spin_lock_irqsave(&sinfo->lock, flags); 6189 list_for_each(dlist, &sinfo->ndev_list) { 6190 priv = (bkn_priv_t *)dlist; 6191 dev = priv->dev; 6192 if (dev) { 6193 seq_printf(m, " %-14s %s\n", dev->name, 6194 netif_carrier_ok(dev) ? "up" : "down"); 6195 } 6196 } 6197 spin_unlock_irqrestore(&sinfo->lock, flags); 6198 } 6199 return 0; 6200 } 6201 6202 static int 6203 bkn_proc_link_open(struct inode * inode, struct file * file) 6204 { 6205 return single_open(file, bkn_proc_link_show, NULL); 6206 } 6207 6208 /* 6209 * Device Link Control Proc Write Entry 6210 * 6211 * Syntax: 6212 * <netif>=up|down 6213 * 6214 * Where <netif> is a virtual network interface name. 6215 * 6216 * Examples: 6217 * eth4=up 6218 * eth4=down 6219 */ 6220 static ssize_t 6221 bkn_proc_link_write(struct file *file, const char *buf, 6222 size_t count, loff_t *loff) 6223 { 6224 struct list_head *slist, *dlist; 6225 struct net_device *dev; 6226 bkn_priv_t *priv; 6227 bkn_switch_info_t *sinfo; 6228 unsigned long flags; 6229 char link_str[40]; 6230 char *ptr; 6231 char *newline; 6232 6233 if (count > sizeof(link_str)) { 6234 count = sizeof(link_str) - 1; 6235 link_str[count] = '\0'; 6236 } 6237 if (copy_from_user(link_str, buf, count)) { 6238 return -EFAULT; 6239 } 6240 link_str[count] = 0; 6241 newline = strchr(link_str, '\n'); 6242 if (newline) { 6243 /* Chop off the trailing newline */ 6244 *newline = '\0'; 6245 } 6246 6247 if ((ptr = strchr(link_str, '=')) == NULL && 6248 (ptr = strchr(link_str, ':')) == NULL) { 6249 gprintk("Error: link syntax not recognized: '%s'\n", link_str); 6250 return count; 6251 } 6252 *ptr++ = 0; 6253 6254 dev = NULL; 6255 list_for_each(slist, &_sinfo_list) { 6256 sinfo = (bkn_switch_info_t *)slist; 6257 spin_lock_irqsave(&sinfo->lock, flags); 6258 list_for_each(dlist, &sinfo->ndev_list) { 6259 priv = (bkn_priv_t *)dlist; 6260 if (priv->dev) { 6261 if (strcmp(priv->dev->name, link_str) == 0) { 6262 dev = priv->dev; 6263 break; 6264 } 6265 } 6266 } 6267 if (dev) { 6268 if (strcmp(ptr, "up") == 0) { 6269 netif_carrier_on(dev); 6270 } else if (strcmp(ptr, "down") == 0) { 6271 netif_carrier_off(dev); 6272 } else { 6273 gprintk("Warning: unknown link state setting: '%s'\n", ptr); 6274 } 6275 spin_unlock_irqrestore(&sinfo->lock, flags); 6276 return count; 6277 } 6278 spin_unlock_irqrestore(&sinfo->lock, flags); 6279 } 6280 6281 gprintk("Warning: unknown network interface: '%s'\n", link_str); 6282 6283 return count; 6284 } 6285 6286 struct file_operations bkn_proc_link_file_ops = { 6287 owner: THIS_MODULE, 6288 open: bkn_proc_link_open, 6289 read: seq_read, 6290 llseek: seq_lseek, 6291 write: bkn_proc_link_write, 6292 release: single_release, 6293 }; 6294 6295 /* 6296 * Device Rate Control Proc Read Entry 6297 */ 6298 static int 6299 bkn_proc_rate_show(struct seq_file *m, void *v) 6300 { 6301 int unit = 0; 6302 struct list_head *list; 6303 bkn_switch_info_t *sinfo; 6304 int chan; 6305 6306 list_for_each(list, &_sinfo_list) { 6307 sinfo = (bkn_switch_info_t *)list; 6308 6309 seq_printf(m, "Rate control (unit %d):\n", unit); 6310 for (chan = 0; chan < sinfo->rx_chans; chan++) { 6311 seq_printf(m, " Rx%d max rate %8u\n", 6312 chan, sinfo->rx[chan].rate_max); 6313 seq_printf(m, " Rx%d max burst %8u\n", 6314 chan, sinfo->rx[chan].burst_max); 6315 seq_printf(m, " Rx%d rate %8u\n", 6316 chan, sinfo->rx[chan].rate); 6317 seq_printf(m, " Rx%d tokens %8u\n", 6318 chan, sinfo->rx[chan].tokens); 6319 } 6320 6321 unit++; 6322 } 6323 return 0; 6324 } 6325 6326 static int 6327 bkn_proc_rate_open(struct inode * inode, struct file * file) 6328 { 6329 return single_open(file, bkn_proc_rate_show, NULL); 6330 } 6331 6332 /* 6333 * Device Rate Control Proc Write Entry 6334 * 6335 * Syntax: 6336 * [<unit>:]rx_rate=<rate0>[,<rate1>[,<rate2]] 6337 * 6338 * Where <rate0> is packets/sec for the first Rx DMA channel, 6339 * <rate1> is packets/sec for the second Rx DMA channel, etc. 6340 * 6341 * Examples: 6342 * rx_rate=5000 6343 * 0:rx_rate=10000,10000 6344 * 1:rx_rate=10000,5000 6345 */ 6346 static ssize_t 6347 bkn_proc_rate_write(struct file *file, const char *buf, 6348 size_t count, loff_t *loff) 6349 { 6350 bkn_switch_info_t *sinfo; 6351 char rate_str[80]; 6352 char *ptr; 6353 int unit, chan; 6354 6355 if (count > sizeof(rate_str)) { 6356 count = sizeof(rate_str) - 1; 6357 rate_str[count] = '\0'; 6358 } 6359 if (copy_from_user(rate_str, buf, count)) { 6360 return -EFAULT; 6361 } 6362 6363 unit = simple_strtol(rate_str, NULL, 10); 6364 sinfo = bkn_sinfo_from_unit(unit); 6365 if (sinfo == NULL) { 6366 gprintk("Warning: unknown unit: %d\n", unit); 6367 return count; 6368 } 6369 6370 if ((ptr = strstr(rate_str, "rx_rate=")) != NULL) { 6371 ptr += 7; 6372 chan = 0; 6373 do { 6374 ptr++; 6375 sinfo->rx[chan].rate_max = simple_strtol(ptr, NULL, 10); 6376 } while ((ptr = strchr(ptr, ',')) != NULL && ++chan < sinfo->rx_chans); 6377 bkn_rx_rate_config(sinfo); 6378 } else if ((ptr = strstr(rate_str, "rx_burst=")) != NULL) { 6379 ptr += 8; 6380 chan = 0; 6381 do { 6382 ptr++; 6383 sinfo->rx[chan].burst_max = simple_strtol(ptr, NULL, 10); 6384 } while ((ptr = strchr(ptr, ',')) != NULL && ++chan < sinfo->rx_chans); 6385 bkn_rx_rate_config(sinfo); 6386 } else { 6387 gprintk("Warning: unknown configuration setting\n"); 6388 } 6389 6390 return count; 6391 } 6392 6393 struct file_operations bkn_proc_rate_file_ops = { 6394 owner: THIS_MODULE, 6395 open: bkn_proc_rate_open, 6396 read: seq_read, 6397 llseek: seq_lseek, 6398 write: bkn_proc_rate_write, 6399 release: single_release, 6400 }; 6401 6402 /* 6403 * Driver DMA Proc Entry 6404 * 6405 * This output can be rather large (> PAGE_SIZE) so we use the 6406 * seq_file interface to do the output. Special header records 6407 * are indicated by a negative DCB index. 6408 */ 6409 typedef struct { 6410 int dev_no; /* Current unit */ 6411 int rx_dma; /* 0: Tx DMA, 1: Rx DMA*/ 6412 int ch_no; /* DMA channel no. (Rx only) */ 6413 int idx; /* DCB index */ 6414 } bkn_seq_dma_iter_t; 6415 6416 /* From current record, move forward 'pos' records */ 6417 static int 6418 bkn_seq_dma_next_pos(bkn_seq_dma_iter_t *iter, loff_t pos) 6419 { 6420 bkn_switch_info_t *sinfo; 6421 6422 sinfo = bkn_sinfo_from_unit(iter->dev_no); 6423 while (pos) { 6424 if (iter->rx_dma) { 6425 if (++iter->idx >= MAX_RX_DCBS + 1) { 6426 iter->idx = -1; 6427 if (++iter->ch_no >= sinfo->rx_chans) { 6428 iter->rx_dma = 0; 6429 iter->ch_no = 0; 6430 iter->dev_no++; 6431 if ((sinfo = bkn_sinfo_from_unit(iter->dev_no)) == NULL) { 6432 return -1; 6433 } 6434 } 6435 } 6436 } else { 6437 if (++iter->idx >= MAX_TX_DCBS + 1) { 6438 iter->idx = -1; 6439 iter->rx_dma = 1; 6440 } 6441 } 6442 pos--; 6443 } 6444 return 0; 6445 } 6446 6447 /* Initialize private data and move to requested start record */ 6448 static void * 6449 bkn_seq_dma_start(struct seq_file *s, loff_t *pos) 6450 { 6451 bkn_seq_dma_iter_t *iter; 6452 6453 iter = kmalloc(sizeof(bkn_seq_dma_iter_t), GFP_KERNEL); 6454 if (!iter) { 6455 return NULL; 6456 } 6457 memset(iter, 0, sizeof(*iter)); 6458 iter->idx = -2; 6459 if (bkn_seq_dma_next_pos(iter, *pos) < 0) { 6460 kfree(iter); 6461 return NULL; 6462 } 6463 return iter; 6464 } 6465 6466 /* Move to next record */ 6467 static void * 6468 bkn_seq_dma_next(struct seq_file *s, void *v, loff_t *pos) 6469 { 6470 bkn_seq_dma_iter_t *iter = (bkn_seq_dma_iter_t *)v; 6471 void *rv = iter; 6472 6473 if (bkn_seq_dma_next_pos(iter, 1) < 0) { 6474 return NULL; 6475 } 6476 (*pos)++; 6477 return rv; 6478 } 6479 6480 /* Release private data */ 6481 static void 6482 bkn_seq_dma_stop(struct seq_file *s, void *v) 6483 { 6484 if (v) { 6485 kfree(v); 6486 } 6487 } 6488 6489 /* Print current record */ 6490 static int 6491 bkn_seq_dma_show(struct seq_file *s, void *v) 6492 { 6493 bkn_seq_dma_iter_t *iter = (bkn_seq_dma_iter_t *)v; 6494 bkn_switch_info_t *sinfo; 6495 uint32_t *dcb = NULL; 6496 bkn_dcb_chain_t *dcb_chain = NULL; 6497 struct list_head *curr, *next; 6498 unsigned long flags; 6499 int chan, cnt; 6500 6501 sinfo = bkn_sinfo_from_unit(iter->dev_no); 6502 if (sinfo == NULL) { 6503 /* Should not happen */ 6504 return 0; 6505 } 6506 6507 if (iter->rx_dma == 0) { 6508 if (iter->idx == -2) { 6509 seq_printf(s, "Pending events: 0x%x\n", sinfo->dma_events); 6510 } else if (iter->idx == -1) { 6511 spin_lock_irqsave(&sinfo->lock, flags); 6512 curr = &sinfo->tx.api_dcb_list; 6513 dcb_chain = sinfo->tx.api_dcb_chain; 6514 while (dcb_chain) { 6515 seq_printf(s, " [0x%08lx]--->\n", (unsigned long)dcb_chain->dcb_dma); 6516 for (cnt = 0; cnt < dcb_chain->dcb_cnt; cnt++) { 6517 dcb = &dcb_chain->dcb_mem[sinfo->dcb_wsize * cnt]; 6518 if (sinfo->cmic_type == 'x') { 6519 seq_printf(s, " DCB %2d: 0x%08x 0x%08x 0x%08x 0x%08x\n", cnt, 6520 dcb[0], dcb[1], dcb[2], dcb[sinfo->dcb_wsize-1]); 6521 } else { 6522 seq_printf(s, " DCB %2d: 0x%08x 0x%08x ... 0x%08x\n", cnt, 6523 dcb[0], dcb[1], dcb[sinfo->dcb_wsize-1]); 6524 } 6525 } 6526 next = curr->next; 6527 if (next != &sinfo->tx.api_dcb_list) { 6528 dcb_chain = list_entry(next, bkn_dcb_chain_t, list); 6529 curr = next; 6530 } else { 6531 dcb_chain = NULL; 6532 } 6533 } 6534 dcb = NULL; 6535 spin_unlock_irqrestore(&sinfo->lock, flags); 6536 seq_printf(s, 6537 "Tx DCB info (unit %d):\n" 6538 " api: %d\n" 6539 " dirty: %d\n" 6540 " cur: %d\n" 6541 " free: %d\n" 6542 " pause: %s\n", 6543 iter->dev_no, 6544 sinfo->tx.api_active, 6545 sinfo->tx.dirty, 6546 sinfo->tx.cur, 6547 sinfo->tx.free, 6548 netif_queue_stopped(sinfo->dev) ? "yes" : "no"); 6549 if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN)) { 6550 bkn_desc_info_t *desc = &sinfo->tx.desc[0]; 6551 uint64_t halt = sinfo->halt_addr[XGS_DMA_TX_CHAN]; 6552 seq_printf(s, 6553 " halt: %d\n", 6554 (int)((uint32_t)(halt - desc->dcb_dma) / (sinfo->dcb_wsize * sizeof(uint32_t)))); 6555 } 6556 } else { 6557 dcb = sinfo->tx.desc[iter->idx].dcb_mem; 6558 if (iter->idx == 0) { 6559 seq_printf(s, " [0x%08lx]--->\n", (unsigned long)sinfo->tx.desc[0].dcb_dma); 6560 } 6561 } 6562 } else { 6563 if (iter->idx == -1) { 6564 chan = iter->ch_no; 6565 seq_printf(s, 6566 "Rx%d DCB info (unit %d):\n" 6567 " api: %d\n" 6568 " dirty: %d\n" 6569 " cur: %d\n" 6570 " free: %d\n" 6571 " run: %d\n", 6572 chan, iter->dev_no, 6573 sinfo->rx[chan].api_active, 6574 sinfo->rx[chan].dirty, 6575 sinfo->rx[chan].cur, 6576 sinfo->rx[chan].free, 6577 sinfo->rx[chan].running); 6578 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan) && sinfo->rx[chan].use_rx_skb) { 6579 bkn_desc_info_t *desc = &sinfo->rx[chan].desc[0]; 6580 uint64_t halt = sinfo->halt_addr[XGS_DMA_RX_CHAN + chan]; 6581 seq_printf(s, 6582 " halt: %d\n", 6583 (int)((uint32_t)(halt - desc->dcb_dma) / (sinfo->dcb_wsize * sizeof(uint32_t)))); 6584 } 6585 } else if (sinfo->rx[iter->ch_no].use_rx_skb) { 6586 dcb = sinfo->rx[iter->ch_no].desc[iter->idx].dcb_mem; 6587 if (iter->idx == 0) { 6588 seq_printf(s, " [0x%08lx]--->\n", (unsigned long)sinfo->rx[iter->ch_no].desc[0].dcb_dma); 6589 } 6590 } else if (!sinfo->rx[iter->ch_no].use_rx_skb && iter->idx == 0) { 6591 spin_lock_irqsave(&sinfo->lock, flags); 6592 curr = &sinfo->rx[iter->ch_no].api_dcb_list; 6593 dcb_chain = sinfo->rx[iter->ch_no].api_dcb_chain; 6594 while (dcb_chain) { 6595 seq_printf(s, " [0x%08lx]--->\n", (unsigned long)dcb_chain->dcb_dma); 6596 for (cnt = 0; cnt < dcb_chain->dcb_cnt; cnt++) { 6597 dcb = &dcb_chain->dcb_mem[sinfo->dcb_wsize * cnt]; 6598 if (sinfo->cmic_type == 'x') { 6599 seq_printf(s, " DCB %2d: 0x%08x 0x%08x 0x%08x 0x%08x\n", cnt, 6600 dcb[0], dcb[1], dcb[2], dcb[sinfo->dcb_wsize-1]); 6601 } else { 6602 seq_printf(s, " DCB %2d: 0x%08x 0x%08x ... 0x%08x\n", cnt, 6603 dcb[0], dcb[1], dcb[sinfo->dcb_wsize-1]); 6604 } 6605 } 6606 next = curr->next; 6607 if (next != &sinfo->rx[iter->ch_no].api_dcb_list) { 6608 dcb_chain = list_entry(next, bkn_dcb_chain_t, list); 6609 curr = next; 6610 } else { 6611 dcb_chain = NULL; 6612 } 6613 } 6614 dcb = NULL; 6615 spin_unlock_irqrestore(&sinfo->lock, flags); 6616 } 6617 } 6618 if (dcb) { 6619 if (sinfo->cmic_type == 'x') { 6620 seq_printf(s, " DCB %2d: 0x%08x 0x%08x 0x%08x 0x%08x\n", iter->idx, 6621 dcb[0], dcb[1], dcb[2], dcb[sinfo->dcb_wsize-1]); 6622 } else { 6623 seq_printf(s, " DCB %2d: 0x%08x 0x%08x ... 0x%08x\n", iter->idx, 6624 dcb[0], dcb[1], dcb[sinfo->dcb_wsize-1]); 6625 } 6626 } 6627 return 0; 6628 } 6629 6630 static struct seq_operations bkn_seq_dma_ops = { 6631 .start = bkn_seq_dma_start, 6632 .next = bkn_seq_dma_next, 6633 .stop = bkn_seq_dma_stop, 6634 .show = bkn_seq_dma_show 6635 }; 6636 6637 static int 6638 bkn_seq_dma_open(struct inode *inode, struct file *file) 6639 { 6640 return seq_open(file, &bkn_seq_dma_ops); 6641 }; 6642 6643 static struct file_operations bkn_seq_dma_file_ops = { 6644 .owner = THIS_MODULE, 6645 .open = bkn_seq_dma_open, 6646 .read = seq_read, 6647 .llseek = seq_lseek, 6648 .release = seq_release 6649 }; 6650 6651 /* 6652 * Device Debug Control Proc Write Entry 6653 * 6654 * Syntax: 6655 * [<unit>:]debug=<mask> 6656 * 6657 * Where <mask> corresponds to the debug module parameter. 6658 * 6659 * Examples: 6660 * debug=0xffff 6661 * 0:debug-0x2000 6662 */ 6663 static ssize_t 6664 bkn_proc_debug_write(struct file *file, const char *buf, 6665 size_t count, loff_t *loff) 6666 { 6667 bkn_switch_info_t *sinfo; 6668 char debug_str[40]; 6669 char *ptr; 6670 int unit; 6671 6672 if (count > sizeof(debug_str)) { 6673 count = sizeof(debug_str) - 1; 6674 debug_str[count] = '\0'; 6675 } 6676 if (copy_from_user(debug_str, buf, count)) { 6677 return -EFAULT; 6678 } 6679 6680 unit = simple_strtol(debug_str, NULL, 10); 6681 sinfo = bkn_sinfo_from_unit(unit); 6682 if (sinfo == NULL) { 6683 gprintk("Warning: unknown unit: %d\n", unit); 6684 return count; 6685 } 6686 6687 if ((ptr = strstr(debug_str, "debug=")) != NULL) { 6688 ptr += 6; 6689 debug = simple_strtol(ptr, NULL, 0); 6690 } else { 6691 gprintk("Warning: unknown configuration setting\n"); 6692 } 6693 6694 return count; 6695 } 6696 6697 /* 6698 * Driver Debug Proc Entry 6699 */ 6700 static int 6701 bkn_proc_debug_show(struct seq_file *m, void *v) 6702 { 6703 int unit = 0; 6704 struct list_head *list; 6705 bkn_switch_info_t *sinfo; 6706 6707 seq_printf(m, "Configuration:\n"); 6708 seq_printf(m, " debug: 0x%x\n", debug); 6709 seq_printf(m, " mac_addr: %02x:%02x:%02x:%02x:%02x:%02x\n", 6710 bkn_dev_mac[0], bkn_dev_mac[1], bkn_dev_mac[2], 6711 bkn_dev_mac[3], bkn_dev_mac[4], bkn_dev_mac[5]); 6712 seq_printf(m, " rx_buffer_size: %d (0x%x)\n", 6713 rx_buffer_size, rx_buffer_size); 6714 seq_printf(m, " rcpu_mode: %d\n", rcpu_mode); 6715 seq_printf(m, " rcpu_dmac: %02x:%02x:%02x:%02x:%02x:%02x\n", 6716 bkn_rcpu_dmac[0], bkn_rcpu_dmac[1], bkn_rcpu_dmac[2], 6717 bkn_rcpu_dmac[3], bkn_rcpu_dmac[4], bkn_rcpu_dmac[5]); 6718 seq_printf(m, " rcpu_smac: %02x:%02x:%02x:%02x:%02x:%02x\n", 6719 bkn_rcpu_smac[0], bkn_rcpu_smac[1], bkn_rcpu_smac[2], 6720 bkn_rcpu_smac[3], bkn_rcpu_smac[4], bkn_rcpu_smac[5]); 6721 seq_printf(m, " rcpu_ethertype: 0x%x\n", rcpu_ethertype); 6722 seq_printf(m, " rcpu_signature: 0x%x\n", rcpu_signature); 6723 seq_printf(m, " rcpu_vlan: %d\n", rcpu_vlan); 6724 seq_printf(m, " use_rx_skb: %d\n", use_rx_skb); 6725 seq_printf(m, " num_rx_prio: %d\n", num_rx_prio); 6726 seq_printf(m, " check_rcpu_sig: %d\n", check_rcpu_signature); 6727 seq_printf(m, " default_mtu: %d\n", default_mtu); 6728 seq_printf(m, " rx_sync_retry: %d\n", rx_sync_retry); 6729 seq_printf(m, " use_napi: %d\n", use_napi); 6730 seq_printf(m, " napi_weight: %d\n", napi_weight); 6731 seq_printf(m, " basedev_susp: %d\n", basedev_suspend); 6732 seq_printf(m, "Thread states:\n"); 6733 seq_printf(m, " Command thread: %d\n", bkn_cmd_ctrl.state); 6734 seq_printf(m, " Event thread: %d\n", bkn_evt_ctrl.state); 6735 seq_printf(m, "Active IOCTLs:\n"); 6736 seq_printf(m, " Command: %d\n", ioctl_cmd); 6737 seq_printf(m, " Event: %d\n", ioctl_evt); 6738 6739 list_for_each(list, &_sinfo_list) { 6740 sinfo = (bkn_switch_info_t *)list; 6741 6742 seq_printf(m, "Device %d:\n", unit); 6743 seq_printf(m, " base_addr: 0x%p\n", sinfo->base_addr); 6744 seq_printf(m, " dev_no: %d\n", sinfo->dev_no); 6745 seq_printf(m, " cmic_type: %c\n", sinfo->cmic_type); 6746 seq_printf(m, " dcb_type: %d\n", sinfo->dcb_type); 6747 seq_printf(m, " dcb_wsize: %d\n", sinfo->dcb_wsize); 6748 seq_printf(m, " pkt_hdr_size: %d\n", sinfo->pkt_hdr_size); 6749 seq_printf(m, " rx_chans: %d\n", sinfo->rx_chans); 6750 seq_printf(m, " cdma_chans: 0x%x\n", sinfo->cdma_channels); 6751 seq_printf(m, " irq_mask: 0x%x\n", sinfo->irq_mask); 6752 seq_printf(m, " dma_events: 0x%x\n", sinfo->dma_events); 6753 seq_printf(m, " dcb_dma: 0x%p\n", (void *)(sal_paddr_t)sinfo->dcb_dma); 6754 seq_printf(m, " dcb_mem_size: 0x%x\n", sinfo->dcb_mem_size); 6755 seq_printf(m, " rcpu_sig: 0x%x\n", sinfo->rcpu_sig); 6756 seq_printf(m, " napi_poll_mode: %d\n", sinfo->napi_poll_mode); 6757 seq_printf(m, " inst_id: 0x%x\n", sinfo->inst_id); 6758 seq_printf(m, " evt_queue: %d\n", sinfo->evt_idx); 6759 6760 unit++; 6761 } 6762 6763 return 0; 6764 } 6765 6766 static int bkn_proc_debug_open(struct inode * inode, struct file * file) 6767 { 6768 return single_open(file, bkn_proc_debug_show, NULL); 6769 } 6770 6771 struct file_operations bkn_proc_debug_file_ops = { 6772 owner: THIS_MODULE, 6773 open: bkn_proc_debug_open, 6774 read: seq_read, 6775 llseek: seq_lseek, 6776 write: bkn_proc_debug_write, 6777 release: single_release, 6778 }; 6779 6780 /* 6781 * Device Statistics Proc Entry 6782 */ 6783 static int 6784 bkn_proc_stats_show(struct seq_file *m, void *v) 6785 { 6786 int unit = 0; 6787 struct list_head *list, *flist; 6788 bkn_switch_info_t *sinfo; 6789 bkn_filter_t *filter; 6790 int chan; 6791 6792 6793 list_for_each(list, &_sinfo_list) { 6794 sinfo = (bkn_switch_info_t *)list; 6795 6796 seq_printf(m, "Device stats (unit %d):\n", unit); 6797 seq_printf(m, " Interrupts %10u\n", sinfo->interrupts); 6798 seq_printf(m, " Tx packets %10u\n", sinfo->tx.pkts); 6799 for (chan = 0; chan < sinfo->rx_chans; chan++) { 6800 seq_printf(m, " Rx%d packets %10u\n", chan, sinfo->rx[chan].pkts); 6801 } 6802 for (chan = 0; chan < sinfo->rx_chans; chan++) { 6803 if (sinfo->interrupts == 0) { 6804 /* Avoid divide-by-zero */ 6805 seq_printf(m, " Rx%d pkts/intr -\n", chan); 6806 } else { 6807 seq_printf(m, " Rx%d pkts/intr %8u\n", 6808 chan, sinfo->rx[chan].pkts / sinfo->interrupts); 6809 } 6810 } 6811 seq_printf(m, " Timer runs %10u\n", sinfo->timer_runs); 6812 seq_printf(m, " NAPI reruns %10u\n", sinfo->napi_not_done); 6813 6814 list_for_each(flist, &sinfo->rxpf_list) { 6815 filter = (bkn_filter_t *)flist; 6816 6817 seq_printf(m, " Filter %d stats:\n", filter->kf.id); 6818 seq_printf(m, " Hits %10lu\n", filter->hits); 6819 } 6820 6821 unit++; 6822 } 6823 return 0; 6824 } 6825 6826 static int bkn_proc_stats_open(struct inode * inode, struct file * file) 6827 { 6828 return single_open(file, bkn_proc_stats_show, NULL); 6829 } 6830 6831 /* 6832 * Device Statistics Proc Write Entry 6833 * 6834 * Syntax: 6835 * [<unit>:]clear[=all] 6836 * 6837 * Where <mask> corresponds to the debug module parameter. 6838 * 6839 * Examples: 6840 * clear 6841 * 0:clear=all 6842 */ 6843 static ssize_t 6844 bkn_proc_stats_write(struct file *file, const char *buf, 6845 size_t count, loff_t *loff) 6846 { 6847 bkn_switch_info_t *sinfo; 6848 struct list_head *flist; 6849 bkn_filter_t *filter; 6850 char debug_str[40]; 6851 char *ptr; 6852 int unit; 6853 int clear_mask; 6854 int chan; 6855 6856 if (count > sizeof(debug_str)) { 6857 count = sizeof(debug_str) - 1; 6858 debug_str[count] = '\0'; 6859 } 6860 if (copy_from_user(debug_str, buf, count)) { 6861 return -EFAULT; 6862 } 6863 6864 unit = simple_strtol(debug_str, NULL, 10); 6865 sinfo = bkn_sinfo_from_unit(unit); 6866 if (sinfo == NULL) { 6867 gprintk("Warning: unknown unit: %d\n", unit); 6868 return count; 6869 } 6870 6871 clear_mask = 0; 6872 if ((ptr = strstr(debug_str, "clear=")) != NULL) { 6873 ptr += 6; 6874 if (strncmp(ptr, "all", 3) == 0) { 6875 clear_mask = ~0; 6876 } 6877 } else if ((ptr = strstr(debug_str, "clear")) != NULL) { 6878 clear_mask = ~0; 6879 } else { 6880 gprintk("Warning: unknown configuration setting\n"); 6881 } 6882 6883 if (clear_mask) { 6884 sinfo->tx.pkts = 0; 6885 for (chan = 0; chan < sinfo->rx_chans; chan++) { 6886 sinfo->rx[chan].pkts = 0; 6887 } 6888 sinfo->interrupts = 0; 6889 sinfo->timer_runs = 0; 6890 sinfo->napi_not_done = 0; 6891 list_for_each(flist, &sinfo->rxpf_list) { 6892 filter = (bkn_filter_t *)flist; 6893 filter->hits = 0; 6894 } 6895 } 6896 6897 return count; 6898 } 6899 6900 struct file_operations bkn_proc_stats_file_ops = { 6901 owner: THIS_MODULE, 6902 open: bkn_proc_stats_open, 6903 read: seq_read, 6904 llseek: seq_lseek, 6905 write: bkn_proc_stats_write, 6906 release: single_release, 6907 }; 6908 6909 /* 6910 * Device Debug Statistics Proc Entry 6911 */ 6912 static int 6913 bkn_proc_dstats_show(struct seq_file *m, void *v) 6914 { 6915 int unit = 0; 6916 struct list_head *list; 6917 bkn_switch_info_t *sinfo; 6918 int chan; 6919 6920 list_for_each(list, &_sinfo_list) { 6921 sinfo = (bkn_switch_info_t *)list; 6922 6923 seq_printf(m, "Device debug stats (unit %d):\n", unit); 6924 seq_printf(m, " Tx drop no skb %10u\n", 6925 sinfo->tx.pkts_d_no_skb); 6926 seq_printf(m, " Tx drop rcpu encap %10u\n", 6927 sinfo->tx.pkts_d_rcpu_encap); 6928 seq_printf(m, " Tx drop rcpu sig %10u\n", 6929 sinfo->tx.pkts_d_rcpu_sig); 6930 seq_printf(m, " Tx drop rcpu meta %10u\n", 6931 sinfo->tx.pkts_d_rcpu_meta); 6932 seq_printf(m, " Tx drop pad failed %10u\n", 6933 sinfo->tx.pkts_d_pad_fail); 6934 seq_printf(m, " Tx drop no resource %10u\n", 6935 sinfo->tx.pkts_d_dma_resrc); 6936 seq_printf(m, " Tx drop callback %10u\n", 6937 sinfo->tx.pkts_d_callback); 6938 seq_printf(m, " Tx drop no link %10u\n", 6939 sinfo->tx.pkts_d_no_link); 6940 seq_printf(m, " Tx drop oversized %10u\n", 6941 sinfo->tx.pkts_d_over_limit); 6942 seq_printf(m, " Tx suspends %10u\n", 6943 sinfo->tx.suspends); 6944 for (chan = 0; chan < sinfo->rx_chans; chan++) { 6945 seq_printf(m, " Rx%d filter to api %10u\n", 6946 chan, sinfo->rx[chan].pkts_f_api); 6947 seq_printf(m, " Rx%d filter to netif %10u\n", 6948 chan, sinfo->rx[chan].pkts_f_netif); 6949 seq_printf(m, " Rx%d mirror to api %10u\n", 6950 chan, sinfo->rx[chan].pkts_m_api); 6951 seq_printf(m, " Rx%d mirror to netif %10u\n", 6952 chan, sinfo->rx[chan].pkts_m_netif); 6953 seq_printf(m, " Rx%d drop no skb %10u\n", 6954 chan, sinfo->rx[chan].pkts_d_no_skb); 6955 seq_printf(m, " Rx%d drop no match %10u\n", 6956 chan, sinfo->rx[chan].pkts_d_no_match); 6957 seq_printf(m, " Rx%d drop unkn netif %10u\n", 6958 chan, sinfo->rx[chan].pkts_d_unkn_netif); 6959 seq_printf(m, " Rx%d drop unkn dest %10u\n", 6960 chan, sinfo->rx[chan].pkts_d_unkn_dest); 6961 seq_printf(m, " Rx%d drop callback %10u\n", 6962 chan, sinfo->rx[chan].pkts_d_callback); 6963 seq_printf(m, " Rx%d drop no link %10u\n", 6964 chan, sinfo->rx[chan].pkts_d_no_link); 6965 seq_printf(m, " Rx%d sync error %10u\n", 6966 chan, sinfo->rx[chan].sync_err); 6967 seq_printf(m, " Rx%d sync retry %10u\n", 6968 chan, sinfo->rx[chan].sync_retry); 6969 seq_printf(m, " Rx%d sync maxloop %10u\n", 6970 chan, sinfo->rx[chan].sync_maxloop); 6971 seq_printf(m, " Rx%d drop no buffer %10u\n", 6972 chan, sinfo->rx[chan].pkts_d_no_api_buf); 6973 } 6974 unit++; 6975 } 6976 return 0; 6977 } 6978 6979 static int bkn_proc_dstats_open(struct inode * inode, struct file * file) 6980 { 6981 return single_open(file, bkn_proc_dstats_show, NULL); 6982 } 6983 6984 /* 6985 * Device Debug Statistics Proc Write Entry 6986 * 6987 * Syntax: 6988 * [<unit>:]clear[=all|tx|rx[<chan>]] 6989 * 6990 * Where <mask> corresponds to the debug module parameter. 6991 * 6992 * Examples: 6993 * clear 6994 * 0:clear=rx1 6995 */ 6996 static ssize_t 6997 bkn_proc_dstats_write(struct file *file, const char *buf, 6998 size_t count, loff_t *loff) 6999 { 7000 bkn_switch_info_t *sinfo; 7001 char debug_str[40]; 7002 char *ptr; 7003 int unit; 7004 int clear_mask; 7005 int chan; 7006 7007 if (count > sizeof(debug_str)) { 7008 count = sizeof(debug_str) - 1; 7009 debug_str[count] = '\0'; 7010 } 7011 if (copy_from_user(debug_str, buf, count)) { 7012 return -EFAULT; 7013 } 7014 7015 unit = simple_strtol(debug_str, NULL, 10); 7016 sinfo = bkn_sinfo_from_unit(unit); 7017 if (sinfo == NULL) { 7018 gprintk("Warning: unknown unit: %d\n", unit); 7019 return count; 7020 } 7021 7022 clear_mask = 0; 7023 if ((ptr = strstr(debug_str, "clear=")) != NULL) { 7024 ptr += 6; 7025 if (strncmp(ptr, "all", 3) == 0) { 7026 clear_mask = ~0; 7027 } else if (strncmp(ptr, "dev", 3) == 0) { 7028 clear_mask = 0x20; 7029 } else if (strncmp(ptr, "tx", 2) == 0) { 7030 clear_mask = 0x10; 7031 } else if (strncmp(ptr, "rx0", 3) == 0) { 7032 clear_mask = (1 << 0); 7033 } else if (strncmp(ptr, "rx1", 3) == 0) { 7034 clear_mask = (1 << 1); 7035 } else if (strncmp(ptr, "rx", 2) == 0) { 7036 clear_mask = 0xf; 7037 } 7038 } else if ((ptr = strstr(debug_str, "clear")) != NULL) { 7039 clear_mask = ~0; 7040 } else { 7041 gprintk("Warning: unknown configuration setting\n"); 7042 } 7043 7044 /* Tx counters */ 7045 if (clear_mask & 0x10) { 7046 sinfo->tx.pkts_d_no_skb = 0; 7047 sinfo->tx.pkts_d_rcpu_encap = 0; 7048 sinfo->tx.pkts_d_rcpu_sig = 0; 7049 sinfo->tx.pkts_d_rcpu_meta = 0; 7050 sinfo->tx.pkts_d_pad_fail = 0; 7051 sinfo->tx.pkts_d_over_limit = 0; 7052 sinfo->tx.pkts_d_dma_resrc = 0; 7053 sinfo->tx.suspends = 0; 7054 } 7055 /* Rx counters */ 7056 for (chan = 0; chan < sinfo->rx_chans; chan++) { 7057 if (clear_mask & (1 << chan)) { 7058 sinfo->rx[chan].pkts_f_api = 0; 7059 sinfo->rx[chan].pkts_f_netif = 0; 7060 sinfo->rx[chan].pkts_m_api = 0; 7061 sinfo->rx[chan].pkts_m_netif = 0; 7062 sinfo->rx[chan].pkts_d_no_skb = 0; 7063 sinfo->rx[chan].pkts_d_no_match = 0; 7064 sinfo->rx[chan].pkts_d_unkn_netif = 0; 7065 sinfo->rx[chan].pkts_d_unkn_dest = 0; 7066 sinfo->rx[chan].pkts_d_no_api_buf = 0; 7067 sinfo->rx[chan].sync_err = 0; 7068 sinfo->rx[chan].sync_retry = 0; 7069 sinfo->rx[chan].sync_maxloop = 0; 7070 } 7071 } 7072 7073 return count; 7074 } 7075 7076 struct file_operations bkn_proc_dstats_file_ops = { 7077 owner: THIS_MODULE, 7078 open: bkn_proc_dstats_open, 7079 read: seq_read, 7080 llseek: seq_lseek, 7081 write: bkn_proc_dstats_write, 7082 release: single_release, 7083 }; 7084 7085 static int 7086 bkn_proc_init(void) 7087 { 7088 struct proc_dir_entry *entry; 7089 7090 PROC_CREATE(entry, "link", 0666, bkn_proc_root, &bkn_proc_link_file_ops); 7091 if (entry == NULL) { 7092 return -1; 7093 } 7094 PROC_CREATE(entry, "rate", 0666, bkn_proc_root, &bkn_proc_rate_file_ops); 7095 if (entry == NULL) { 7096 return -1; 7097 } 7098 PROC_CREATE(entry, "dma", 0, bkn_proc_root, &bkn_seq_dma_file_ops); 7099 if (entry == NULL) { 7100 return -1; 7101 } 7102 PROC_CREATE(entry, "debug", 0666, bkn_proc_root, &bkn_proc_debug_file_ops); 7103 if (entry == NULL) { 7104 return -1; 7105 } 7106 PROC_CREATE(entry, "stats", 0666, bkn_proc_root, &bkn_proc_stats_file_ops); 7107 if (entry == NULL) { 7108 return -1; 7109 } 7110 PROC_CREATE(entry, "dstats", 0666, bkn_proc_root, &bkn_proc_dstats_file_ops); 7111 if (entry == NULL) { 7112 return -1; 7113 } 7114 7115 return 0; 7116 } 7117 7118 static int 7119 bkn_proc_cleanup(void) 7120 { 7121 remove_proc_entry("link", bkn_proc_root); 7122 remove_proc_entry("rate", bkn_proc_root); 7123 remove_proc_entry("dma", bkn_proc_root); 7124 remove_proc_entry("debug", bkn_proc_root); 7125 remove_proc_entry("stats", bkn_proc_root); 7126 remove_proc_entry("dstats", bkn_proc_root); 7127 return 0; 7128 } 7129 7130 /* 7131 * Generic module functions 7132 */ 7133 7134 static int 7135 _pprint(void) 7136 { 7137 pprintf("Broadcom BCM KNET Linux Network Driver\n"); 7138 7139 return 0; 7140 } 7141 7142 static int 7143 bkn_knet_dma_info(kcom_msg_dma_info_t *kmsg, int len) 7144 { 7145 bkn_switch_info_t *sinfo; 7146 bkn_dcb_chain_t *dcb_chain, *dcb_chain_end; 7147 unsigned long flags; 7148 int chan; 7149 uint64_t dcb_dma; 7150 int woffset; 7151 7152 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7153 7154 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 7155 if (sinfo == NULL) { 7156 kmsg->hdr.status = KCOM_E_PARAM; 7157 return sizeof(kcom_msg_hdr_t); 7158 } 7159 7160 dcb_chain = kmalloc(sizeof(*dcb_chain), GFP_KERNEL); 7161 if (dcb_chain == NULL) { 7162 gprintk("Fatal error: No memory for dcb_chain\n"); 7163 kmsg->hdr.status = KCOM_E_RESOURCE; 7164 return sizeof(kcom_msg_hdr_t); 7165 } 7166 memset(dcb_chain, 0, sizeof(*dcb_chain)); 7167 dcb_chain->dcb_cnt = kmsg->dma_info.cnt; 7168 dcb_chain->dcb_dma = kmsg->dma_info.data.dcb_start; 7169 dcb_chain->dcb_mem = kernel_bde->p2l(sinfo->dev_no, 7170 (sal_paddr_t)dcb_chain->dcb_dma); 7171 7172 if (kmsg->dma_info.type == KCOM_DMA_INFO_T_TX_DCB) { 7173 spin_lock_irqsave(&sinfo->lock, flags); 7174 7175 /* Hold back packets from kernel */ 7176 bkn_suspend_tx(sinfo); 7177 7178 list_add_tail(&dcb_chain->list, &sinfo->tx.api_dcb_list); 7179 7180 /* Handle for Continuous DMA mode */ 7181 if (CDMA_CH(sinfo, XGS_DMA_TX_CHAN)) { 7182 woffset = (dcb_chain->dcb_cnt - 1) * sinfo->dcb_wsize + 1; 7183 if (sinfo->cmic_type == 'x') { 7184 woffset += 1; 7185 } 7186 if ((dcb_chain->dcb_mem[woffset] & ((1 << 18) | (1 << 16))) != 0x50000) { 7187 gprintk("Not suitable API DCB chain for Continuous DMA mode\n"); 7188 list_del(&dcb_chain->list); 7189 kfree(dcb_chain); 7190 kmsg->hdr.status = KCOM_E_PARAM; 7191 spin_unlock_irqrestore(&sinfo->lock, flags); 7192 return sizeof(kcom_msg_hdr_t); 7193 } 7194 dcb_chain_end = sinfo->tx.api_dcb_chain_end; 7195 if (dcb_chain_end != NULL) { 7196 /* Stitch this chain */ 7197 woffset = (dcb_chain_end->dcb_cnt - 1) * sinfo->dcb_wsize; 7198 dcb_chain_end->dcb_mem[woffset] = dcb_chain->dcb_dma; 7199 if (sinfo->cmic_type == 'x') { 7200 dcb_chain_end->dcb_mem[woffset + 1] = DMA_TO_BUS_HI(dcb_chain->dcb_dma >> 32); 7201 } 7202 MEMORY_BARRIER; 7203 } 7204 sinfo->tx.api_dcb_chain_end = dcb_chain; 7205 if (sinfo->tx.api_active) { 7206 /* Set new halt location */ 7207 woffset = (dcb_chain->dcb_cnt - 1) * sinfo->dcb_wsize; 7208 dcb_dma = dcb_chain->dcb_dma + woffset * sizeof(uint32_t); 7209 /* DMA run to the new halt location */ 7210 bkn_cdma_goto(sinfo, XGS_DMA_TX_CHAN, dcb_dma); 7211 } 7212 } 7213 7214 if (sinfo->tx.free == MAX_TX_DCBS && 7215 !sinfo->tx.api_active && 7216 !sinfo->basedev_suspended) { 7217 bkn_api_tx(sinfo); 7218 } 7219 7220 spin_unlock_irqrestore(&sinfo->lock, flags); 7221 } else if (kmsg->dma_info.type == KCOM_DMA_INFO_T_RX_DCB) { 7222 spin_lock_irqsave(&sinfo->lock, flags); 7223 7224 chan = kmsg->dma_info.chan - 1; 7225 if ((chan < 0) || (chan > sinfo->rx_chans)) { 7226 gprintk("Invalid RX DMA channel specified: %d\n", 7227 kmsg->dma_info.chan); 7228 kmsg->hdr.status = KCOM_E_PARAM; 7229 spin_unlock_irqrestore(&sinfo->lock, flags); 7230 return sizeof(kcom_msg_hdr_t); 7231 } 7232 7233 list_add_tail(&dcb_chain->list, &sinfo->rx[chan].api_dcb_list); 7234 7235 /* Handle for Continuous DMA mode */ 7236 if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { 7237 woffset = (dcb_chain->dcb_cnt - 1) * sinfo->dcb_wsize + 1; 7238 if (sinfo->cmic_type == 'x') { 7239 woffset += 1; 7240 } 7241 if ((dcb_chain->dcb_mem[woffset] & ((1 << 18) | (1 << 16))) != 0x50000) { 7242 gprintk("Not suitable API DCB chain for Continuous DMA mode\n"); 7243 list_del(&dcb_chain->list); 7244 kfree(dcb_chain); 7245 kmsg->hdr.status = KCOM_E_PARAM; 7246 spin_unlock_irqrestore(&sinfo->lock, flags); 7247 return sizeof(kcom_msg_hdr_t); 7248 } 7249 dcb_chain_end = sinfo->rx[chan].api_dcb_chain_end; 7250 if (dcb_chain_end != NULL) { 7251 /* Stitch this chain */ 7252 woffset = (dcb_chain_end->dcb_cnt - 1) * sinfo->dcb_wsize; 7253 dcb_chain_end->dcb_mem[woffset] = dcb_chain->dcb_dma; 7254 if (sinfo->cmic_type == 'x') { 7255 dcb_chain_end->dcb_mem[woffset + 1] = DMA_TO_BUS_HI(dcb_chain->dcb_dma >> 32); 7256 } 7257 MEMORY_BARRIER; 7258 } 7259 sinfo->rx[chan].api_dcb_chain_end = dcb_chain; 7260 if (!sinfo->rx[chan].use_rx_skb) { 7261 /* Set new halt location */ 7262 woffset = (dcb_chain->dcb_cnt - 1) * sinfo->dcb_wsize; 7263 dcb_dma = dcb_chain->dcb_dma + woffset * sizeof(uint32_t); 7264 /* DMA run to the new halt location */ 7265 bkn_cdma_goto(sinfo, XGS_DMA_RX_CHAN + chan, dcb_dma); 7266 } 7267 } 7268 7269 if (sinfo->rx[chan].api_active == 0) { 7270 bkn_api_rx_restart(sinfo, chan); 7271 } 7272 7273 spin_unlock_irqrestore(&sinfo->lock, flags); 7274 } else { 7275 DBG_DCB(("Unknown DCB_INFO type (%d).\n", kmsg->dma_info.type)); 7276 kfree(dcb_chain); 7277 kmsg->hdr.status = KCOM_E_PARAM; 7278 } 7279 7280 return sizeof(kcom_msg_hdr_t); 7281 } 7282 7283 static int 7284 bkn_create_inst(uint32 inst_id) 7285 { 7286 bkn_switch_info_t *sinfo; 7287 bkn_evt_resource_t *evt; 7288 unsigned long flags; 7289 int i, evt_idx = -1; 7290 7291 /* multiple instance mode */ 7292 for (i = 0; i < kernel_bde->num_devices(BDE_ALL_DEVICES); i++) { 7293 evt = &_bkn_evt[i]; 7294 if (evt->inst_id == inst_id) { 7295 evt_idx = i; 7296 DBG_INST(("%s evt_idx %d inst_id 0x%x\n",__FUNCTION__, i, inst_id)); 7297 break; 7298 } 7299 if ((_bkn_multi_inst == 0) || (evt->inst_id == 0)) { 7300 _bkn_multi_inst ++; 7301 evt_idx = i; 7302 init_waitqueue_head(&evt->evt_wq); 7303 evt->inst_id = inst_id; 7304 DBG_INST(("%s evt_idx %d inst_id 0x%x\n",__FUNCTION__, i, inst_id)); 7305 break; 7306 } 7307 } 7308 7309 if (evt_idx == -1) { 7310 DBG_WARN(("Run out the event queue resource !\n")); 7311 return -1; 7312 } 7313 for (i = 0; i < kernel_bde->num_devices(BDE_ALL_DEVICES); i++) { 7314 if (inst_id & (1 << i)) { 7315 sinfo = bkn_sinfo_from_unit(i); 7316 spin_lock_irqsave(&sinfo->lock, flags); 7317 sinfo->evt_idx = evt_idx; 7318 spin_unlock_irqrestore(&sinfo->lock, flags); 7319 DBG_INST(("%s d(%d) evt_idx %d \n",__FUNCTION__, i, evt_idx)); 7320 } 7321 } 7322 return 0; 7323 } 7324 7325 /* 7326 * Device reprobe driven by application to check if new device is probed or 7327 * existed device is changed after inserting KNET module. 7328 */ 7329 static int 7330 bkn_knet_dev_reprobe(void) 7331 { 7332 bkn_switch_info_t *sinfo; 7333 int i; 7334 7335 for (i = 0; i < kernel_bde->num_devices(BDE_ALL_DEVICES); i++) { 7336 sinfo = bkn_sinfo_from_unit(i); 7337 if (sinfo == NULL) { 7338 /* New device found after re-probe. */ 7339 if (bkn_knet_dev_init(i) < 0) { 7340 return -1; 7341 } 7342 } else { 7343 /* Existed device reinit after re-probe. */ 7344 if (bkn_knet_dev_reinit(i) < 0) { 7345 return -1; 7346 } 7347 } 7348 } 7349 return 0; 7350 } 7351 7352 /* Assign the inst_id and evt_idx */ 7353 static int 7354 bkn_knet_dev_inst_set(kcom_msg_reprobe_t *kmsg) 7355 { 7356 bkn_switch_info_t *sinfo; 7357 int d = kmsg->hdr.unit; 7358 uint32 inst = 0; 7359 unsigned long flags; 7360 struct list_head *list; 7361 7362 sinfo = bkn_sinfo_from_unit(d); 7363 lkbde_dev_instid_get(d, &inst); 7364 7365 spin_lock_irqsave(&sinfo->lock, flags); 7366 if (sinfo->inst_id != inst) { 7367 /* Instance database changed, reinit the inst_id */ 7368 sinfo->inst_id = 0; 7369 sinfo->evt_idx = -1; 7370 } 7371 spin_unlock_irqrestore(&sinfo->lock, flags); 7372 7373 if (inst) { 7374 if (sinfo->inst_id == 0) { 7375 if (bkn_create_inst(inst) != 0) { 7376 return -1; 7377 } 7378 } 7379 spin_lock_irqsave(&sinfo->lock, flags); 7380 sinfo->inst_id = inst; 7381 spin_unlock_irqrestore(&sinfo->lock, flags); 7382 } else { 7383 /* legacy mode */ 7384 list_for_each(list, &_sinfo_list) { 7385 sinfo = (bkn_switch_info_t *)list; 7386 spin_lock_irqsave(&sinfo->lock, flags); 7387 sinfo->evt_idx = 0; 7388 sinfo->inst_id = 0; 7389 spin_unlock_irqrestore(&sinfo->lock, flags); 7390 } 7391 } 7392 return 0; 7393 } 7394 7395 static int 7396 bkn_knet_version(kcom_msg_version_t *kmsg, int len) 7397 { 7398 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7399 kmsg->version = KCOM_VERSION; 7400 kmsg->netif_max = KCOM_NETIF_MAX; 7401 kmsg->filter_max = KCOM_FILTER_MAX; 7402 7403 return sizeof(kcom_msg_version_t); 7404 } 7405 7406 static int 7407 bkn_knet_hw_reset(kcom_msg_hw_reset_t *kmsg, int len) 7408 { 7409 bkn_switch_info_t *sinfo; 7410 unsigned long flags; 7411 int chan; 7412 7413 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7414 7415 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 7416 if (sinfo == NULL) { 7417 kmsg->hdr.status = KCOM_E_PARAM; 7418 return sizeof(kcom_msg_hdr_t); 7419 } 7420 7421 spin_lock_irqsave(&sinfo->lock, flags); 7422 7423 if (kmsg->channels == 0) { 7424 /* Clean all if no channels specified */ 7425 bkn_dma_abort(sinfo); 7426 bkn_clean_dcbs(sinfo); 7427 skb_queue_purge(&sinfo->tx_ptp_queue); 7428 } else { 7429 if (kmsg->channels & (1 << XGS_DMA_TX_CHAN)) { 7430 bkn_dma_abort_tx(sinfo); 7431 bkn_clean_tx_dcbs(sinfo); 7432 skb_queue_purge(&sinfo->tx_ptp_queue); 7433 } 7434 for (chan = 0; chan < sinfo->rx_chans; chan++) { 7435 if (kmsg->channels & (1 << (XGS_DMA_RX_CHAN + chan))) { 7436 bkn_dma_abort_rx(sinfo, chan); 7437 bkn_clean_rx_dcbs(sinfo, chan); 7438 } 7439 } 7440 } 7441 7442 spin_unlock_irqrestore(&sinfo->lock, flags); 7443 7444 return sizeof(kcom_msg_hdr_t); 7445 } 7446 7447 static int 7448 bkn_knet_hw_init(kcom_msg_hw_init_t *kmsg, int len) 7449 { 7450 bkn_switch_info_t *sinfo; 7451 uint32_t dev_type; 7452 unsigned long flags; 7453 7454 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7455 7456 DBG_DCB(("DCB size %d, type %d\n", kmsg->dcb_size, kmsg->dcb_type)); 7457 7458 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 7459 if (sinfo == NULL) { 7460 kmsg->hdr.status = KCOM_E_PARAM; 7461 return sizeof(kcom_msg_hdr_t); 7462 } 7463 7464 spin_lock_irqsave(&sinfo->lock, flags); 7465 7466 sinfo->cmic_type = kmsg->cmic_type; 7467 sinfo->dcb_type = kmsg->dcb_type; 7468 sinfo->dcb_wsize = BYTES2WORDS(kmsg->dcb_size); 7469 sinfo->pkt_hdr_size = kmsg->pkt_hdr_size; 7470 sinfo->dma_hi = kmsg->dma_hi; 7471 sinfo->rx_chans = sinfo->cmic_type == 'x' ? NUM_CMICX_RX_CHAN : NUM_CMICM_RX_CHAN; 7472 if (sinfo->rx_chans > NUM_RX_CHAN) { 7473 sinfo->rx_chans = NUM_RX_CHAN; 7474 } 7475 7476 DBG_DUNE(("CMIC:%c DCB:%d WSIZE:%d DMA HI: 0x%08x HDR size: %d\n", 7477 sinfo->cmic_type, sinfo->dcb_type, sinfo->dcb_wsize, 7478 sinfo->dma_hi, sinfo->pkt_hdr_size)); 7479 7480 /* Config Continuous DMA mode */ 7481 sinfo->cdma_channels = kmsg->cdma_channels & ~(~0 << (sinfo->rx_chans + 1)); 7482 7483 /* Ensure 32-bit PCI DMA is mapped properly on 64-bit platforms */ 7484 dev_type = kernel_bde->get_dev_type(sinfo->dev_no); 7485 if (dev_type & BDE_PCI_DEV_TYPE && sinfo->cmic_type != 'x') { 7486 if (pci_set_dma_mask(sinfo->pdev, 0xffffffff)) { 7487 spin_unlock_irqrestore(&sinfo->lock, flags); 7488 gprintk("No suitable DMA available for SKBs\n"); 7489 kmsg->hdr.status = KCOM_E_RESOURCE; 7490 return sizeof(kcom_msg_hdr_t); 7491 } 7492 } 7493 7494 /* First time called we need to allocate DCBs */ 7495 if (sinfo->dcb_mem == NULL) { 7496 if (bkn_alloc_dcbs(sinfo) < 0) { 7497 spin_unlock_irqrestore(&sinfo->lock, flags); 7498 kmsg->hdr.status = KCOM_E_RESOURCE; 7499 return sizeof(kcom_msg_hdr_t); 7500 } 7501 } 7502 7503 /* Ensure that we restart properly */ 7504 bkn_dma_abort(sinfo); 7505 bkn_clean_dcbs(sinfo); 7506 7507 if (basedev_suspend) { 7508 if (!netif_running(sinfo->dev)) { 7509 sinfo->basedev_suspended = 1; 7510 } 7511 } 7512 7513 /* Ensure all interrupts are disabled, e.g. if warmbooting */ 7514 dev_irq_mask_set(sinfo, 0); 7515 7516 /* Register interrupt handler */ 7517 kernel_bde->interrupt_connect(sinfo->dev_no | LKBDE_ISR2_DEV, 7518 bkn_isr, sinfo); 7519 7520 /* Init DCBs */ 7521 bkn_init_dcbs(sinfo); 7522 7523 bkn_dma_init(sinfo); 7524 7525 spin_unlock_irqrestore(&sinfo->lock, flags); 7526 7527 return sizeof(kcom_msg_hdr_t); 7528 } 7529 7530 static int 7531 bkn_knet_detach(kcom_msg_detach_t *kmsg, int len) 7532 { 7533 bkn_switch_info_t *sinfo; 7534 unsigned long flags; 7535 bkn_evt_resource_t *evt; 7536 7537 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7538 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 7539 if (sinfo == NULL) { 7540 kmsg->hdr.status = KCOM_E_PARAM; 7541 return sizeof(kcom_msg_hdr_t); 7542 } 7543 7544 spin_lock_irqsave(&sinfo->lock, flags); 7545 7546 /* Create dummy event to unblock pending IOCTL */ 7547 sinfo->dma_events |= KCOM_DMA_INFO_F_TX_DONE; 7548 evt = &_bkn_evt[sinfo->evt_idx]; 7549 evt->evt_wq_put++; 7550 wake_up_interruptible(&evt->evt_wq); 7551 7552 spin_unlock_irqrestore(&sinfo->lock, flags); 7553 7554 /* Ensure that we return a valid unit number */ 7555 kmsg->hdr.unit = sinfo->dev_no; 7556 7557 return sizeof(kcom_msg_detach_t); 7558 } 7559 7560 static int 7561 bkn_knet_reprobe(kcom_msg_reprobe_t *kmsg, int len) 7562 { 7563 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7564 7565 /* Support pci hot plug and multiple instance */ 7566 if ((bkn_knet_dev_reprobe() < 0) || 7567 (bkn_knet_dev_inst_set(kmsg) < 0)) { 7568 kmsg->hdr.status = KCOM_E_RESOURCE; 7569 return sizeof(kcom_msg_reprobe_t); 7570 } 7571 7572 return sizeof(kcom_msg_reprobe_t); 7573 } 7574 7575 static int 7576 bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) 7577 { 7578 bkn_switch_info_t *sinfo; 7579 struct net_device *dev; 7580 struct list_head *list; 7581 bkn_priv_t *priv, *lpriv; 7582 unsigned long flags; 7583 int found, id; 7584 uint8 *ma; 7585 7586 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7587 7588 switch (kmsg->netif.type) { 7589 case KCOM_NETIF_T_VLAN: 7590 case KCOM_NETIF_T_PORT: 7591 case KCOM_NETIF_T_META: 7592 break; 7593 default: 7594 kmsg->hdr.status = KCOM_E_PARAM; 7595 return sizeof(kcom_msg_hdr_t); 7596 } 7597 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 7598 if (sinfo == NULL) { 7599 kmsg->hdr.status = KCOM_E_PARAM; 7600 return sizeof(kcom_msg_hdr_t); 7601 } 7602 ma = kmsg->netif.macaddr; 7603 if ((ma[0] | ma[1] | ma[2] | ma[3] | ma[4] | ma[5]) == 0) { 7604 bkn_dev_mac[5]++; 7605 ma = bkn_dev_mac; 7606 } 7607 if ((dev = bkn_init_ndev(ma, kmsg->netif.name)) == NULL) { 7608 kmsg->hdr.status = KCOM_E_RESOURCE; 7609 return sizeof(kcom_msg_hdr_t); 7610 } 7611 priv = netdev_priv(dev); 7612 priv->dev = dev; 7613 priv->sinfo = sinfo; 7614 priv->type = kmsg->netif.type; 7615 priv->vlan = kmsg->netif.vlan; 7616 if (priv->type == KCOM_NETIF_T_PORT) { 7617 priv->port = kmsg->netif.port; 7618 if (device_is_dpp(sinfo)) { 7619 memcpy(priv->itmh, kmsg->netif.itmh, 4); 7620 } else if (device_is_dnx(sinfo)) { 7621 memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); 7622 priv->system_headers_size = kmsg->netif.system_headers_size; 7623 } 7624 priv->qnum = kmsg->netif.qnum; 7625 } else { 7626 if (device_is_sand(sinfo)) { 7627 if (device_is_dpp(sinfo)) { 7628 priv->port = kmsg->netif.port; 7629 priv->qnum = kmsg->netif.qnum; 7630 }else if (device_is_dnx(sinfo)) { 7631 memcpy(priv->system_headers, kmsg->netif.system_headers, kmsg->netif.system_headers_size); 7632 priv->system_headers_size = kmsg->netif.system_headers_size; 7633 } 7634 } 7635 else { 7636 priv->port = -1; 7637 } 7638 } 7639 priv->flags = kmsg->netif.flags; 7640 priv->cb_user_data = kmsg->netif.cb_user_data; 7641 7642 /* Force RCPU encapsulation if rcpu_mode */ 7643 if (rcpu_mode) { 7644 priv->flags |= KCOM_NETIF_F_RCPU_ENCAP; 7645 DBG_RCPU(("RCPU auto-enabled\n")); 7646 } 7647 7648 /* Prevent (incorrect) compiler warning */ 7649 lpriv = NULL; 7650 7651 spin_lock_irqsave(&sinfo->lock, flags); 7652 7653 /* 7654 * We insert network interfaces sorted by ID. 7655 * In case an interface is destroyed, we reuse the ID 7656 * the next time an interface is created. 7657 */ 7658 found = 0; 7659 id = 1; 7660 list_for_each(list, &sinfo->ndev_list) { 7661 lpriv = (bkn_priv_t *)list; 7662 if (id < lpriv->id) { 7663 found = 1; 7664 break; 7665 } 7666 id = lpriv->id + 1; 7667 } 7668 priv->id = id; 7669 if (found) { 7670 /* Replace previously removed interface */ 7671 list_add_tail(&priv->list, &lpriv->list); 7672 } else { 7673 /* No holes - add to end of list */ 7674 list_add_tail(&priv->list, &sinfo->ndev_list); 7675 } 7676 7677 if (id < sinfo->ndev_max) { 7678 DBG_NDEV(("Add netif ID %d to table\n", id)); 7679 sinfo->ndevs[id] = dev; 7680 } else { 7681 int ndev_max = sinfo->ndev_max + NDEVS_CHUNK; 7682 int size = ndev_max * sizeof(struct net_device *); 7683 void *ndevs = kmalloc(size, GFP_ATOMIC); 7684 if (ndevs != NULL) { 7685 DBG_NDEV(("Reallocate netif table for ID %d\n", id)); 7686 memset(ndevs, 0, size); 7687 if (sinfo->ndevs != NULL) { 7688 size = sinfo->ndev_max * sizeof(struct net_device *); 7689 memcpy(ndevs, sinfo->ndevs, size); 7690 kfree(sinfo->ndevs); 7691 } 7692 sinfo->ndevs = ndevs; 7693 sinfo->ndev_max = ndev_max; 7694 sinfo->ndevs[id] = dev; 7695 } 7696 } 7697 7698 spin_unlock_irqrestore(&sinfo->lock, flags); 7699 7700 DBG_VERB(("Assigned ID %d to Ethernet device %s\n", 7701 priv->id, dev->name)); 7702 7703 kmsg->netif.id = priv->id; 7704 memcpy(kmsg->netif.macaddr, dev->dev_addr, 6); 7705 memcpy(kmsg->netif.name, dev->name, KCOM_NETIF_NAME_MAX - 1); 7706 7707 if (device_is_dnx(sinfo)) { 7708 int idx = 0; 7709 for (idx = 0; idx < priv->system_headers_size; idx++) { 7710 DBG_DUNE(("System Header[%d]: 0x%02x\n", idx, priv->system_headers[idx])); 7711 } 7712 } 7713 7714 return sizeof(*kmsg); 7715 } 7716 7717 static int 7718 bkn_knet_netif_destroy(kcom_msg_netif_destroy_t *kmsg, int len) 7719 { 7720 bkn_switch_info_t *sinfo; 7721 struct net_device *dev; 7722 bkn_priv_t *priv; 7723 struct list_head *list; 7724 unsigned long flags; 7725 int found; 7726 7727 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7728 7729 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 7730 if (sinfo == NULL) { 7731 kmsg->hdr.status = KCOM_E_PARAM; 7732 return sizeof(kcom_msg_hdr_t); 7733 } 7734 7735 spin_lock_irqsave(&sinfo->lock, flags); 7736 7737 found = 0; 7738 list_for_each(list, &sinfo->ndev_list) { 7739 priv = (bkn_priv_t *)list; 7740 if (kmsg->hdr.id == priv->id) { 7741 found = 1; 7742 break; 7743 } 7744 } 7745 7746 if (!found) { 7747 spin_unlock_irqrestore(&sinfo->lock, flags); 7748 kmsg->hdr.status = KCOM_E_NOT_FOUND; 7749 return sizeof(kcom_msg_hdr_t); 7750 } 7751 7752 list_del(&priv->list); 7753 7754 if (priv->id < sinfo->ndev_max) { 7755 sinfo->ndevs[priv->id] = NULL; 7756 } 7757 7758 spin_unlock_irqrestore(&sinfo->lock, flags); 7759 7760 dev = priv->dev; 7761 DBG_VERB(("Removing virtual Ethernet device %s (%d).\n", 7762 dev->name, priv->id)); 7763 unregister_netdev(dev); 7764 free_netdev(dev); 7765 7766 return sizeof(kcom_msg_hdr_t); 7767 } 7768 7769 static int 7770 bkn_knet_netif_list(kcom_msg_netif_list_t *kmsg, int len) 7771 { 7772 bkn_switch_info_t *sinfo; 7773 bkn_priv_t *priv; 7774 struct list_head *list; 7775 unsigned long flags; 7776 int idx; 7777 7778 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7779 7780 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 7781 if (sinfo == NULL) { 7782 kmsg->hdr.status = KCOM_E_PARAM; 7783 return sizeof(kcom_msg_hdr_t); 7784 } 7785 7786 spin_lock_irqsave(&sinfo->lock, flags); 7787 7788 idx = 0; 7789 list_for_each(list, &sinfo->ndev_list) { 7790 if (idx >= KCOM_NETIF_MAX) { 7791 DBG_WARN(("Too many network interfaces to list (max %d).\n", 7792 KCOM_NETIF_MAX)); 7793 break; 7794 } 7795 priv = (bkn_priv_t *)list; 7796 kmsg->id[idx] = priv->id; 7797 idx++; 7798 } 7799 kmsg->ifcnt = idx; 7800 7801 spin_unlock_irqrestore(&sinfo->lock, flags); 7802 7803 return sizeof(*kmsg) - sizeof(kmsg->id) + (idx * sizeof(kmsg->id[0])); 7804 } 7805 7806 static int 7807 bkn_knet_netif_get(kcom_msg_netif_get_t *kmsg, int len) 7808 { 7809 bkn_switch_info_t *sinfo; 7810 bkn_priv_t *priv; 7811 unsigned long flags; 7812 7813 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7814 7815 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 7816 if (sinfo == NULL) { 7817 kmsg->hdr.status = KCOM_E_PARAM; 7818 return sizeof(kcom_msg_hdr_t); 7819 } 7820 7821 spin_lock_irqsave(&sinfo->lock, flags); 7822 7823 priv = bkn_netif_lookup(sinfo, kmsg->hdr.id); 7824 7825 if (priv == NULL) { 7826 spin_unlock_irqrestore(&sinfo->lock, flags); 7827 kmsg->hdr.status = KCOM_E_NOT_FOUND; 7828 return sizeof(kcom_msg_hdr_t); 7829 } 7830 7831 memcpy(kmsg->netif.macaddr, priv->dev->dev_addr, 6); 7832 memcpy(kmsg->netif.name, priv->dev->name, KCOM_NETIF_NAME_MAX - 1); 7833 kmsg->netif.vlan = priv->vlan; 7834 kmsg->netif.type = priv->type; 7835 kmsg->netif.id = priv->id; 7836 kmsg->netif.flags = priv->flags; 7837 7838 if (priv->port < 0) { 7839 kmsg->netif.port = 0; 7840 } else { 7841 kmsg->netif.port = priv->port; 7842 } 7843 kmsg->netif.qnum = priv->qnum; 7844 7845 spin_unlock_irqrestore(&sinfo->lock, flags); 7846 7847 return sizeof(*kmsg); 7848 } 7849 7850 static int 7851 bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) 7852 { 7853 bkn_switch_info_t *sinfo; 7854 struct list_head *list; 7855 bkn_filter_t *filter, *lfilter; 7856 unsigned long flags; 7857 int found, id; 7858 7859 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7860 7861 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 7862 if (sinfo == NULL) { 7863 kmsg->hdr.status = KCOM_E_PARAM; 7864 return sizeof(kcom_msg_hdr_t); 7865 } 7866 7867 switch (kmsg->filter.type) { 7868 case KCOM_FILTER_T_RX_PKT: 7869 break; 7870 default: 7871 kmsg->hdr.status = KCOM_E_PARAM; 7872 return sizeof(kcom_msg_hdr_t); 7873 } 7874 7875 spin_lock_irqsave(&sinfo->lock, flags); 7876 7877 /* 7878 * Find available ID 7879 */ 7880 found = 1; 7881 id = 0; 7882 while (found && ++id < KCOM_FILTER_MAX) { 7883 found = 0; 7884 list_for_each(list, &sinfo->rxpf_list) { 7885 lfilter = (bkn_filter_t *)list; 7886 if (id == lfilter->kf.id) { 7887 found = 1; 7888 break; 7889 } 7890 } 7891 } 7892 if (found) { 7893 /* Too many filters */ 7894 spin_unlock_irqrestore(&sinfo->lock, flags); 7895 kmsg->hdr.status = KCOM_E_RESOURCE; 7896 return sizeof(kcom_msg_hdr_t); 7897 } 7898 7899 filter = kmalloc(sizeof(*filter), GFP_ATOMIC); 7900 if (filter == NULL) { 7901 spin_unlock_irqrestore(&sinfo->lock, flags); 7902 kmsg->hdr.status = KCOM_E_PARAM; 7903 return sizeof(kcom_msg_hdr_t); 7904 } 7905 memset(filter, 0, sizeof(*filter)); 7906 memcpy(&filter->kf, &kmsg->filter, sizeof(filter->kf)); 7907 7908 if (device_is_dnx(sinfo)) { 7909 /* Information to parser Dune system headers */ 7910 sinfo->ftmh_lb_key_ext_size = kmsg->filter.ftmh_lb_key_ext_size; 7911 sinfo->ftmh_stacking_ext_size = kmsg->filter.ftmh_stacking_ext_size; 7912 sinfo->pph_base_size = kmsg->filter.pph_base_size; 7913 memcpy(sinfo->pph_lif_ext_size, kmsg->filter.pph_lif_ext_size, sizeof(sinfo->pph_lif_ext_size)); 7914 sinfo->udh_enable = kmsg->filter.udh_enable; 7915 memcpy(sinfo->udh_length_type, kmsg->filter.udh_length_type, sizeof(sinfo->udh_length_type)); 7916 } 7917 7918 filter->kf.id = id; 7919 7920 /* Add according to priority */ 7921 found = 0; 7922 list_for_each(list, &sinfo->rxpf_list) { 7923 lfilter = (bkn_filter_t *)list; 7924 if (filter->kf.priority < lfilter->kf.priority) { 7925 list_add_tail(&filter->list, &lfilter->list); 7926 found = 1; 7927 break; 7928 } 7929 } 7930 if (!found) { 7931 list_add_tail(&filter->list, &sinfo->rxpf_list); 7932 } 7933 7934 kmsg->filter.id = filter->kf.id; 7935 7936 spin_unlock_irqrestore(&sinfo->lock, flags); 7937 7938 DBG_VERB(("Created filter ID %d (%s).\n", 7939 filter->kf.id, filter->kf.desc)); 7940 7941 if (device_is_dnx(sinfo)) { 7942 int idx, wsize; 7943 wsize = BYTES2WORDS(filter->kf.oob_data_size + filter->kf.pkt_data_size); 7944 DBG_DUNE(("Filter: oob_data_size = %d pkt_data_size=%d wsize %d\n", filter->kf.oob_data_size, filter->kf.pkt_data_size, wsize)); 7945 for (idx = 0; idx < wsize; idx++) 7946 { 7947 DBG_DUNE(("OOB[%d]: 0x%08x [0x%08x]\n", idx, filter->kf.data.w[idx], filter->kf.mask.w[idx])); 7948 } 7949 DBG_DUNE(("DNX system headers parameters:LB_KEY_EXT %d, STK_EXT %d, PPH_BASE %d, LIF_EXT %d %d %d, UDH_ENA %d, %d %d %d %d\n", 7950 sinfo->ftmh_lb_key_ext_size, sinfo->ftmh_stacking_ext_size, sinfo->pph_base_size, 7951 sinfo->pph_lif_ext_size[1],sinfo->pph_lif_ext_size[2], sinfo->pph_lif_ext_size[3], 7952 sinfo->udh_enable, sinfo->udh_length_type[0], sinfo->udh_length_type[1], sinfo->udh_length_type[2], sinfo->udh_length_type[3])); 7953 } 7954 7955 return len; 7956 } 7957 7958 static int 7959 bkn_knet_filter_destroy(kcom_msg_filter_destroy_t *kmsg, int len) 7960 { 7961 bkn_switch_info_t *sinfo; 7962 bkn_filter_t *filter; 7963 struct list_head *list; 7964 unsigned long flags; 7965 int found; 7966 7967 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 7968 7969 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 7970 if (sinfo == NULL) { 7971 kmsg->hdr.status = KCOM_E_PARAM; 7972 return sizeof(kcom_msg_hdr_t); 7973 } 7974 7975 spin_lock_irqsave(&sinfo->lock, flags); 7976 7977 found = 0; 7978 list_for_each(list, &sinfo->rxpf_list) { 7979 filter = (bkn_filter_t *)list; 7980 if (kmsg->hdr.id == filter->kf.id) { 7981 found = 1; 7982 break; 7983 } 7984 } 7985 7986 if (!found) { 7987 spin_unlock_irqrestore(&sinfo->lock, flags); 7988 kmsg->hdr.status = KCOM_E_NOT_FOUND; 7989 return sizeof(kcom_msg_hdr_t); 7990 } 7991 7992 list_del(&filter->list); 7993 7994 spin_unlock_irqrestore(&sinfo->lock, flags); 7995 7996 DBG_VERB(("Removing filter ID %d.\n", filter->kf.id)); 7997 kfree(filter); 7998 7999 return sizeof(kcom_msg_hdr_t); 8000 } 8001 8002 static int 8003 bkn_knet_filter_list(kcom_msg_filter_list_t *kmsg, int len) 8004 { 8005 bkn_switch_info_t *sinfo; 8006 bkn_filter_t *filter; 8007 struct list_head *list; 8008 unsigned long flags; 8009 int idx; 8010 8011 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 8012 8013 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 8014 if (sinfo == NULL) { 8015 kmsg->hdr.status = KCOM_E_PARAM; 8016 return sizeof(kcom_msg_hdr_t); 8017 } 8018 8019 spin_lock_irqsave(&sinfo->lock, flags); 8020 8021 idx = 0; 8022 list_for_each(list, &sinfo->rxpf_list) { 8023 if (idx >= KCOM_FILTER_MAX) { 8024 DBG_WARN(("Too many filters to list (max %d).\n", 8025 KCOM_FILTER_MAX)); 8026 break; 8027 } 8028 filter = (bkn_filter_t *)list; 8029 kmsg->id[idx] = filter->kf.id; 8030 idx++; 8031 } 8032 kmsg->fcnt = idx; 8033 8034 spin_unlock_irqrestore(&sinfo->lock, flags); 8035 8036 return sizeof(*kmsg) - sizeof(kmsg->id) + (idx * sizeof(kmsg->id[0])); 8037 } 8038 8039 static int 8040 bkn_knet_filter_get(kcom_msg_filter_get_t *kmsg, int len) 8041 { 8042 bkn_switch_info_t *sinfo; 8043 bkn_filter_t *filter; 8044 struct list_head *list; 8045 unsigned long flags; 8046 int found; 8047 8048 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 8049 8050 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 8051 if (sinfo == NULL) { 8052 kmsg->hdr.status = KCOM_E_PARAM; 8053 return sizeof(kcom_msg_hdr_t); 8054 } 8055 8056 spin_lock_irqsave(&sinfo->lock, flags); 8057 8058 found = 0; 8059 list_for_each(list, &sinfo->rxpf_list) { 8060 filter = (bkn_filter_t *)list; 8061 if (kmsg->hdr.id == filter->kf.id) { 8062 found = 1; 8063 break; 8064 } 8065 } 8066 8067 if (!found) { 8068 spin_unlock_irqrestore(&sinfo->lock, flags); 8069 kmsg->hdr.status = KCOM_E_NOT_FOUND; 8070 return sizeof(kcom_msg_hdr_t); 8071 } 8072 8073 memcpy(&kmsg->filter, &filter->kf, sizeof(kmsg->filter)); 8074 8075 spin_unlock_irqrestore(&sinfo->lock, flags); 8076 8077 return sizeof(*kmsg); 8078 } 8079 8080 static int 8081 bkn_knet_dbg_pkt_set(kcom_msg_dbg_pkt_set_t *kmsg, int len) 8082 { 8083 dbg_pkt_enable = kmsg->enable; 8084 return sizeof(kcom_msg_dbg_pkt_set_t); 8085 } 8086 8087 static int 8088 bkn_knet_dbg_pkt_get(kcom_msg_dbg_pkt_get_t *kmsg, int len) 8089 { 8090 kmsg->value = dbg_pkt_enable; 8091 return sizeof(kcom_msg_dbg_pkt_get_t); 8092 } 8093 8094 static int 8095 bkn_knet_wb_cleanup(kcom_msg_wb_cleanup_t *kmsg, int len) 8096 { 8097 bkn_switch_info_t *sinfo; 8098 bkn_dcb_chain_t *dcb_chain; 8099 unsigned long flags; 8100 int chan; 8101 8102 kmsg->hdr.type = KCOM_MSG_TYPE_RSP; 8103 8104 sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); 8105 if (sinfo == NULL) { 8106 kmsg->hdr.status = KCOM_E_PARAM; 8107 return sizeof(kcom_msg_hdr_t); 8108 } 8109 8110 spin_lock_irqsave(&sinfo->lock, flags); 8111 8112 for (chan = 0; chan < sinfo->rx_chans; chan++) { 8113 if (sinfo->rx[chan].api_dcb_chain) { 8114 DBG_DCB_RX(("Freeing active Rx%d DCB chain.\n", chan)); 8115 kfree(sinfo->rx[chan].api_dcb_chain); 8116 sinfo->rx[chan].api_dcb_chain = NULL; 8117 } 8118 while (!list_empty(&sinfo->rx[chan].api_dcb_list)) { 8119 dcb_chain = list_entry(sinfo->rx[chan].api_dcb_list.next, 8120 bkn_dcb_chain_t, list); 8121 list_del(&dcb_chain->list); 8122 DBG_DCB_RX(("Freeing Rx%d DCB chain.\n", chan)); 8123 kfree(dcb_chain); 8124 } 8125 sinfo->rx[chan].api_dcb_chain_end = NULL; 8126 sinfo->rx[chan].api_active = 0; 8127 } 8128 8129 spin_unlock_irqrestore(&sinfo->lock, flags); 8130 8131 return sizeof(kcom_msg_hdr_t); 8132 } 8133 8134 static int 8135 bkn_handle_cmd_req(kcom_msg_t *kmsg, int len) 8136 { 8137 /* Silently drop events and unrecognized message types */ 8138 if (kmsg->hdr.type != KCOM_MSG_TYPE_CMD) { 8139 if (kmsg->hdr.opcode == KCOM_M_STRING) { 8140 DBG_VERB(("Debug string: '%s'\n", kmsg->string.val)); 8141 return 0; 8142 } 8143 DBG_WARN(("Unsupported message (type=%d, opcode=%d)\n", 8144 kmsg->hdr.type, kmsg->hdr.opcode)); 8145 return 0; 8146 } 8147 8148 switch (kmsg->hdr.opcode) { 8149 case KCOM_M_DMA_INFO: 8150 DBG_CMD(("KCOM_M_DMA_INFO\n")); 8151 /* Packet buffer */ 8152 len = bkn_knet_dma_info(&kmsg->dma_info, len); 8153 break; 8154 case KCOM_M_VERSION: 8155 DBG_CMD(("KCOM_M_VERSION\n")); 8156 /* Return procotol version */ 8157 len = bkn_knet_version(&kmsg->version, len); 8158 break; 8159 case KCOM_M_HW_RESET: 8160 DBG_CMD(("KCOM_M_HW_RESET\n")); 8161 /* Shut down DMA and release buffers */ 8162 len = bkn_knet_hw_reset(&kmsg->hw_reset, len); 8163 break; 8164 case KCOM_M_HW_INIT: 8165 DBG_CMD(("KCOM_M_HW_INIT\n")); 8166 /* Initialize DMA */ 8167 len = bkn_knet_hw_init(&kmsg->hw_init, len); 8168 break; 8169 case KCOM_M_DETACH: 8170 DBG_CMD(("KCOM_M_DETACH\n")); 8171 /* Detach kernel module */ 8172 len = bkn_knet_detach(&kmsg->detach, len); 8173 break; 8174 case KCOM_M_REPROBE: 8175 DBG_CMD(("KCOM_M_REPROBE\n")); 8176 /* Reprobe device */ 8177 len = bkn_knet_reprobe(&kmsg->reprobe, len); 8178 break; 8179 case KCOM_M_NETIF_CREATE: 8180 DBG_CMD(("KCOM_M_NETIF_CREATE\n")); 8181 /* Create network interface */ 8182 len = bkn_knet_netif_create(&kmsg->netif_create, len); 8183 break; 8184 case KCOM_M_NETIF_DESTROY: 8185 DBG_CMD(("KCOM_M_NETIF_DESTROY\n")); 8186 /* Destroy network interface */ 8187 len = bkn_knet_netif_destroy(&kmsg->netif_destroy, len); 8188 break; 8189 case KCOM_M_NETIF_LIST: 8190 DBG_CMD(("KCOM_M_NETIF_LIST\n")); 8191 /* Return list of IDs of installed network interfaces */ 8192 len = bkn_knet_netif_list(&kmsg->netif_list, len); 8193 break; 8194 case KCOM_M_NETIF_GET: 8195 DBG_CMD(("KCOM_M_NETIF_GET\n")); 8196 /* Return network interface info */ 8197 len = bkn_knet_netif_get(&kmsg->netif_get, len); 8198 break; 8199 case KCOM_M_FILTER_CREATE: 8200 DBG_CMD(("KCOM_M_FILTER_CREATE\n")); 8201 /* Create packet filter */ 8202 len = bkn_knet_filter_create(&kmsg->filter_create, len); 8203 break; 8204 case KCOM_M_FILTER_DESTROY: 8205 DBG_CMD(("KCOM_M_FILTER_DESTROY\n")); 8206 /* Destroy packet filter */ 8207 len = bkn_knet_filter_destroy(&kmsg->filter_destroy, len); 8208 break; 8209 case KCOM_M_FILTER_LIST: 8210 DBG_CMD(("KCOM_M_FILTER_LIST\n")); 8211 /* Return list of IDs of installed packet filters */ 8212 len = bkn_knet_filter_list(&kmsg->filter_list, len); 8213 break; 8214 case KCOM_M_FILTER_GET: 8215 DBG_CMD(("KCOM_M_FILTER_GET\n")); 8216 /* Return packet filter info */ 8217 len = bkn_knet_filter_get(&kmsg->filter_get, len); 8218 break; 8219 case KCOM_M_DBGPKT_SET: 8220 DBG_CMD(("KCOM_M_DBGPKT_SET\n")); 8221 /* Set debugging packet function */ 8222 len = bkn_knet_dbg_pkt_set(&kmsg->dbg_pkt_set, len); 8223 break; 8224 case KCOM_M_DBGPKT_GET: 8225 DBG_CMD(("KCOM_M_DBGPKT_GET\n")); 8226 /* Get debugging packet function info */ 8227 len = bkn_knet_dbg_pkt_get(&kmsg->dbg_pkt_get, len); 8228 break; 8229 case KCOM_M_WB_CLEANUP: 8230 DBG_CMD(("KCOM_M_WB_CLEANUP\n")); 8231 /* Clean up for warmbooting */ 8232 len = bkn_knet_wb_cleanup(&kmsg->wb_cleanup, len); 8233 break; 8234 default: 8235 DBG_WARN(("Unsupported command (type=%d, opcode=%d)\n", 8236 kmsg->hdr.type, kmsg->hdr.opcode)); 8237 kmsg->hdr.opcode = 0; 8238 len = sizeof(kcom_msg_hdr_t); 8239 break; 8240 } 8241 return len; 8242 } 8243 8244 static int 8245 bkn_cmd_thread(void *context) 8246 { 8247 bkn_thread_ctrl_t *tc = (bkn_thread_ctrl_t *)context; 8248 kcom_msg_t kmsg; 8249 unsigned int len, rlen; 8250 8251 bkn_thread_boot(tc); 8252 8253 DBG_VERB(("Command thread starting\n")); 8254 tc->state = 1; 8255 while (!bkn_thread_should_stop(tc)) { 8256 len = sizeof(kmsg); 8257 tc->state = 2; 8258 if (PROXY_RECV(KCOM_CHAN_KNET, &kmsg, &len) >= 0) { 8259 DBG_VERB(("Received %d bytes from KCOM_CHAN_CMD\n", len)); 8260 tc->state = 3; 8261 rlen = bkn_handle_cmd_req(&kmsg, len); 8262 tc->state = 4; 8263 if (rlen > 0) { 8264 PROXY_SEND(KCOM_CHAN_KNET, &kmsg, rlen); 8265 } 8266 } else { 8267 /* Thread interrupted */ 8268 bkn_sleep(1); 8269 } 8270 } 8271 DBG_VERB(("Command thread done\n")); 8272 8273 bkn_thread_exit(tc); 8274 return 0; 8275 } 8276 8277 static int 8278 bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) 8279 { 8280 static int last_dev_no = 0; 8281 bkn_switch_info_t *sinfo; 8282 unsigned long flags; 8283 int dev_no, dev_evt; 8284 bkn_evt_resource_t *evt; 8285 8286 dev_evt = kmsg->hdr.unit; 8287 sinfo = bkn_sinfo_from_unit(dev_evt); 8288 if (sinfo == NULL) { 8289 /* The device is not probed or initialized yet.*/ 8290 return 0; 8291 } 8292 if (sinfo->evt_idx == -1) { 8293 /* Event queue is not ready yet */ 8294 return 0; 8295 } 8296 8297 DBG_INST(("%s dev %d evt_idx %d\n",__FUNCTION__, dev_evt, sinfo->evt_idx)); 8298 dev_no = last_dev_no; 8299 while (1) { 8300 dev_no++; 8301 sinfo = bkn_sinfo_from_unit(dev_no); 8302 if (sinfo == NULL) { 8303 dev_no = 0; 8304 sinfo = bkn_sinfo_from_unit(dev_no); 8305 } 8306 8307 if (sinfo && (sinfo->inst_id != 0) && 8308 ((sinfo->inst_id & (1 << dev_evt)) == 0)) { 8309 DBG_INST((" %s skip dev(%d)\n",__FUNCTION__,dev_evt)); 8310 continue; 8311 } 8312 8313 if (sinfo && sinfo->dma_events) { 8314 DBG_EVT(("Next DMA events (0x%08x)\n", sinfo->dma_events)); 8315 kmsg->hdr.unit = sinfo->dev_no; 8316 8317 spin_lock_irqsave(&sinfo->lock, flags); 8318 kmsg->dma_info.flags = sinfo->dma_events; 8319 sinfo->dma_events = 0; 8320 spin_unlock_irqrestore(&sinfo->lock, flags); 8321 8322 last_dev_no = dev_no; 8323 break; 8324 } 8325 8326 if (dev_no == last_dev_no) { 8327 evt = &_bkn_evt[sinfo->evt_idx]; 8328 DBG_INST(("wait queue index %d\n",sinfo->evt_idx)); 8329 wait_event_interruptible(evt->evt_wq, 8330 evt->evt_wq_get != evt->evt_wq_put); 8331 DBG_VERB(("Event thread wakeup\n")); 8332 8333 /* Thread interrupted */ 8334 if (signal_pending(current)) { 8335 return 0; 8336 } 8337 8338 evt->evt_wq_get = evt->evt_wq_put; 8339 } 8340 } 8341 return sizeof(*kmsg); 8342 } 8343 8344 static int 8345 bkn_evt_thread(void *context) 8346 { 8347 bkn_thread_ctrl_t *tc = (bkn_thread_ctrl_t *)context; 8348 kcom_msg_dma_info_t kmsg; 8349 int len; 8350 8351 bkn_thread_boot(tc); 8352 8353 memset(&kmsg, 0, sizeof(kmsg)); 8354 kmsg.hdr.type = KCOM_MSG_TYPE_EVT; 8355 kmsg.hdr.opcode = KCOM_M_DMA_INFO; 8356 8357 DBG_VERB(("Event thread starting\n")); 8358 tc->state = 1; 8359 while (!bkn_thread_should_stop(tc)) { 8360 tc->state = 2; 8361 len = bkn_get_next_dma_event(&kmsg); 8362 tc->state = 3; 8363 if (len) { 8364 PROXY_SEND(KCOM_CHAN_KNET, &kmsg, len); 8365 } else { 8366 /* Thread interrupted */ 8367 bkn_sleep(1); 8368 } 8369 } 8370 DBG_VERB(("Event thread done\n")); 8371 8372 bkn_thread_exit(tc); 8373 return 0; 8374 } 8375 8376 static int 8377 _cleanup(void) 8378 { 8379 struct list_head *list; 8380 struct net_device *dev; 8381 bkn_filter_t *filter; 8382 bkn_priv_t *priv; 8383 bkn_switch_info_t *sinfo; 8384 unsigned long flags; 8385 8386 /* Inidicate that we are shutting down */ 8387 module_initialized = 0; 8388 8389 /* Shut down event thread */ 8390 bkn_thread_stop(&bkn_evt_ctrl); 8391 8392 /* Shut down command thread */ 8393 bkn_thread_stop(&bkn_cmd_ctrl); 8394 8395 /* Remove KCOM channel */ 8396 PROXY_SERVICE_DESTROY(KCOM_CHAN_KNET); 8397 8398 bkn_proc_cleanup(); 8399 remove_proc_entry("bcm/knet", NULL); 8400 remove_proc_entry("bcm", NULL); 8401 8402 list_for_each(list, &_sinfo_list) { 8403 sinfo = (bkn_switch_info_t *)list; 8404 8405 del_timer_sync(&sinfo->timer); 8406 del_timer_sync(&sinfo->rxtick); 8407 8408 spin_lock_irqsave(&sinfo->lock, flags); 8409 bkn_dma_abort(sinfo); 8410 dev_irq_mask_set(sinfo, 0); 8411 spin_unlock_irqrestore(&sinfo->lock, flags); 8412 8413 DBG_IRQ(("Unregister ISR.\n")); 8414 kernel_bde->interrupt_disconnect(sinfo->dev_no | LKBDE_ISR2_DEV); 8415 8416 if (use_napi) { 8417 while (sinfo->napi_poll_mode) { 8418 bkn_sleep(1); 8419 } 8420 } 8421 8422 spin_lock_irqsave(&sinfo->lock, flags); 8423 bkn_clean_dcbs(sinfo); 8424 skb_queue_purge(&sinfo->tx_ptp_queue); 8425 spin_unlock_irqrestore(&sinfo->lock, flags); 8426 } 8427 8428 /* Destroy all switch devices */ 8429 while (!list_empty(&_sinfo_list)) { 8430 sinfo = list_entry(_sinfo_list.next, bkn_switch_info_t, list); 8431 8432 /* Destroy all associated Rx packet filters */ 8433 while (!list_empty(&sinfo->rxpf_list)) { 8434 filter = list_entry(sinfo->rxpf_list.next, bkn_filter_t, list); 8435 list_del(&filter->list); 8436 DBG_VERB(("Removing filter ID %d.\n", filter->kf.id)); 8437 kfree(filter); 8438 } 8439 8440 /* Destroy all associated virtual net devices */ 8441 while (!list_empty(&sinfo->ndev_list)) { 8442 priv = list_entry(sinfo->ndev_list.next, bkn_priv_t, list); 8443 list_del(&priv->list); 8444 dev = priv->dev; 8445 DBG_VERB(("Removing virtual Ethernet device %s.\n", dev->name)); 8446 unregister_netdev(dev); 8447 free_netdev(dev); 8448 } 8449 if (sinfo->ndevs != NULL) { 8450 kfree(sinfo->ndevs); 8451 } 8452 8453 /* Destroy base net device */ 8454 if (sinfo->dev) { 8455 DBG_VERB(("Removing Ethernet device %s.\n", sinfo->dev->name)); 8456 unregister_netdev(sinfo->dev); 8457 free_netdev(sinfo->dev); 8458 } 8459 8460 DBG_VERB(("Removing switch device.\n")); 8461 bkn_destroy_sinfo(sinfo); 8462 } 8463 8464 return 0; 8465 } 8466 8467 static int 8468 bkn_knet_dev_reinit(int d) 8469 { 8470 bkn_switch_info_t *sinfo; 8471 uint32 dev_state; 8472 unsigned long flags; 8473 8474 if (lkbde_dev_state_get(d, &dev_state) < 0) { 8475 return -1; 8476 } 8477 DBG_VERB(("%s dev %d dev_state %d\n",__FUNCTION__, d, dev_state)); 8478 if (dev_state == BDE_DEV_STATE_CHANGED) { 8479 sinfo = bkn_sinfo_from_unit(d); 8480 spin_lock_irqsave(&sinfo->lock, flags); 8481 sinfo->base_addr = lkbde_get_dev_virt(d); 8482 sinfo->dma_dev = lkbde_get_dma_dev(d); 8483 sinfo->pdev = lkbde_get_hw_dev(d); 8484 spin_unlock_irqrestore(&sinfo->lock, flags); 8485 8486 dev_state = 0; 8487 lkbde_dev_state_set(d, dev_state); 8488 } 8489 return 0; 8490 } 8491 8492 static int 8493 bkn_knet_dev_init(int d) 8494 { 8495 uint32_t dev_type; 8496 struct net_device *dev; 8497 bkn_switch_info_t *sinfo; 8498 bkn_priv_t *priv; 8499 char *bdev_name; 8500 const ibde_dev_t *bde_dev; 8501 8502 DBG_VERB(("%s dev %d\n",__FUNCTION__, d)); 8503 /* Base network device name */ 8504 bdev_name = "bcm%d"; 8505 if (base_dev_name) { 8506 if (strlen(base_dev_name) < IFNAMSIZ) { 8507 bdev_name = base_dev_name; 8508 } else { 8509 DBG_WARN(("Base device name too long\n")); 8510 } 8511 } 8512 8513 dev_type = kernel_bde->get_dev_type(d); 8514 DBG_VERB(("Found device type 0x%x\n", dev_type)); 8515 if ((dev_type & BDE_SWITCH_DEV_TYPE) == 0) { 8516 DBG_WARN(("Not switch device - skipping\n")); 8517 return 0; 8518 } 8519 switch (dev_type & BDE_DEV_BUS_TYPE_MASK) { 8520 case BDE_PCI_DEV_TYPE: 8521 case BDE_ICS_DEV_TYPE: 8522 case BDE_AXI_DEV_TYPE: 8523 break; 8524 default: 8525 DBG_WARN(("Not PCI/ICS/AXI device - skipping\n")); 8526 return 0; 8527 } 8528 8529 if ((sinfo = bkn_create_sinfo(d)) == NULL) { 8530 _cleanup(); 8531 return -ENOMEM; 8532 } 8533 8534 /* Initialize the cpu_no.*/ 8535 if (dev_type & BDE_AXI_DEV_TYPE) { 8536 /* AXI device type implies the activated iProc iHost */ 8537 sinfo->cpu_no = 1; 8538 } 8539 /* Initialize default RCPU signature */ 8540 if ((bde_dev = kernel_bde->get_dev(d)) != NULL) { 8541 sinfo->rcpu_sig = bde_dev->device & ~0xf; 8542 } 8543 /* Check for override */ 8544 if (rcpu_signature) { 8545 sinfo->rcpu_sig = rcpu_signature; 8546 } 8547 8548 /* Create base virtual net device */ 8549 bkn_dev_mac[5]++; 8550 if ((dev = bkn_init_ndev(bkn_dev_mac, bdev_name)) == NULL) { 8551 _cleanup(); 8552 return -ENOMEM; 8553 } else { 8554 sinfo->dev = dev; 8555 priv = netdev_priv(dev); 8556 priv->dev = dev; 8557 priv->sinfo = sinfo; 8558 priv->vlan = 1; 8559 priv->port = -1; 8560 memset(priv->itmh, 0, sizeof(priv->itmh)); 8561 priv->id = -1; 8562 } 8563 8564 if (use_napi) { 8565 netif_napi_add(dev, &sinfo->napi, bkn_poll, napi_weight); 8566 } 8567 return 0; 8568 } 8569 8570 static int 8571 _init(void) 8572 { 8573 int idx; 8574 int num_dev; 8575 int rv; 8576 bkn_evt_resource_t *evt; 8577 8578 /* Connect to the kernel bde */ 8579 if ((linux_bde_create(NULL, &kernel_bde) < 0) || kernel_bde == NULL) { 8580 return -ENODEV; 8581 } 8582 8583 /* Randomize Lower 3 bytes of the MAC address (TESTING ONLY) */ 8584 get_random_bytes(&bkn_dev_mac[3], 3); 8585 8586 /* Check for user-supplied MAC address (recommended) */ 8587 if (mac_addr != NULL && strlen(mac_addr) == 17) { 8588 for (idx = 0; idx < 6; idx++) { 8589 bkn_dev_mac[idx] = simple_strtoul(&mac_addr[idx*3], NULL, 16); 8590 } 8591 /* Do not allow multicast address */ 8592 bkn_dev_mac[0] &= ~0x01; 8593 } 8594 8595 /* Optional RCPU MAC addresses */ 8596 if (rcpu_dmac != NULL && strlen(rcpu_dmac) == 17) { 8597 for (idx = 0; idx < 6; idx++) { 8598 bkn_rcpu_dmac[idx] = simple_strtoul(&rcpu_dmac[idx*3], NULL, 16); 8599 } 8600 } 8601 if (rcpu_smac != NULL && strlen(rcpu_smac) == 17) { 8602 for (idx = 0; idx < 6; idx++) { 8603 bkn_rcpu_smac[idx] = simple_strtoul(&rcpu_smac[idx*3], NULL, 16); 8604 } 8605 } 8606 8607 /* NAPI implies that base device must be up before we can pass traffic */ 8608 if (use_napi) { 8609 basedev_suspend = 1; 8610 } 8611 8612 num_dev = kernel_bde->num_devices(BDE_ALL_DEVICES); 8613 for (idx = 0; idx < num_dev; idx++) { 8614 rv = bkn_knet_dev_init(idx); 8615 if (rv) { 8616 return rv; 8617 } 8618 } 8619 8620 /* Initialize proc files */ 8621 proc_mkdir("bcm", NULL); 8622 bkn_proc_root = proc_mkdir("bcm/knet", NULL); 8623 8624 bkn_proc_init(); 8625 8626 /* Initialize event queue */ 8627 for (idx = 0; idx < LINUX_BDE_MAX_DEVICES; idx++) { 8628 memset(&_bkn_evt[idx], 0, sizeof(bkn_evt_resource_t)); 8629 } 8630 evt = &_bkn_evt[0]; 8631 init_waitqueue_head(&evt->evt_wq); 8632 8633 if (use_proxy) { 8634 PROXY_SERVICE_CREATE(KCOM_CHAN_KNET, 1, 0); 8635 8636 DBG_VERB(("Starting command thread\n")); 8637 bkn_thread_start(&bkn_cmd_ctrl, "bkncmd", bkn_cmd_thread); 8638 8639 DBG_VERB(("Starting event thread\n")); 8640 bkn_thread_start(&bkn_evt_ctrl, "bknevt", bkn_evt_thread); 8641 } 8642 8643 module_initialized = 1; 8644 8645 return 0; 8646 } 8647 8648 static int 8649 _ioctl(unsigned int cmd, unsigned long arg) 8650 { 8651 bkn_ioctl_t io; 8652 kcom_msg_t kmsg; 8653 8654 if (!module_initialized) { 8655 return -EFAULT; 8656 } 8657 8658 if (copy_from_user(&io, (void*)arg, sizeof(io))) { 8659 return -EFAULT; 8660 } 8661 8662 if (io.len > sizeof(kmsg)) { 8663 return -EINVAL; 8664 } 8665 8666 io.rc = 0; 8667 8668 switch(cmd) { 8669 case 0: 8670 if (io.len > 0) { 8671 if (copy_from_user(&kmsg, (void *)(unsigned long)io.buf, io.len)) { 8672 return -EFAULT; 8673 } 8674 ioctl_cmd++; 8675 io.len = bkn_handle_cmd_req(&kmsg, io.len); 8676 ioctl_cmd--; 8677 } else { 8678 memset(&kmsg, 0, sizeof(kcom_msg_dma_info_t)); 8679 /* 8680 * Retrive the kmsg.hdr.unit from user space. The dma event queue 8681 * selection is based the instance derived from unit. 8682 */ 8683 if (copy_from_user(&kmsg, (void *)(unsigned long)io.buf, sizeof(kmsg))) { 8684 return -EFAULT; 8685 } 8686 kmsg.hdr.type = KCOM_MSG_TYPE_EVT; 8687 kmsg.hdr.opcode = KCOM_M_DMA_INFO; 8688 ioctl_evt++; 8689 io.len = bkn_get_next_dma_event((kcom_msg_dma_info_t *)&kmsg); 8690 ioctl_evt--; 8691 } 8692 if (io.len > 0) { 8693 if (copy_to_user((void *)(unsigned long)io.buf, &kmsg, io.len)) { 8694 return -EFAULT; 8695 } 8696 } 8697 break; 8698 default: 8699 gprintk("Invalid IOCTL"); 8700 io.rc = -1; 8701 break; 8702 } 8703 8704 if (copy_to_user((void*)arg, &io, sizeof(io))) { 8705 return -EFAULT; 8706 } 8707 8708 return 0; 8709 } 8710 8711 static gmodule_t _gmodule = { 8712 name: MODULE_NAME, 8713 major: MODULE_MAJOR, 8714 init: _init, 8715 cleanup: _cleanup, 8716 pprint: _pprint, 8717 ioctl: _ioctl, 8718 open: NULL, 8719 close: NULL, 8720 }; 8721 8722 gmodule_t * 8723 gmodule_get(void) 8724 { 8725 EXPORT_NO_SYMBOLS; 8726 return &_gmodule; 8727 } 8728 8729 /* 8730 * Call-back interfaces for other Linux kernel drivers. 8731 * 8732 * The Rx call-back allows an external module to modify SKB contents 8733 * before it is handed off to the Linux network stack. 8734 * 8735 * The Tx call-back allows an external module to modify SKB contents 8736 * before it is injected inot the switch. 8737 * 8738 * The HW timestamp callbacks invoke an external module to enable, disable 8739 * HW timestamp on a specific port which is indicated while the netif is 8740 * created through KNET API. KNET can also get device-specific SOBMH and 8741 * timestamp for a Tx PTP packet through these callbacks. 8742 */ 8743 8744 int 8745 bkn_rx_skb_cb_register(knet_skb_cb_f rx_cb) 8746 { 8747 if (knet_rx_cb != NULL) { 8748 return -1; 8749 } 8750 knet_rx_cb = rx_cb; 8751 return 0; 8752 } 8753 8754 int 8755 bkn_rx_skb_cb_unregister(knet_skb_cb_f rx_cb) 8756 { 8757 if (rx_cb != NULL && knet_rx_cb != rx_cb) { 8758 return -1; 8759 } 8760 knet_rx_cb = NULL; 8761 return 0; 8762 } 8763 8764 int 8765 bkn_tx_skb_cb_register(knet_skb_cb_f tx_cb) 8766 { 8767 if (knet_tx_cb != NULL) { 8768 return -1; 8769 } 8770 knet_tx_cb = tx_cb; 8771 return 0; 8772 } 8773 8774 int 8775 bkn_tx_skb_cb_unregister(knet_skb_cb_f tx_cb) 8776 { 8777 if (tx_cb != NULL && knet_tx_cb != tx_cb) { 8778 return -1; 8779 } 8780 knet_tx_cb = NULL; 8781 return 0; 8782 } 8783 8784 int 8785 bkn_filter_cb_register(knet_filter_cb_f filter_cb) 8786 { 8787 if (knet_filter_cb != NULL) { 8788 return -1; 8789 } 8790 knet_filter_cb = filter_cb; 8791 return 0; 8792 } 8793 8794 int 8795 bkn_filter_cb_unregister(knet_filter_cb_f filter_cb) 8796 { 8797 if (filter_cb != NULL && knet_filter_cb != filter_cb) { 8798 return -1; 8799 } 8800 knet_filter_cb = NULL; 8801 return 0; 8802 } 8803 8804 int 8805 bkn_hw_tstamp_enable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb) 8806 { 8807 if (knet_hw_tstamp_enable_cb != NULL) { 8808 return -1; 8809 } 8810 knet_hw_tstamp_enable_cb = hw_tstamp_enable_cb; 8811 return 0; 8812 } 8813 8814 int 8815 bkn_hw_tstamp_enable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb) 8816 { 8817 if (hw_tstamp_enable_cb == NULL || 8818 knet_hw_tstamp_enable_cb != hw_tstamp_enable_cb) { 8819 return -1; 8820 } 8821 knet_hw_tstamp_enable_cb = NULL; 8822 return 0; 8823 } 8824 8825 int 8826 bkn_hw_tstamp_disable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb) 8827 { 8828 if (knet_hw_tstamp_disable_cb != NULL) { 8829 return -1; 8830 } 8831 knet_hw_tstamp_disable_cb = hw_tstamp_disable_cb; 8832 return 0; 8833 } 8834 8835 int 8836 bkn_hw_tstamp_disable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb) 8837 { 8838 if (hw_tstamp_disable_cb == NULL || 8839 knet_hw_tstamp_disable_cb != hw_tstamp_disable_cb) { 8840 return -1; 8841 } 8842 knet_hw_tstamp_disable_cb = NULL; 8843 return 0; 8844 } 8845 8846 int 8847 bkn_hw_tstamp_tx_time_get_cb_register(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb) 8848 { 8849 if (knet_hw_tstamp_tx_time_get_cb != NULL) { 8850 return -1; 8851 } 8852 knet_hw_tstamp_tx_time_get_cb = hw_tstamp_tx_time_get_cb; 8853 return 0; 8854 } 8855 8856 int 8857 bkn_hw_tstamp_tx_time_get_cb_unregister(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb) 8858 { 8859 if (hw_tstamp_tx_time_get_cb == NULL || 8860 knet_hw_tstamp_tx_time_get_cb != hw_tstamp_tx_time_get_cb) { 8861 return -1; 8862 } 8863 knet_hw_tstamp_tx_time_get_cb = NULL; 8864 return 0; 8865 } 8866 8867 int 8868 bkn_hw_tstamp_tx_meta_get_cb_register(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb) 8869 { 8870 if (knet_hw_tstamp_tx_meta_get_cb != NULL) { 8871 return -1; 8872 } 8873 knet_hw_tstamp_tx_meta_get_cb = hw_tstamp_tx_meta_get_cb; 8874 return 0; 8875 } 8876 8877 int 8878 bkn_hw_tstamp_tx_meta_get_cb_unregister(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb) 8879 { 8880 if (hw_tstamp_tx_meta_get_cb == NULL || 8881 knet_hw_tstamp_tx_meta_get_cb != hw_tstamp_tx_meta_get_cb) { 8882 return -1; 8883 } 8884 knet_hw_tstamp_tx_meta_get_cb = NULL; 8885 return 0; 8886 } 8887 8888 int 8889 bkn_hw_tstamp_ptp_clock_index_cb_register(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb) 8890 { 8891 if (knet_hw_tstamp_ptp_clock_index_cb != NULL) { 8892 return -1; 8893 } 8894 knet_hw_tstamp_ptp_clock_index_cb = hw_tstamp_ptp_clock_index_cb; 8895 return 0; 8896 } 8897 8898 int 8899 bkn_hw_tstamp_ptp_clock_index_cb_unregister(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb) 8900 { 8901 if (hw_tstamp_ptp_clock_index_cb == NULL || 8902 knet_hw_tstamp_ptp_clock_index_cb != hw_tstamp_ptp_clock_index_cb) { 8903 return -1; 8904 } 8905 knet_hw_tstamp_ptp_clock_index_cb = NULL; 8906 return 0; 8907 } 8908 8909 int 8910 bkn_hw_tstamp_rx_time_upscale_cb_register(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb) 8911 { 8912 if (knet_hw_tstamp_rx_time_upscale_cb != NULL) { 8913 return -1; 8914 } 8915 knet_hw_tstamp_rx_time_upscale_cb = hw_tstamp_rx_time_upscale_cb; 8916 return 0; 8917 } 8918 8919 int 8920 bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb) 8921 { 8922 if (hw_tstamp_rx_time_upscale_cb == NULL || 8923 knet_hw_tstamp_rx_time_upscale_cb != hw_tstamp_rx_time_upscale_cb) { 8924 return -1; 8925 } 8926 knet_hw_tstamp_rx_time_upscale_cb = NULL; 8927 return 0; 8928 } 8929 8930 LKM_EXPORT_SYM(bkn_rx_skb_cb_register); 8931 LKM_EXPORT_SYM(bkn_rx_skb_cb_unregister); 8932 LKM_EXPORT_SYM(bkn_tx_skb_cb_register); 8933 LKM_EXPORT_SYM(bkn_tx_skb_cb_unregister); 8934 LKM_EXPORT_SYM(bkn_filter_cb_register); 8935 LKM_EXPORT_SYM(bkn_filter_cb_unregister); 8936 LKM_EXPORT_SYM(bkn_hw_tstamp_enable_cb_register); 8937 LKM_EXPORT_SYM(bkn_hw_tstamp_enable_cb_unregister); 8938 LKM_EXPORT_SYM(bkn_hw_tstamp_disable_cb_register); 8939 LKM_EXPORT_SYM(bkn_hw_tstamp_disable_cb_unregister); 8940 LKM_EXPORT_SYM(bkn_hw_tstamp_tx_time_get_cb_register); 8941 LKM_EXPORT_SYM(bkn_hw_tstamp_tx_time_get_cb_unregister); 8942 LKM_EXPORT_SYM(bkn_hw_tstamp_tx_meta_get_cb_register); 8943 LKM_EXPORT_SYM(bkn_hw_tstamp_tx_meta_get_cb_unregister); 8944 LKM_EXPORT_SYM(bkn_hw_tstamp_ptp_clock_index_cb_register); 8945 LKM_EXPORT_SYM(bkn_hw_tstamp_ptp_clock_index_cb_unregister); 8946 LKM_EXPORT_SYM(bkn_hw_tstamp_rx_time_upscale_cb_register); 8947 LKM_EXPORT_SYM(bkn_hw_tstamp_rx_time_upscale_cb_unregister);