The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mips/cavium/octe/ethernet-common.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*************************************************************************
    2 Copyright (c) 2003-2007  Cavium Networks (support@cavium.com). All rights
    3 reserved.
    4 
    5 
    6 Redistribution and use in source and binary forms, with or without
    7 modification, are permitted provided that the following conditions are
    8 met:
    9 
   10     * Redistributions of source code must retain the above copyright
   11       notice, this list of conditions and the following disclaimer.
   12 
   13     * Redistributions in binary form must reproduce the above
   14       copyright notice, this list of conditions and the following
   15       disclaimer in the documentation and/or other materials provided
   16       with the distribution.
   17 
   18     * Neither the name of Cavium Networks nor the names of
   19       its contributors may be used to endorse or promote products
   20       derived from this software without specific prior written
   21       permission.
   22 
   23 This Software, including technical data, may be subject to U.S. export  control laws, including the U.S. Export Administration Act and its  associated regulations, and may be subject to export or import  regulations in other countries.
   24 
   25 TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
   26 AND WITH ALL FAULTS AND CAVIUM  NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
   27 
   28 *************************************************************************/
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD: releng/8.4/sys/mips/cavium/octe/ethernet-common.c 215938 2010-11-27 12:26:40Z jchandra $");
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/bus.h>
   36 #include <sys/endian.h>
   37 #include <sys/kernel.h>
   38 #include <sys/mbuf.h>
   39 #include <sys/socket.h>
   40 
   41 #include <net/ethernet.h>
   42 #include <net/if.h>
   43 
   44 #include "wrapper-cvmx-includes.h"
   45 #include "ethernet-headers.h"
   46 
   47 extern int octeon_is_simulation(void);
   48 extern cvmx_bootinfo_t *octeon_bootinfo;
   49 extern int pow_send_group;
   50 extern int always_use_pow;
   51 extern char pow_send_list[];
   52 
   53 
   54 /**
   55  * Get the low level ethernet statistics
   56  *
   57  * @param dev    Device to get the statistics from
   58  * @return Pointer to the statistics
   59  */
   60 #if 0
   61 static struct ifnet_stats *cvm_oct_common_get_stats(struct ifnet *ifp)
   62 {
   63         cvmx_pip_port_status_t rx_status;
   64         cvmx_pko_port_status_t tx_status;
   65         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
   66 
   67         if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) {
   68                 if (octeon_is_simulation()) {
   69                         /* The simulator doesn't support statistics */
   70                         memset(&rx_status, 0, sizeof(rx_status));
   71                         memset(&tx_status, 0, sizeof(tx_status));
   72                 } else {
   73                 cvmx_pip_get_port_status(priv->port, 1, &rx_status);
   74                 cvmx_pko_get_port_status(priv->port, 1, &tx_status);
   75                 }
   76 
   77                 priv->stats.rx_packets      += rx_status.inb_packets;
   78                 priv->stats.tx_packets      += tx_status.packets;
   79                 priv->stats.rx_bytes        += rx_status.inb_octets;
   80                 priv->stats.tx_bytes        += tx_status.octets;
   81                 priv->stats.multicast       += rx_status.multicast_packets;
   82                 priv->stats.rx_crc_errors   += rx_status.inb_errors;
   83                 priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets;
   84 
   85                 /* The drop counter must be incremented atomically since the RX
   86                    tasklet also increments it */
   87 #ifdef CONFIG_64BIT
   88                 cvmx_atomic_add64_nosync(&priv->stats.rx_dropped, rx_status.dropped_packets);
   89 #else
   90                 cvmx_atomic_add32_nosync((int32_t *)&priv->stats.rx_dropped, rx_status.dropped_packets);
   91 #endif
   92         }
   93 
   94         return &priv->stats;
   95 }
   96 #endif
   97 
   98 
   99 /**
  100  * Set the multicast list. Currently unimplemented.
  101  *
  102  * @param dev    Device to work on
  103  */
  104 void cvm_oct_common_set_multicast_list(struct ifnet *ifp)
  105 {
  106         cvmx_gmxx_prtx_cfg_t gmx_cfg;
  107         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
  108         int interface = INTERFACE(priv->port);
  109         int index = INDEX(priv->port);
  110 
  111         if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) {
  112                 cvmx_gmxx_rxx_adr_ctl_t control;
  113                 control.u64 = 0;
  114                 control.s.bcst = 1;     /* Allow broadcast MAC addresses */
  115 
  116                 if (/*ifp->mc_list || */(ifp->if_flags&IFF_ALLMULTI) ||
  117                     (ifp->if_flags & IFF_PROMISC))
  118                         control.s.mcst = 2; /* Force accept multicast packets */
  119                 else
  120                         control.s.mcst = 1; /* Force reject multicat packets */
  121 
  122                 if (ifp->if_flags & IFF_PROMISC)
  123                         control.s.cam_mode = 0; /* Reject matches if promisc. Since CAM is shut off, should accept everything */
  124                 else
  125                         control.s.cam_mode = 1; /* Filter packets based on the CAM */
  126 
  127                 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
  128                 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64 & ~1ull);
  129 
  130                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface), control.u64);
  131                 if (ifp->if_flags&IFF_PROMISC)
  132                         cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN(index, interface), 0);
  133                 else
  134                         cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN(index, interface), 1);
  135 
  136                 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
  137         }
  138 }
  139 
  140 
  141 /**
  142  * Set the hardware MAC address for a device
  143  *
  144  * @param dev    Device to change the MAC address for
  145  * @param addr   Address structure to change it too.
  146  */
  147 void cvm_oct_common_set_mac_address(struct ifnet *ifp, const void *addr)
  148 {
  149         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
  150         cvmx_gmxx_prtx_cfg_t gmx_cfg;
  151         int interface = INTERFACE(priv->port);
  152         int index = INDEX(priv->port);
  153 
  154         memcpy(priv->mac, addr, 6);
  155 
  156         if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) {
  157                 int i;
  158                 const uint8_t *ptr = addr;
  159                 uint64_t mac = 0;
  160                 for (i = 0; i < 6; i++)
  161                         mac = (mac<<8) | (uint64_t)(ptr[i]);
  162 
  163                 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
  164                 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64 & ~1ull);
  165 
  166                 cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac);
  167                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface), ptr[0]);
  168                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface), ptr[1]);
  169                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface), ptr[2]);
  170                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface), ptr[3]);
  171                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface), ptr[4]);
  172                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface), ptr[5]);
  173                 cvm_oct_common_set_multicast_list(ifp);
  174                 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
  175         }
  176 }
  177 
  178 
  179 /**
  180  * Change the link MTU. Unimplemented
  181  *
  182  * @param dev     Device to change
  183  * @param new_mtu The new MTU
  184  * @return Zero on success
  185  */
  186 int cvm_oct_common_change_mtu(struct ifnet *ifp, int new_mtu)
  187 {
  188         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
  189         int interface = INTERFACE(priv->port);
  190         int index = INDEX(priv->port);
  191         int vlan_bytes = 4;
  192 
  193         /* Limit the MTU to make sure the ethernet packets are between 64 bytes
  194            and 65535 bytes */
  195         if ((new_mtu + 14 + 4 + vlan_bytes < 64) || (new_mtu + 14 + 4 + vlan_bytes > 65392)) {
  196                 printf("MTU must be between %d and %d.\n", 64-14-4-vlan_bytes, 65392-14-4-vlan_bytes);
  197                 return -EINVAL;
  198         }
  199         ifp->if_mtu = new_mtu;
  200 
  201         if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) {
  202                 int max_packet = new_mtu + 14 + 4 + vlan_bytes; /* Add ethernet header and FCS, and VLAN if configured. */
  203 
  204                 if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
  205                         /* Signal errors on packets larger than the MTU */
  206                         cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface), max_packet);
  207                 } else {
  208                         /* Set the hardware to truncate packets larger than the MTU and
  209                                 smaller the 64 bytes */
  210                         cvmx_pip_frm_len_chkx_t frm_len_chk;
  211                         frm_len_chk.u64 = 0;
  212                         frm_len_chk.s.minlen = 64;
  213                         frm_len_chk.s.maxlen = max_packet;
  214                         cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface), frm_len_chk.u64);
  215                 }
  216                 /* Set the hardware to truncate packets larger than the MTU. The
  217                    jabber register must be set to a multiple of 8 bytes, so round up */
  218                 cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface), (max_packet + 7) & ~7u);
  219         }
  220         return 0;
  221 }
  222 
  223 
  224 /**
  225  * Per network device initialization
  226  *
  227  * @param dev    Device to initialize
  228  * @return Zero on success
  229  */
  230 int cvm_oct_common_init(struct ifnet *ifp)
  231 {
  232         static int count;
  233         char mac[6] = {
  234                 octeon_bootinfo->mac_addr_base[0],
  235                 octeon_bootinfo->mac_addr_base[1],
  236                 octeon_bootinfo->mac_addr_base[2],
  237                 octeon_bootinfo->mac_addr_base[3],
  238                 octeon_bootinfo->mac_addr_base[4],
  239                 octeon_bootinfo->mac_addr_base[5] + count};
  240         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
  241 
  242         /* Force the interface to use the POW send if always_use_pow was
  243            specified or it is in the pow send list */
  244         if ((pow_send_group != -1) && (always_use_pow || strstr(pow_send_list, if_name(ifp))))
  245                 priv->queue = -1;
  246 
  247         ifp->if_mtu = ETHERMTU;
  248 
  249         count++;
  250 
  251 #if 0
  252         ifp->get_stats          = cvm_oct_common_get_stats;
  253 #ifdef CONFIG_NET_POLL_CONTROLLER
  254         ifp->poll_controller    = cvm_oct_poll_controller;
  255 #endif
  256 #endif
  257 
  258         cvm_oct_mdio_setup_device(ifp);
  259 
  260         cvm_oct_common_set_mac_address(ifp, mac);
  261         cvm_oct_common_change_mtu(ifp, ifp->if_mtu);
  262 
  263 #if 0
  264         /* Zero out stats for port so we won't mistakenly show counters from the
  265            bootloader */
  266         memset(ifp->get_stats(ifp), 0, sizeof(struct ifnet_stats));
  267 #endif
  268 
  269         /*
  270          * Do any last-minute board-specific initialization.
  271          */
  272         switch (cvmx_sysinfo_get()->board_type) {
  273 #if defined(OCTEON_VENDOR_LANNER)
  274         case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
  275                 if (priv->phy_id == 16)
  276                         cvm_oct_mv88e61xx_setup_device(ifp);
  277                 break;
  278 #endif
  279         default:
  280                 break;
  281         }
  282 
  283         device_attach(priv->dev);
  284 
  285         return 0;
  286 }
  287 
  288 void cvm_oct_common_uninit(struct ifnet *ifp)
  289 {
  290     /* Currently nothing to do */
  291 }
  292 

Cache object: 2d6e0f802c24b464be478ebd78f3e479


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.