^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright Gavin Shan, IBM Corporation 2016.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <net/ncsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "ncsi-pkt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "ncsi-netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) unsigned short payload)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct ncsi_rsp_pkt_hdr *h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) u32 checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) __be32 *pchecksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* Check NCSI packet header. We don't need validate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * the packet type, which should have been checked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * before calling this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) h = (struct ncsi_rsp_pkt_hdr *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (h->common.revision != NCSI_PKT_REVISION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) netdev_dbg(nr->ndp->ndev.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) "NCSI: unsupported header revision\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (ntohs(h->common.length) != payload) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) netdev_dbg(nr->ndp->ndev.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) "NCSI: payload length mismatched\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Check on code and reason */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (ntohs(h->code) != NCSI_PKT_RSP_C_COMPLETED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ntohs(h->reason) != NCSI_PKT_RSP_R_NO_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) netdev_dbg(nr->ndp->ndev.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) "NCSI: non zero response/reason code %04xh, %04xh\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ntohs(h->code), ntohs(h->reason));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Validate checksum, which might be zeroes if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * sender doesn't support checksum according to NCSI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * specification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) pchecksum = (__be32 *)((void *)(h + 1) + ALIGN(payload, 4) - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (ntohl(*pchecksum) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) checksum = ncsi_calculate_checksum((unsigned char *)h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) sizeof(*h) + payload - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (*pchecksum != htonl(checksum)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) netdev_dbg(nr->ndp->ndev.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) "NCSI: checksum mismatched; recd: %08x calc: %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *pchecksum, htonl(checksum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static int ncsi_rsp_handler_cis(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct ncsi_package *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned char id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, &np, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (!nc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (ndp->flags & NCSI_DEV_PROBED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) id = NCSI_CHANNEL_INDEX(rsp->rsp.common.channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) nc = ncsi_add_channel(np, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return nc ? 0 : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static int ncsi_rsp_handler_sp(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct ncsi_package *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned char id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Add the package if it's not existing. Otherwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * to change the state of its child channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) &np, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (ndp->flags & NCSI_DEV_PROBED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) id = NCSI_PACKAGE_INDEX(rsp->rsp.common.channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) np = ncsi_add_package(ndp, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int ncsi_rsp_handler_dp(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct ncsi_package *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* Find the package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) &np, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* Change state of all channels attached to the package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) NCSI_FOR_EACH_CHANNEL(np, nc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) spin_lock_irqsave(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) nc->state = NCSI_CHANNEL_INACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) spin_unlock_irqrestore(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static int ncsi_rsp_handler_ec(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ncm = &nc->modes[NCSI_MODE_ENABLE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ncm->enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int ncsi_rsp_handler_dc(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ret = ncsi_validate_rsp_pkt(nr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ncm = &nc->modes[NCSI_MODE_ENABLE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (!ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ncm->enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static int ncsi_rsp_handler_rc(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Update state for the specified channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) spin_lock_irqsave(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) nc->state = NCSI_CHANNEL_INACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) spin_unlock_irqrestore(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int ncsi_rsp_handler_ecnt(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ncm->enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int ncsi_rsp_handler_dcnt(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (!ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ncm->enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int ncsi_rsp_handler_ae(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct ncsi_cmd_ae_pkt *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* Check if the AEN has been enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ncm = &nc->modes[NCSI_MODE_AEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* Update to AEN configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) cmd = (struct ncsi_cmd_ae_pkt *)skb_network_header(nr->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ncm->enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ncm->data[0] = cmd->mc_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ncm->data[1] = ntohl(cmd->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static int ncsi_rsp_handler_sl(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct ncsi_cmd_sl_pkt *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) cmd = (struct ncsi_cmd_sl_pkt *)skb_network_header(nr->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ncm = &nc->modes[NCSI_MODE_LINK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ncm->data[0] = ntohl(cmd->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ncm->data[1] = ntohl(cmd->oem_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static int ncsi_rsp_handler_gls(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct ncsi_rsp_gls_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) rsp = (struct ncsi_rsp_gls_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ncm = &nc->modes[NCSI_MODE_LINK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ncm->data[2] = ntohl(rsp->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ncm->data[3] = ntohl(rsp->other);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ncm->data[4] = ntohl(rsp->oem_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (nr->flags & NCSI_REQ_FLAG_EVENT_DRIVEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* Reset the channel monitor if it has been enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) spin_lock_irqsave(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) nc->monitor.state = NCSI_CHANNEL_MONITOR_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) spin_unlock_irqrestore(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int ncsi_rsp_handler_svf(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct ncsi_cmd_svf_pkt *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct ncsi_channel_vlan_filter *ncf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) void *bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) cmd = (struct ncsi_cmd_svf_pkt *)skb_network_header(nr->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ncf = &nc->vlan_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (cmd->index == 0 || cmd->index > ncf->n_vids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* Add or remove the VLAN filter. Remember HW indexes from 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) spin_lock_irqsave(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) bitmap = &ncf->bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (!(cmd->enable & 0x1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (test_and_clear_bit(cmd->index - 1, bitmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ncf->vids[cmd->index - 1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) set_bit(cmd->index - 1, bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ncf->vids[cmd->index - 1] = ntohs(cmd->vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) spin_unlock_irqrestore(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static int ncsi_rsp_handler_ev(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct ncsi_cmd_ev_pkt *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* Check if VLAN mode has been enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ncm = &nc->modes[NCSI_MODE_VLAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* Update to VLAN mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) cmd = (struct ncsi_cmd_ev_pkt *)skb_network_header(nr->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ncm->enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ncm->data[0] = ntohl(cmd->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static int ncsi_rsp_handler_dv(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* Check if VLAN mode has been enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ncm = &nc->modes[NCSI_MODE_VLAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (!ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* Update to VLAN mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ncm->enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static int ncsi_rsp_handler_sma(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct ncsi_cmd_sma_pkt *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct ncsi_channel_mac_filter *ncf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) void *bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) bool enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /* According to NCSI spec 1.01, the mixed filter table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * isn't supported yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) cmd = (struct ncsi_cmd_sma_pkt *)skb_network_header(nr->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) enabled = cmd->at_e & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ncf = &nc->mac_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) bitmap = &ncf->bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (cmd->index == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) cmd->index > ncf->n_uc + ncf->n_mc + ncf->n_mixed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) index = (cmd->index - 1) * ETH_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) spin_lock_irqsave(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) set_bit(cmd->index - 1, bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) memcpy(&ncf->addrs[index], cmd->mac, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) clear_bit(cmd->index - 1, bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) eth_zero_addr(&ncf->addrs[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) spin_unlock_irqrestore(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static int ncsi_rsp_handler_ebf(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct ncsi_cmd_ebf_pkt *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /* Find the package and channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* Check if broadcast filter has been enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ncm = &nc->modes[NCSI_MODE_BC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /* Update to broadcast filter mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) cmd = (struct ncsi_cmd_ebf_pkt *)skb_network_header(nr->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ncm->enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ncm->data[0] = ntohl(cmd->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static int ncsi_rsp_handler_dbf(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* Check if broadcast filter isn't enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ncm = &nc->modes[NCSI_MODE_BC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (!ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) /* Update to broadcast filter mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ncm->enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) ncm->data[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static int ncsi_rsp_handler_egmf(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct ncsi_cmd_egmf_pkt *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* Find the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* Check if multicast filter has been enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ncm = &nc->modes[NCSI_MODE_MC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /* Update to multicast filter mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) cmd = (struct ncsi_cmd_egmf_pkt *)skb_network_header(nr->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) ncm->enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ncm->data[0] = ntohl(cmd->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static int ncsi_rsp_handler_dgmf(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* Check if multicast filter has been enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) ncm = &nc->modes[NCSI_MODE_MC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (!ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* Update to multicast filter mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ncm->enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ncm->data[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static int ncsi_rsp_handler_snfc(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct ncsi_cmd_snfc_pkt *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct ncsi_channel_mode *ncm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* Find the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* Check if flow control has been enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ncm = &nc->modes[NCSI_MODE_FC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (ncm->enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) /* Update to flow control mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) cmd = (struct ncsi_cmd_snfc_pkt *)skb_network_header(nr->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ncm->enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ncm->data[0] = cmd->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /* Response handler for Mellanox command Get Mac Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static int ncsi_rsp_handler_oem_mlx_gma(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct net_device *ndev = ndp->ndev.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) const struct net_device_ops *ops = ndev->netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct ncsi_rsp_oem_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct sockaddr saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /* Get the response header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) saddr.sa_family = ndev->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) memcpy(saddr.sa_data, &rsp->data[MLX_MAC_ADDR_OFFSET], ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /* Set the flag for GMA command which should only be called once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ndp->gma_flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ret = ops->ndo_set_mac_address(ndev, &saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* Response handler for Mellanox card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static int ncsi_rsp_handler_oem_mlx(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct ncsi_rsp_oem_mlx_pkt *mlx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct ncsi_rsp_oem_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* Get the response header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) mlx = (struct ncsi_rsp_oem_mlx_pkt *)(rsp->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (mlx->cmd == NCSI_OEM_MLX_CMD_GMA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) mlx->param == NCSI_OEM_MLX_CMD_GMA_PARAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return ncsi_rsp_handler_oem_mlx_gma(nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /* Response handler for Broadcom command Get Mac Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static int ncsi_rsp_handler_oem_bcm_gma(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct net_device *ndev = ndp->ndev.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) const struct net_device_ops *ops = ndev->netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct ncsi_rsp_oem_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct sockaddr saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* Get the response header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) saddr.sa_family = ndev->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) memcpy(saddr.sa_data, &rsp->data[BCM_MAC_ADDR_OFFSET], ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /* Increase mac address by 1 for BMC's address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) eth_addr_inc((u8 *)saddr.sa_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (!is_valid_ether_addr((const u8 *)saddr.sa_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /* Set the flag for GMA command which should only be called once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) ndp->gma_flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ret = ops->ndo_set_mac_address(ndev, &saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /* Response handler for Broadcom card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static int ncsi_rsp_handler_oem_bcm(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct ncsi_rsp_oem_bcm_pkt *bcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct ncsi_rsp_oem_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /* Get the response header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) bcm = (struct ncsi_rsp_oem_bcm_pkt *)(rsp->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (bcm->type == NCSI_OEM_BCM_CMD_GMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return ncsi_rsp_handler_oem_bcm_gma(nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static struct ncsi_rsp_oem_handler {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) unsigned int mfr_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) int (*handler)(struct ncsi_request *nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) } ncsi_rsp_oem_handlers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) { NCSI_OEM_MFR_MLX_ID, ncsi_rsp_handler_oem_mlx },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) { NCSI_OEM_MFR_BCM_ID, ncsi_rsp_handler_oem_bcm }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /* Response handler for OEM command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static int ncsi_rsp_handler_oem(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct ncsi_rsp_oem_handler *nrh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct ncsi_rsp_oem_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) unsigned int mfr_id, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* Get the response header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) mfr_id = ntohl(rsp->mfr_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /* Check for manufacturer id and Find the handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) for (i = 0; i < ARRAY_SIZE(ncsi_rsp_oem_handlers); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (ncsi_rsp_oem_handlers[i].mfr_id == mfr_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (ncsi_rsp_oem_handlers[i].handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) nrh = &ncsi_rsp_oem_handlers[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) nrh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (!nrh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) netdev_err(nr->ndp->ndev.dev, "Received unrecognized OEM packet with MFR-ID (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) mfr_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) /* Process the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return nrh->handler(nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static int ncsi_rsp_handler_gvi(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct ncsi_rsp_gvi_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct ncsi_channel_version *ncv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /* Find the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) rsp = (struct ncsi_rsp_gvi_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /* Update to channel's version info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ncv = &nc->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) ncv->version = ntohl(rsp->ncsi_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) ncv->alpha2 = rsp->alpha2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) memcpy(ncv->fw_name, rsp->fw_name, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) ncv->fw_version = ntohl(rsp->fw_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) for (i = 0; i < ARRAY_SIZE(ncv->pci_ids); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ncv->pci_ids[i] = ntohs(rsp->pci_ids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ncv->mf_id = ntohl(rsp->mf_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct ncsi_rsp_gc_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /* Find the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /* Update channel's capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) nc->caps[NCSI_CAP_GENERIC].cap = ntohl(rsp->cap) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) NCSI_CAP_GENERIC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) nc->caps[NCSI_CAP_BC].cap = ntohl(rsp->bc_cap) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) NCSI_CAP_BC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) nc->caps[NCSI_CAP_MC].cap = ntohl(rsp->mc_cap) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) NCSI_CAP_MC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) nc->caps[NCSI_CAP_BUFFER].cap = ntohl(rsp->buf_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) nc->caps[NCSI_CAP_AEN].cap = ntohl(rsp->aen_cap) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) NCSI_CAP_AEN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) nc->caps[NCSI_CAP_VLAN].cap = rsp->vlan_mode &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) NCSI_CAP_VLAN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) size = (rsp->uc_cnt + rsp->mc_cnt + rsp->mixed_cnt) * ETH_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) nc->mac_filter.addrs = kzalloc(size, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (!nc->mac_filter.addrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) nc->mac_filter.n_uc = rsp->uc_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) nc->mac_filter.n_mc = rsp->mc_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) nc->mac_filter.n_mixed = rsp->mixed_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) nc->vlan_filter.vids = kcalloc(rsp->vlan_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) sizeof(*nc->vlan_filter.vids),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (!nc->vlan_filter.vids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /* Set VLAN filters active so they are cleared in the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * configuration state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) nc->vlan_filter.bitmap = U64_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) nc->vlan_filter.n_vids = rsp->vlan_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct ncsi_channel_vlan_filter *ncvf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct ncsi_channel_mac_filter *ncmf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct ncsi_rsp_gp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) unsigned short enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) unsigned char *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) void *bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /* Find the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) rsp = (struct ncsi_rsp_gp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) /* Modes with explicit enabled indications */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (ntohl(rsp->valid_modes) & 0x1) { /* BC filter mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) nc->modes[NCSI_MODE_BC].enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) nc->modes[NCSI_MODE_BC].data[0] = ntohl(rsp->bc_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (ntohl(rsp->valid_modes) & 0x2) /* Channel enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) nc->modes[NCSI_MODE_ENABLE].enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (ntohl(rsp->valid_modes) & 0x4) /* Channel Tx enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) nc->modes[NCSI_MODE_TX_ENABLE].enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (ntohl(rsp->valid_modes) & 0x8) /* MC filter mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) nc->modes[NCSI_MODE_MC].enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* Modes without explicit enabled indications */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) nc->modes[NCSI_MODE_LINK].enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) nc->modes[NCSI_MODE_LINK].data[0] = ntohl(rsp->link_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) nc->modes[NCSI_MODE_VLAN].enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) nc->modes[NCSI_MODE_VLAN].data[0] = rsp->vlan_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) nc->modes[NCSI_MODE_FC].enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) nc->modes[NCSI_MODE_FC].data[0] = rsp->fc_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) nc->modes[NCSI_MODE_AEN].enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) nc->modes[NCSI_MODE_AEN].data[0] = ntohl(rsp->aen_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) /* MAC addresses filter table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) pdata = (unsigned char *)rsp + 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) enable = rsp->mac_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) ncmf = &nc->mac_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) spin_lock_irqsave(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) bitmap = &ncmf->bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) for (i = 0; i < rsp->mac_cnt; i++, pdata += 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (!(enable & (0x1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) clear_bit(i, bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) set_bit(i, bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) memcpy(&ncmf->addrs[i * ETH_ALEN], pdata, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) spin_unlock_irqrestore(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) /* VLAN filter table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) enable = ntohs(rsp->vlan_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ncvf = &nc->vlan_filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) bitmap = &ncvf->bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) spin_lock_irqsave(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) for (i = 0; i < rsp->vlan_cnt; i++, pdata += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!(enable & (0x1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) clear_bit(i, bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) set_bit(i, bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ncvf->vids[i] = ntohs(*(__be16 *)pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) spin_unlock_irqrestore(&nc->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static int ncsi_rsp_handler_gcps(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct ncsi_rsp_gcps_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) struct ncsi_channel_stats *ncs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) /* Find the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) rsp = (struct ncsi_rsp_gcps_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) /* Update HNC's statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) ncs = &nc->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) ncs->hnc_cnt_hi = ntohl(rsp->cnt_hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) ncs->hnc_cnt_lo = ntohl(rsp->cnt_lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) ncs->hnc_rx_bytes = ntohl(rsp->rx_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ncs->hnc_tx_bytes = ntohl(rsp->tx_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ncs->hnc_rx_uc_pkts = ntohl(rsp->rx_uc_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) ncs->hnc_rx_mc_pkts = ntohl(rsp->rx_mc_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ncs->hnc_rx_bc_pkts = ntohl(rsp->rx_bc_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) ncs->hnc_tx_uc_pkts = ntohl(rsp->tx_uc_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) ncs->hnc_tx_mc_pkts = ntohl(rsp->tx_mc_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) ncs->hnc_tx_bc_pkts = ntohl(rsp->tx_bc_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) ncs->hnc_fcs_err = ntohl(rsp->fcs_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ncs->hnc_align_err = ntohl(rsp->align_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) ncs->hnc_false_carrier = ntohl(rsp->false_carrier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ncs->hnc_runt_pkts = ntohl(rsp->runt_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) ncs->hnc_jabber_pkts = ntohl(rsp->jabber_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) ncs->hnc_rx_pause_xon = ntohl(rsp->rx_pause_xon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) ncs->hnc_rx_pause_xoff = ntohl(rsp->rx_pause_xoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) ncs->hnc_tx_pause_xon = ntohl(rsp->tx_pause_xon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) ncs->hnc_tx_pause_xoff = ntohl(rsp->tx_pause_xoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) ncs->hnc_tx_s_collision = ntohl(rsp->tx_s_collision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ncs->hnc_tx_m_collision = ntohl(rsp->tx_m_collision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) ncs->hnc_l_collision = ntohl(rsp->l_collision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) ncs->hnc_e_collision = ntohl(rsp->e_collision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) ncs->hnc_rx_ctl_frames = ntohl(rsp->rx_ctl_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) ncs->hnc_rx_64_frames = ntohl(rsp->rx_64_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) ncs->hnc_rx_127_frames = ntohl(rsp->rx_127_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) ncs->hnc_rx_255_frames = ntohl(rsp->rx_255_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ncs->hnc_rx_511_frames = ntohl(rsp->rx_511_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ncs->hnc_rx_1023_frames = ntohl(rsp->rx_1023_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) ncs->hnc_rx_1522_frames = ntohl(rsp->rx_1522_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) ncs->hnc_rx_9022_frames = ntohl(rsp->rx_9022_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) ncs->hnc_tx_64_frames = ntohl(rsp->tx_64_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ncs->hnc_tx_127_frames = ntohl(rsp->tx_127_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) ncs->hnc_tx_255_frames = ntohl(rsp->tx_255_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ncs->hnc_tx_511_frames = ntohl(rsp->tx_511_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) ncs->hnc_tx_1023_frames = ntohl(rsp->tx_1023_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) ncs->hnc_tx_1522_frames = ntohl(rsp->tx_1522_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) ncs->hnc_tx_9022_frames = ntohl(rsp->tx_9022_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ncs->hnc_rx_valid_bytes = ntohl(rsp->rx_valid_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) ncs->hnc_rx_runt_pkts = ntohl(rsp->rx_runt_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) ncs->hnc_rx_jabber_pkts = ntohl(rsp->rx_jabber_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) static int ncsi_rsp_handler_gns(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) struct ncsi_rsp_gns_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) struct ncsi_channel_stats *ncs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) /* Find the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) rsp = (struct ncsi_rsp_gns_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) /* Update HNC's statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) ncs = &nc->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) ncs->ncsi_rx_cmds = ntohl(rsp->rx_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) ncs->ncsi_dropped_cmds = ntohl(rsp->dropped_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) ncs->ncsi_cmd_type_errs = ntohl(rsp->cmd_type_errs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) ncs->ncsi_cmd_csum_errs = ntohl(rsp->cmd_csum_errs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) ncs->ncsi_rx_pkts = ntohl(rsp->rx_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) ncs->ncsi_tx_pkts = ntohl(rsp->tx_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) ncs->ncsi_tx_aen_pkts = ntohl(rsp->tx_aen_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) static int ncsi_rsp_handler_gnpts(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) struct ncsi_rsp_gnpts_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) struct ncsi_channel_stats *ncs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) /* Find the channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) rsp = (struct ncsi_rsp_gnpts_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) NULL, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) if (!nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /* Update HNC's statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) ncs = &nc->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) ncs->pt_tx_pkts = ntohl(rsp->tx_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ncs->pt_tx_dropped = ntohl(rsp->tx_dropped);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ncs->pt_tx_channel_err = ntohl(rsp->tx_channel_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) ncs->pt_tx_us_err = ntohl(rsp->tx_us_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ncs->pt_rx_pkts = ntohl(rsp->rx_pkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) ncs->pt_rx_dropped = ntohl(rsp->rx_dropped);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) ncs->pt_rx_channel_err = ntohl(rsp->rx_channel_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) ncs->pt_rx_us_err = ntohl(rsp->rx_us_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ncs->pt_rx_os_err = ntohl(rsp->rx_os_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) static int ncsi_rsp_handler_gps(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) struct ncsi_rsp_gps_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) struct ncsi_package *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /* Find the package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) rsp = (struct ncsi_rsp_gps_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) &np, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static int ncsi_rsp_handler_gpuuid(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct ncsi_rsp_gpuuid_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) struct ncsi_package *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /* Find the package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) rsp = (struct ncsi_rsp_gpuuid_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) &np, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) memcpy(np->uuid, rsp->uuid, sizeof(rsp->uuid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static int ncsi_rsp_handler_pldm(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static int ncsi_rsp_handler_netlink(struct ncsi_request *nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) struct ncsi_dev_priv *ndp = nr->ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct ncsi_rsp_pkt *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) struct ncsi_package *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) struct ncsi_channel *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /* Find the package */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) &np, &nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) ret = ncsi_send_netlink_rsp(nr, np, nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static struct ncsi_rsp_handler {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) unsigned char type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) int payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) int (*handler)(struct ncsi_request *nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) } ncsi_rsp_handlers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) { NCSI_PKT_RSP_CIS, 4, ncsi_rsp_handler_cis },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) { NCSI_PKT_RSP_SP, 4, ncsi_rsp_handler_sp },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) { NCSI_PKT_RSP_DP, 4, ncsi_rsp_handler_dp },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) { NCSI_PKT_RSP_EC, 4, ncsi_rsp_handler_ec },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) { NCSI_PKT_RSP_DC, 4, ncsi_rsp_handler_dc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) { NCSI_PKT_RSP_RC, 4, ncsi_rsp_handler_rc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) { NCSI_PKT_RSP_ECNT, 4, ncsi_rsp_handler_ecnt },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) { NCSI_PKT_RSP_DCNT, 4, ncsi_rsp_handler_dcnt },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) { NCSI_PKT_RSP_AE, 4, ncsi_rsp_handler_ae },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) { NCSI_PKT_RSP_SL, 4, ncsi_rsp_handler_sl },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) { NCSI_PKT_RSP_GLS, 16, ncsi_rsp_handler_gls },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) { NCSI_PKT_RSP_SVF, 4, ncsi_rsp_handler_svf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) { NCSI_PKT_RSP_EV, 4, ncsi_rsp_handler_ev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) { NCSI_PKT_RSP_DV, 4, ncsi_rsp_handler_dv },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) { NCSI_PKT_RSP_SMA, 4, ncsi_rsp_handler_sma },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) { NCSI_PKT_RSP_EBF, 4, ncsi_rsp_handler_ebf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) { NCSI_PKT_RSP_DBF, 4, ncsi_rsp_handler_dbf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) { NCSI_PKT_RSP_EGMF, 4, ncsi_rsp_handler_egmf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) { NCSI_PKT_RSP_DGMF, 4, ncsi_rsp_handler_dgmf },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) { NCSI_PKT_RSP_SNFC, 4, ncsi_rsp_handler_snfc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) { NCSI_PKT_RSP_GVI, 40, ncsi_rsp_handler_gvi },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) { NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) { NCSI_PKT_RSP_GP, -1, ncsi_rsp_handler_gp },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) { NCSI_PKT_RSP_GCPS, 204, ncsi_rsp_handler_gcps },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) { NCSI_PKT_RSP_GNS, 32, ncsi_rsp_handler_gns },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) { NCSI_PKT_RSP_GNPTS, 48, ncsi_rsp_handler_gnpts },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) { NCSI_PKT_RSP_GPS, 8, ncsi_rsp_handler_gps },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) { NCSI_PKT_RSP_OEM, -1, ncsi_rsp_handler_oem },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) { NCSI_PKT_RSP_PLDM, -1, ncsi_rsp_handler_pldm },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) { NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) { NCSI_PKT_RSP_QPNPR, -1, ncsi_rsp_handler_pldm },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) { NCSI_PKT_RSP_SNPR, -1, ncsi_rsp_handler_pldm }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) struct packet_type *pt, struct net_device *orig_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) struct ncsi_rsp_handler *nrh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) struct ncsi_dev *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) struct ncsi_dev_priv *ndp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) struct ncsi_request *nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) struct ncsi_pkt_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) int payload, i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) /* Find the NCSI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) nd = ncsi_find_dev(orig_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (!ndp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /* Check if it is AEN packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) hdr = (struct ncsi_pkt_hdr *)skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (hdr->type == NCSI_PKT_AEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return ncsi_aen_handler(ndp, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) /* Find the handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) for (i = 0; i < ARRAY_SIZE(ncsi_rsp_handlers); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (ncsi_rsp_handlers[i].type == hdr->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (ncsi_rsp_handlers[i].handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) nrh = &ncsi_rsp_handlers[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) nrh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (!nrh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) netdev_err(nd->dev, "Received unrecognized packet (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) hdr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) /* Associate with the request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) spin_lock_irqsave(&ndp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) nr = &ndp->requests[hdr->id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (!nr->used) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) spin_unlock_irqrestore(&ndp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) nr->rsp = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if (!nr->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) spin_unlock_irqrestore(&ndp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /* Validate the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) spin_unlock_irqrestore(&ndp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) payload = nrh->payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (payload < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) payload = ntohs(hdr->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) ret = ncsi_validate_rsp_pkt(nr, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) netdev_warn(ndp->ndev.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) "NCSI: 'bad' packet ignored for type 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) hdr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (ret == -EPERM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) goto out_netlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) ncsi_send_netlink_err(ndp->ndev.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) nr->snd_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) nr->snd_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) &nr->nlhdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) /* Process the packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ret = nrh->handler(nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) netdev_err(ndp->ndev.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) "NCSI: Handler for packet type 0x%x returned %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) hdr->type, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) out_netlink:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) ret = ncsi_rsp_handler_netlink(nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) netdev_err(ndp->ndev.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) "NCSI: Netlink handler for packet type 0x%x returned %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) hdr->type, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) ncsi_free_request(nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }