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$");
   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 
   50 
   51 /**
   52  * Set the multicast list. Currently unimplemented.
   53  *
   54  * @param dev    Device to work on
   55  */
   56 void cvm_oct_common_set_multicast_list(struct ifnet *ifp)
   57 {
   58         cvmx_gmxx_prtx_cfg_t gmx_cfg;
   59         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
   60         int interface = INTERFACE(priv->port);
   61         int index = INDEX(priv->port);
   62 
   63         if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) {
   64                 cvmx_gmxx_rxx_adr_ctl_t control;
   65                 control.u64 = 0;
   66                 control.s.bcst = 1;     /* Allow broadcast MAC addresses */
   67 
   68                 if (/*ifp->mc_list || */(ifp->if_flags&IFF_ALLMULTI) ||
   69                     (ifp->if_flags & IFF_PROMISC))
   70                         control.s.mcst = 2; /* Force accept multicast packets */
   71                 else
   72                         control.s.mcst = 1; /* Force reject multicat packets */
   73 
   74                 if (ifp->if_flags & IFF_PROMISC)
   75                         control.s.cam_mode = 0; /* Reject matches if promisc. Since CAM is shut off, should accept everything */
   76                 else
   77                         control.s.cam_mode = 1; /* Filter packets based on the CAM */
   78 
   79                 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
   80                 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64 & ~1ull);
   81 
   82                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface), control.u64);
   83                 if (ifp->if_flags&IFF_PROMISC)
   84                         cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN(index, interface), 0);
   85                 else
   86                         cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN(index, interface), 1);
   87 
   88                 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
   89         }
   90 }
   91 
   92 
   93 /**
   94  * Set the hardware MAC address for a device
   95  *
   96  * @param dev    Device to change the MAC address for
   97  * @param addr   Address structure to change it too.
   98  */
   99 void cvm_oct_common_set_mac_address(struct ifnet *ifp, const void *addr)
  100 {
  101         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
  102         cvmx_gmxx_prtx_cfg_t gmx_cfg;
  103         int interface = INTERFACE(priv->port);
  104         int index = INDEX(priv->port);
  105 
  106         memcpy(priv->mac, addr, 6);
  107 
  108         if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) {
  109                 int i;
  110                 const uint8_t *ptr = addr;
  111                 uint64_t mac = 0;
  112                 for (i = 0; i < 6; i++)
  113                         mac = (mac<<8) | (uint64_t)(ptr[i]);
  114 
  115                 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
  116                 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64 & ~1ull);
  117 
  118                 cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac);
  119                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface), ptr[0]);
  120                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface), ptr[1]);
  121                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface), ptr[2]);
  122                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface), ptr[3]);
  123                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface), ptr[4]);
  124                 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface), ptr[5]);
  125                 cvm_oct_common_set_multicast_list(ifp);
  126                 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
  127         }
  128 }
  129 
  130 
  131 /**
  132  * Change the link MTU. Unimplemented
  133  *
  134  * @param dev     Device to change
  135  * @param new_mtu The new MTU
  136  * @return Zero on success
  137  */
  138 int cvm_oct_common_change_mtu(struct ifnet *ifp, int new_mtu)
  139 {
  140         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
  141         int interface = INTERFACE(priv->port);
  142         int index = INDEX(priv->port);
  143         int vlan_bytes = 4;
  144 
  145         /* Limit the MTU to make sure the ethernet packets are between 64 bytes
  146            and 65535 bytes */
  147         if ((new_mtu + 14 + 4 + vlan_bytes < 64) || (new_mtu + 14 + 4 + vlan_bytes > 65392)) {
  148                 printf("MTU must be between %d and %d.\n", 64-14-4-vlan_bytes, 65392-14-4-vlan_bytes);
  149                 return -EINVAL;
  150         }
  151         ifp->if_mtu = new_mtu;
  152 
  153         if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) {
  154                 int max_packet = new_mtu + 14 + 4 + vlan_bytes; /* Add ethernet header and FCS, and VLAN if configured. */
  155 
  156                 if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
  157                         /* Signal errors on packets larger than the MTU */
  158                         cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface), max_packet);
  159                 } else {
  160                         /* Set the hardware to truncate packets larger than the MTU and
  161                                 smaller the 64 bytes */
  162                         cvmx_pip_frm_len_chkx_t frm_len_chk;
  163                         frm_len_chk.u64 = 0;
  164                         frm_len_chk.s.minlen = 64;
  165                         frm_len_chk.s.maxlen = max_packet;
  166                         cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface), frm_len_chk.u64);
  167                 }
  168                 /* Set the hardware to truncate packets larger than the MTU. The
  169                    jabber register must be set to a multiple of 8 bytes, so round up */
  170                 cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface), (max_packet + 7) & ~7u);
  171         }
  172         return 0;
  173 }
  174 
  175 
  176 /**
  177  * Enable port.
  178  */
  179 int cvm_oct_common_open(struct ifnet *ifp)
  180 {
  181         cvmx_gmxx_prtx_cfg_t gmx_cfg;
  182         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
  183         int interface = INTERFACE(priv->port);
  184         int index = INDEX(priv->port);
  185         cvmx_helper_link_info_t link_info;
  186 
  187         gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
  188         gmx_cfg.s.en = 1;
  189         cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
  190 
  191         /*
  192          * Set the link state unless we are using MII.
  193          */
  194         if (!octeon_is_simulation() && priv->miibus == NULL) {
  195              link_info = cvmx_helper_link_get(priv->port);
  196              if (!link_info.s.link_up)  
  197                 if_link_state_change(ifp, LINK_STATE_DOWN);
  198              else
  199                 if_link_state_change(ifp, LINK_STATE_UP);
  200         }
  201 
  202         return 0;
  203 }
  204 
  205 
  206 /**
  207  * Disable port.
  208  */
  209 int cvm_oct_common_stop(struct ifnet *ifp)
  210 {
  211         cvmx_gmxx_prtx_cfg_t gmx_cfg;
  212         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
  213         int interface = INTERFACE(priv->port);
  214         int index = INDEX(priv->port);
  215 
  216         gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
  217         gmx_cfg.s.en = 0;
  218         cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
  219         return 0;
  220 }
  221 
  222 /**
  223  * Poll for link status change.
  224  */
  225 void cvm_oct_common_poll(struct ifnet *ifp)
  226 {
  227         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
  228         cvmx_helper_link_info_t link_info;
  229 
  230         /*
  231          * If this is a simulation, do nothing.
  232          */
  233         if (octeon_is_simulation())
  234                 return;
  235 
  236         /*
  237          * If there is a device-specific poll method, use it.
  238          */
  239         if (priv->poll != NULL) {
  240                 priv->poll(ifp);
  241                 return;
  242         }
  243 
  244         /*
  245          * If an MII bus is attached, don't use the Simple Executive's link
  246          * state routines.
  247          */
  248         if (priv->miibus != NULL)
  249                 return;
  250 
  251         /*
  252          * Use the Simple Executive's link state routines.
  253          */
  254         link_info = cvmx_helper_link_get(priv->port);
  255         if (link_info.u64 == priv->link_info)
  256                 return;
  257 
  258         link_info = cvmx_helper_link_autoconf(priv->port);
  259         priv->link_info = link_info.u64;
  260         priv->need_link_update = 1;
  261 }
  262 
  263 
  264 /**
  265  * Per network device initialization
  266  *
  267  * @param dev    Device to initialize
  268  * @return Zero on success
  269  */
  270 int cvm_oct_common_init(struct ifnet *ifp)
  271 {
  272         char mac[6] = {
  273                 octeon_bootinfo->mac_addr_base[0],
  274                 octeon_bootinfo->mac_addr_base[1],
  275                 octeon_bootinfo->mac_addr_base[2],
  276                 octeon_bootinfo->mac_addr_base[3],
  277                 octeon_bootinfo->mac_addr_base[4],
  278                 octeon_bootinfo->mac_addr_base[5] };
  279         cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
  280 
  281         mac[5] += cvm_oct_mac_addr_offset++;
  282 
  283         ifp->if_mtu = ETHERMTU;
  284 
  285         cvm_oct_mdio_setup_device(ifp);
  286 
  287         cvm_oct_common_set_mac_address(ifp, mac);
  288         cvm_oct_common_change_mtu(ifp, ifp->if_mtu);
  289 
  290         /*
  291          * Do any last-minute board-specific initialization.
  292          */
  293         switch (cvmx_sysinfo_get()->board_type) {
  294 #if defined(OCTEON_VENDOR_LANNER)
  295         case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
  296         case CVMX_BOARD_TYPE_CUST_LANNER_MR321X:
  297                 if (priv->phy_id == 16)
  298                         cvm_oct_mv88e61xx_setup_device(ifp);
  299                 break;
  300 #endif
  301         default:
  302                 break;
  303         }
  304 
  305         device_attach(priv->dev);
  306 
  307         return 0;
  308 }
  309 
  310 void cvm_oct_common_uninit(struct ifnet *ifp)
  311 {
  312     /* Currently nothing to do */
  313 }
  314 

Cache object: 5ca1917c52f48544852acf03ec46e6a1


[ 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.