1 /* net/core/xdp.c 2 * 3 * Copyright (c) 2017 Jesper Dangaard Brouer, Red Hat Inc. 4 * Released under terms in GPL version 2. See COPYING. 5 */ 6 #include <linux/types.h> 7 #include <linux/mm.h> 8 9 #include <net/xdp.h> 10 11 #define REG_STATE_NEW 0x0 12 #define REG_STATE_REGISTERED 0x1 13 #define REG_STATE_UNREGISTERED 0x2 14 #define REG_STATE_UNUSED 0x3 15 16 void xdp_rxq_info_unreg(struct xdp_rxq_info *xdp_rxq) 17 { 18 /* Simplify driver cleanup code paths, allow unreg "unused" */ 19 if (xdp_rxq->reg_state == REG_STATE_UNUSED) 20 return; 21 22 WARN(!(xdp_rxq->reg_state == REG_STATE_REGISTERED), "Driver BUG"); 23 24 xdp_rxq->reg_state = REG_STATE_UNREGISTERED; 25 xdp_rxq->dev = NULL; 26 } 27 EXPORT_SYMBOL_GPL(xdp_rxq_info_unreg); 28 29 static void xdp_rxq_info_init(struct xdp_rxq_info *xdp_rxq) 30 { 31 memset(xdp_rxq, 0, sizeof(*xdp_rxq)); 32 } 33 34 /* Returns 0 on success, negative on failure */ 35 int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq, 36 struct net_device *dev, u32 queue_index) 37 { 38 if (xdp_rxq->reg_state == REG_STATE_UNUSED) { 39 WARN(1, "Driver promised not to register this"); 40 return -EINVAL; 41 } 42 43 if (xdp_rxq->reg_state == REG_STATE_REGISTERED) { 44 WARN(1, "Missing unregister, handled but fix driver"); 45 xdp_rxq_info_unreg(xdp_rxq); 46 } 47 48 if (!dev) { 49 WARN(1, "Missing net_device from driver"); 50 return -ENODEV; 51 } 52 53 /* State either UNREGISTERED or NEW */ 54 xdp_rxq_info_init(xdp_rxq); 55 xdp_rxq->dev = dev; 56 xdp_rxq->queue_index = queue_index; 57 58 xdp_rxq->reg_state = REG_STATE_REGISTERED; 59 return 0; 60 } 61 EXPORT_SYMBOL_GPL(xdp_rxq_info_reg); 62 63 void xdp_rxq_info_unused(struct xdp_rxq_info *xdp_rxq) 64 { 65 xdp_rxq->reg_state = REG_STATE_UNUSED; 66 } 67 EXPORT_SYMBOL_GPL(xdp_rxq_info_unused); 68 69 bool xdp_rxq_info_is_reg(struct xdp_rxq_info *xdp_rxq) 70 { 71 return (xdp_rxq->reg_state == REG_STATE_REGISTERED); 72 } 73 EXPORT_SYMBOL_GPL(xdp_rxq_info_is_reg); 74