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/dev/liquidio/lio_ioctl.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  *   BSD LICENSE
    3  *
    4  *   Copyright(c) 2017 Cavium, Inc.. All rights reserved.
    5  *   All rights reserved.
    6  *
    7  *   Redistribution and use in source and binary forms, with or without
    8  *   modification, are permitted provided that the following conditions
    9  *   are met:
   10  *
   11  *     * Redistributions of source code must retain the above copyright
   12  *       notice, this list of conditions and the following disclaimer.
   13  *     * Redistributions in binary form must reproduce the above copyright
   14  *       notice, this list of conditions and the following disclaimer in
   15  *       the documentation and/or other materials provided with the
   16  *       distribution.
   17  *     * Neither the name of Cavium, Inc. nor the names of its
   18  *       contributors may be used to endorse or promote products derived
   19  *       from this software without specific prior written permission.
   20  *
   21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   25  *   OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 /*$FreeBSD$*/
   34 
   35 #include "lio_bsd.h"
   36 #include "lio_common.h"
   37 #include "lio_droq.h"
   38 #include "lio_iq.h"
   39 #include "lio_response_manager.h"
   40 #include "lio_device.h"
   41 #include "lio_network.h"
   42 #include "lio_ctrl.h"
   43 #include "cn23xx_pf_device.h"
   44 #include "lio_image.h"
   45 #include "lio_ioctl.h"
   46 #include "lio_main.h"
   47 #include "lio_rxtx.h"
   48 
   49 static int      lio_set_rx_csum(struct ifnet *ifp, uint32_t data);
   50 static int      lio_set_tso4(struct ifnet *ifp);
   51 static int      lio_set_tso6(struct ifnet *ifp);
   52 static int      lio_set_lro(struct ifnet *ifp);
   53 static int      lio_change_mtu(struct ifnet *ifp, int new_mtu);
   54 static int      lio_set_mcast_list(struct ifnet *ifp);
   55 static inline enum      lio_ifflags lio_get_new_flags(struct ifnet *ifp);
   56 
   57 static inline bool
   58 lio_is_valid_ether_addr(const uint8_t *addr)
   59 {
   60 
   61         return (!(0x01 & addr[0]) && !((addr[0] + addr[1] + addr[2] + addr[3] +
   62                                         addr[4] + addr[5]) == 0x00));
   63 }
   64 
   65 static int
   66 lio_change_dev_flags(struct ifnet *ifp)
   67 {
   68         struct lio_ctrl_pkt     nctrl;
   69         struct lio              *lio = if_getsoftc(ifp);
   70         struct octeon_device    *oct = lio->oct_dev;
   71         int ret = 0;
   72 
   73         bzero(&nctrl, sizeof(struct lio_ctrl_pkt));
   74 
   75         /* Create a ctrl pkt command to be sent to core app. */
   76         nctrl.ncmd.cmd64 = 0;
   77         nctrl.ncmd.s.cmd = LIO_CMD_CHANGE_DEVFLAGS;
   78         nctrl.ncmd.s.param1 = lio_get_new_flags(ifp);
   79         nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
   80         nctrl.lio = lio;
   81         nctrl.cb_fn = lio_ctrl_cmd_completion;
   82 
   83         ret = lio_send_ctrl_pkt(oct, &nctrl);
   84         if (ret)
   85                 lio_dev_err(oct, "Failed to change flags ret %d\n", ret);
   86 
   87         return (ret);
   88 }
   89 
   90 /*
   91  * lio_ioctl : User calls this routine for configuring
   92  * the interface.
   93  *
   94  * return 0 on success, positive on failure
   95  */
   96 int
   97 lio_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
   98 {
   99         struct lio      *lio = if_getsoftc(ifp);
  100         struct ifreq    *ifrequest = (struct ifreq *)data;
  101         int     error = 0;
  102 
  103         switch (cmd) {
  104         case SIOCSIFADDR:
  105                 lio_dev_dbg(lio->oct_dev, "ioctl: SIOCSIFADDR\n");
  106                 if_setflagbits(ifp, IFF_UP, 0);
  107                 error = ether_ioctl(ifp, cmd, data);
  108                 break;
  109         case SIOCSIFMTU:
  110                 lio_dev_dbg(lio->oct_dev, "ioctl: SIOCSIFMTU\n");
  111                 error = lio_change_mtu(ifp, ifrequest->ifr_mtu);
  112                 break;
  113         case SIOCSIFFLAGS:
  114                 lio_dev_dbg(lio->oct_dev, "ioctl: SIOCSIFFLAGS\n");
  115                 if (if_getflags(ifp) & IFF_UP) {
  116                         if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
  117                                 if ((if_getflags(ifp) ^ lio->if_flags) &
  118                                     (IFF_PROMISC | IFF_ALLMULTI))
  119                                         error = lio_change_dev_flags(ifp);
  120                         } else {
  121                                 if (!(atomic_load_acq_int(&lio->ifstate) &
  122                                       LIO_IFSTATE_DETACH))
  123                                         lio_open(lio);
  124                         }
  125                 } else {
  126                         if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
  127                                 lio_stop(ifp);
  128                 }
  129                 lio->if_flags = if_getflags(ifp);
  130                 break;
  131         case SIOCADDMULTI:
  132                 lio_dev_dbg(lio->oct_dev, "ioctl: SIOCADDMULTI\n");
  133                 if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
  134                         error = lio_set_mcast_list(ifp);
  135                 break;
  136         case SIOCDELMULTI:
  137                 lio_dev_dbg(lio->oct_dev, "ioctl: SIOCSIFMULTI\n");
  138                 break;
  139         case SIOCSIFMEDIA:
  140                 lio_dev_dbg(lio->oct_dev, "ioctl: SIOCSIFMEDIA\n");
  141         case SIOCGIFMEDIA:
  142                 lio_dev_dbg(lio->oct_dev, "ioctl: SIOCGIFMEDIA\n");
  143         case SIOCGIFXMEDIA:
  144                 lio_dev_dbg(lio->oct_dev, "ioctl: SIOCGIFXMEDIA\n");
  145                 error = ifmedia_ioctl(ifp, ifrequest, &lio->ifmedia, cmd);
  146                 break;
  147         case SIOCSIFCAP:
  148                 {
  149                         int     features = ifrequest->ifr_reqcap ^
  150                                         if_getcapenable(ifp);
  151 
  152                         lio_dev_dbg(lio->oct_dev, "ioctl: SIOCSIFCAP (Set Capabilities)\n");
  153 
  154                         if (!features)
  155                                 break;
  156 
  157                         if (features & IFCAP_TXCSUM) {
  158                                 if_togglecapenable(ifp, IFCAP_TXCSUM);
  159                                 if (if_getcapenable(ifp) & IFCAP_TXCSUM)
  160                                         if_sethwassistbits(ifp, (CSUM_TCP |
  161                                                                  CSUM_UDP |
  162                                                                  CSUM_IP), 0);
  163                                 else
  164                                         if_sethwassistbits(ifp, 0,
  165                                                         (CSUM_TCP | CSUM_UDP |
  166                                                          CSUM_IP));
  167                         }
  168                         if (features & IFCAP_TXCSUM_IPV6) {
  169                                 if_togglecapenable(ifp, IFCAP_TXCSUM_IPV6);
  170                                 if (if_getcapenable(ifp) & IFCAP_TXCSUM_IPV6)
  171                                         if_sethwassistbits(ifp, (CSUM_UDP_IPV6 |
  172                                                            CSUM_TCP_IPV6), 0);
  173                                 else
  174                                         if_sethwassistbits(ifp, 0,
  175                                                            (CSUM_UDP_IPV6 |
  176                                                             CSUM_TCP_IPV6));
  177                         }
  178                         if (features & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6))
  179                                 error |= lio_set_rx_csum(ifp, (features &
  180                                                                (IFCAP_RXCSUM |
  181                                                          IFCAP_RXCSUM_IPV6)));
  182 
  183                         if (features & IFCAP_TSO4)
  184                                 error |= lio_set_tso4(ifp);
  185 
  186                         if (features & IFCAP_TSO6)
  187                                 error |= lio_set_tso6(ifp);
  188 
  189                         if (features & IFCAP_LRO)
  190                                 error |= lio_set_lro(ifp);
  191 
  192                         if (features & IFCAP_VLAN_HWTAGGING)
  193                                 if_togglecapenable(ifp, IFCAP_VLAN_HWTAGGING);
  194 
  195                         if (features & IFCAP_VLAN_HWFILTER)
  196                                 if_togglecapenable(ifp, IFCAP_VLAN_HWFILTER);
  197 
  198                         if (features & IFCAP_VLAN_HWTSO)
  199                                 if_togglecapenable(ifp, IFCAP_VLAN_HWTSO);
  200 
  201                         VLAN_CAPABILITIES(ifp);
  202                         break;
  203                 }
  204         default:
  205                 lio_dev_dbg(lio->oct_dev, "ioctl: UNKNOWN (0x%X)\n", (int)cmd);
  206                 error = ether_ioctl(ifp, cmd, data);
  207                 break;
  208         }
  209 
  210         return (error);
  211 }
  212 
  213 static int
  214 lio_set_tso4(struct ifnet *ifp)
  215 {
  216         struct lio      *lio = if_getsoftc(ifp);
  217 
  218         if (if_getcapabilities(ifp) & IFCAP_TSO4) {
  219                 if_togglecapenable(ifp, IFCAP_TSO4);
  220                 if (if_getcapenable(ifp) & IFCAP_TSO4)
  221                         if_sethwassistbits(ifp, CSUM_IP_TSO, 0);
  222                 else
  223                         if_sethwassistbits(ifp, 0, CSUM_IP_TSO);
  224         } else {
  225                 lio_dev_info(lio->oct_dev, "TSO4 capability not supported\n");
  226                 return (EINVAL);
  227         }
  228 
  229         return (0);
  230 }
  231 
  232 static int
  233 lio_set_tso6(struct ifnet *ifp)
  234 {
  235         struct lio      *lio = if_getsoftc(ifp);
  236 
  237         if (if_getcapabilities(ifp) & IFCAP_TSO6) {
  238                 if_togglecapenable(ifp, IFCAP_TSO6);
  239                 if (if_getcapenable(ifp) & IFCAP_TSO6)
  240                         if_sethwassistbits(ifp, CSUM_IP6_TSO, 0);
  241                 else
  242                         if_sethwassistbits(ifp, 0, CSUM_IP6_TSO);
  243         } else {
  244                 lio_dev_info(lio->oct_dev, "TSO6 capability not supported\n");
  245                 return (EINVAL);
  246         }
  247 
  248         return (0);
  249 }
  250 
  251 static int
  252 lio_set_rx_csum(struct ifnet *ifp, uint32_t data)
  253 {
  254         struct lio      *lio = if_getsoftc(ifp);
  255         int     ret = 0;
  256 
  257         if (if_getcapabilities(ifp) & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) {
  258                 if_togglecapenable(ifp, (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6));
  259 
  260                 if (data) {
  261                         /* LRO requires RXCSUM */
  262                         if ((if_getcapabilities(ifp) & IFCAP_LRO) &&
  263                             (if_getcapenable(ifp) & IFCAP_LRO)) {
  264                                 ret = lio_set_feature(ifp, LIO_CMD_LRO_DISABLE,
  265                                                       LIO_LROIPV4 |
  266                                                       LIO_LROIPV6);
  267                                 if_togglecapenable(ifp, IFCAP_LRO);
  268                         }
  269                 }
  270         } else {
  271                 lio_dev_info(lio->oct_dev, "Rx checksum offload capability not supported\n");
  272                 return (ENODEV);
  273         }
  274 
  275         return ((ret) ? EINVAL : 0);
  276 }
  277 
  278 static int
  279 lio_set_lro(struct ifnet *ifp)
  280 {
  281         struct lio      *lio = if_getsoftc(ifp);
  282         int     ret = 0;
  283 
  284         if (!(if_getcapabilities(ifp) & IFCAP_LRO)) {
  285                 lio_dev_info(lio->oct_dev, "LRO capability not supported\n");
  286                 return (ENODEV);
  287         }
  288 
  289         if ((!(if_getcapenable(ifp) & IFCAP_LRO)) &&
  290             (if_getcapenable(ifp) & IFCAP_RXCSUM) &&
  291             (if_getcapenable(ifp) & IFCAP_RXCSUM_IPV6)) {
  292                 if_togglecapenable(ifp, IFCAP_LRO);
  293 
  294                 if (lio_hwlro)
  295                         ret = lio_set_feature(ifp, LIO_CMD_LRO_ENABLE, LIO_LROIPV4 |
  296                                               LIO_LROIPV6);
  297 
  298         } else if (if_getcapenable(ifp) & IFCAP_LRO) {
  299                 if_togglecapenable(ifp, IFCAP_LRO);
  300 
  301                 if (lio_hwlro)
  302                         ret = lio_set_feature(ifp, LIO_CMD_LRO_DISABLE, LIO_LROIPV4 |
  303                                               LIO_LROIPV6);
  304         } else
  305                 lio_dev_info(lio->oct_dev, "LRO requires RXCSUM");
  306 
  307         return ((ret) ? EINVAL : 0);
  308 }
  309 
  310 static void
  311 lio_mtu_ctl_callback(struct octeon_device *oct, uint32_t status, void *buf)
  312 {
  313         struct lio_soft_command *sc = buf;
  314         volatile int            *mtu_sc_ctx;
  315 
  316         mtu_sc_ctx = sc->ctxptr;
  317 
  318         if (status) {
  319                 lio_dev_err(oct, "MTU updation ctl instruction failed. Status: %llx\n",
  320                             LIO_CAST64(status));
  321                 *mtu_sc_ctx = -1;
  322                 /*
  323                  * This barrier is required to be sure that the
  324                  * response has been written fully.
  325                  */
  326                 wmb();
  327                 return;
  328         }
  329 
  330         *mtu_sc_ctx = 1;
  331 
  332         /*
  333          * This barrier is required to be sure that the response has been
  334          * written fully.
  335          */
  336         wmb();
  337 }
  338 
  339 /* @param ifp is network device */
  340 static int
  341 lio_change_mtu(struct ifnet *ifp, int new_mtu)
  342 {
  343         struct lio              *lio = if_getsoftc(ifp);
  344         struct octeon_device    *oct = lio->oct_dev;
  345         struct lio_soft_command *sc;
  346         union octeon_cmd        *ncmd;
  347         volatile int            *mtu_sc_ctx;
  348         int     retval = 0;
  349 
  350         if (lio->mtu == new_mtu)
  351                 return (0);
  352 
  353         /*
  354          * Limit the MTU to make sure the ethernet packets are between
  355          * LIO_MIN_MTU_SIZE bytes and LIO_MAX_MTU_SIZE bytes
  356          */
  357         if ((new_mtu < LIO_MIN_MTU_SIZE) || (new_mtu > LIO_MAX_MTU_SIZE)) {
  358                 lio_dev_err(oct, "Invalid MTU: %d\n", new_mtu);
  359                 lio_dev_err(oct, "Valid range %d and %d\n",
  360                             LIO_MIN_MTU_SIZE, LIO_MAX_MTU_SIZE);
  361                 return (EINVAL);
  362         }
  363 
  364         sc = lio_alloc_soft_command(oct, OCTEON_CMD_SIZE, 16,
  365                                     sizeof(*mtu_sc_ctx));
  366         if (sc == NULL)
  367                 return (ENOMEM);
  368 
  369         ncmd = (union octeon_cmd *)sc->virtdptr;
  370         mtu_sc_ctx = sc->ctxptr;
  371 
  372         *mtu_sc_ctx = 0;
  373 
  374         ncmd->cmd64 = 0;
  375         ncmd->s.cmd = LIO_CMD_CHANGE_MTU;
  376         ncmd->s.param1 = new_mtu;
  377 
  378         lio_swap_8B_data((uint64_t *)ncmd, (OCTEON_CMD_SIZE >> 3));
  379 
  380         sc->iq_no = lio->linfo.txpciq[0].s.q_no;
  381 
  382         lio_prepare_soft_command(oct, sc, LIO_OPCODE_NIC,
  383                                  LIO_OPCODE_NIC_CMD, 0, 0, 0);
  384 
  385         sc->callback = lio_mtu_ctl_callback;
  386         sc->callback_arg = sc;
  387         sc->wait_time = 5000;
  388 
  389         retval = lio_send_soft_command(oct, sc);
  390         if (retval == LIO_IQ_SEND_FAILED) {
  391                 lio_dev_info(oct,
  392                              "Failed to send MTU update Control message\n");
  393                 retval = EBUSY;
  394                 goto mtu_updation_failed;
  395         }
  396 
  397         /*
  398          * Sleep on a wait queue till the cond flag indicates that the
  399          * response arrived or timed-out.
  400          */
  401         lio_sleep_cond(oct, mtu_sc_ctx);
  402 
  403         if (*mtu_sc_ctx < 0) {
  404                 retval = EBUSY;
  405                 goto mtu_updation_failed;
  406         }
  407         lio_dev_info(oct, "MTU Changed from %d to %d\n", if_getmtu(ifp),
  408                      new_mtu);
  409         if_setmtu(ifp, new_mtu);
  410         lio->mtu = new_mtu;
  411         retval = 0;                     /*
  412                                          * this updation is make sure that LIO_IQ_SEND_STOP case
  413                                          * also success
  414                                          */
  415 
  416 mtu_updation_failed:
  417         lio_free_soft_command(oct, sc);
  418 
  419         return (retval);
  420 }
  421 
  422 /* @param ifp network device */
  423 int
  424 lio_set_mac(struct ifnet *ifp, uint8_t *p)
  425 {
  426         struct lio_ctrl_pkt     nctrl;
  427         struct lio              *lio = if_getsoftc(ifp);
  428         struct octeon_device    *oct = lio->oct_dev;
  429         int     ret = 0;
  430 
  431         if (!lio_is_valid_ether_addr(p))
  432                 return (EADDRNOTAVAIL);
  433 
  434         bzero(&nctrl, sizeof(struct lio_ctrl_pkt));
  435 
  436         nctrl.ncmd.cmd64 = 0;
  437         nctrl.ncmd.s.cmd = LIO_CMD_CHANGE_MACADDR;
  438         nctrl.ncmd.s.param1 = 0;
  439         nctrl.ncmd.s.more = 1;
  440         nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
  441         nctrl.lio = lio;
  442         nctrl.cb_fn = lio_ctrl_cmd_completion;
  443         nctrl.wait_time = 100;
  444 
  445         nctrl.udd[0] = 0;
  446         /* The MAC Address is presented in network byte order. */
  447         memcpy((uint8_t *)&nctrl.udd[0] + 2, p, ETHER_HDR_LEN);
  448 
  449         ret = lio_send_ctrl_pkt(lio->oct_dev, &nctrl);
  450         if (ret < 0) {
  451                 lio_dev_err(oct, "MAC Address change failed\n");
  452                 return (ENOMEM);
  453         }
  454 
  455         memcpy(((uint8_t *)&lio->linfo.hw_addr) + 2, p, ETHER_HDR_LEN);
  456 
  457         return (0);
  458 }
  459 
  460 /*
  461  * \brief Converts a mask based on ifp flags
  462  * @param ifp network device
  463  *
  464  * This routine generates a lio_ifflags mask from the ifp flags
  465  * received from the OS.
  466  */
  467 static inline enum lio_ifflags
  468 lio_get_new_flags(struct ifnet *ifp)
  469 {
  470         enum lio_ifflags f = LIO_IFFLAG_UNICAST;
  471 
  472         if (if_getflags(ifp) & IFF_PROMISC)
  473                 f |= LIO_IFFLAG_PROMISC;
  474 
  475         if (if_getflags(ifp) & IFF_ALLMULTI)
  476                 f |= LIO_IFFLAG_ALLMULTI;
  477 
  478         if (if_getflags(ifp) & IFF_MULTICAST) {
  479                 f |= LIO_IFFLAG_MULTICAST;
  480 
  481                 /*
  482                  * Accept all multicast addresses if there are more than we
  483                  * can handle
  484                  */
  485                 if (if_getamcount(ifp) > LIO_MAX_MULTICAST_ADDR)
  486                         f |= LIO_IFFLAG_ALLMULTI;
  487         }
  488         if (if_getflags(ifp) & IFF_BROADCAST)
  489                 f |= LIO_IFFLAG_BROADCAST;
  490 
  491         return (f);
  492 }
  493 
  494 static u_int
  495 lio_copy_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
  496 {
  497         uint64_t *mc = arg;
  498 
  499         if (cnt == LIO_MAX_MULTICAST_ADDR)
  500                 return (0);
  501 
  502         mc += cnt;
  503         *mc = 0;
  504         memcpy(((uint8_t *)mc) + 2, LLADDR(sdl), ETHER_ADDR_LEN);
  505         /* no need to swap bytes */
  506 
  507         return (1);
  508 }
  509 
  510 /* @param ifp network device */
  511 static int
  512 lio_set_mcast_list(struct ifnet *ifp)
  513 {
  514         struct lio              *lio = if_getsoftc(ifp);
  515         struct octeon_device    *oct = lio->oct_dev;
  516         struct lio_ctrl_pkt     nctrl;
  517         int     mc_count;
  518         int     ret;
  519 
  520         bzero(&nctrl, sizeof(struct lio_ctrl_pkt));
  521 
  522         /* Create a ctrl pkt command to be sent to core app. */
  523         nctrl.ncmd.cmd64 = 0;
  524         nctrl.ncmd.s.cmd = LIO_CMD_SET_MULTI_LIST;
  525         nctrl.ncmd.s.param1 = lio_get_new_flags(ifp);
  526         nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
  527         nctrl.lio = lio;
  528         nctrl.cb_fn = lio_ctrl_cmd_completion;
  529 
  530         /* copy all the addresses into the udd */
  531         mc_count = if_foreach_llmaddr(ifp, lio_copy_maddr, &nctrl.udd[0]);
  532 
  533         /*
  534          * Apparently, any activity in this call from the kernel has to
  535          * be atomic. So we won't wait for response.
  536          */
  537         nctrl.wait_time = 0;
  538         nctrl.ncmd.s.param2 = mc_count;
  539         nctrl.ncmd.s.more = mc_count;
  540 
  541         ret = lio_send_ctrl_pkt(lio->oct_dev, &nctrl);
  542         if (ret < 0) {
  543                 lio_dev_err(oct, "DEVFLAGS change failed in core (ret: 0x%x)\n",
  544                             ret);
  545         }
  546 
  547         return ((ret) ? EINVAL : 0);
  548 }

Cache object: 1b3c99eb467bebdeec80b1757e7ba346


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