^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * File: pep-gprs.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * GPRS over Phonet pipe end point socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2008 Nokia Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Author: Rémi Denis-Courmont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/if_phonet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <net/tcp_states.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/phonet/gprs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define GPRS_DEFAULT_MTU 1400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct gprs_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) void (*old_state_change)(struct sock *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) void (*old_data_ready)(struct sock *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) void (*old_write_space)(struct sock *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static __be16 gprs_type_trans(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) const u8 *pvfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u8 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) pvfc = skb_header_pointer(skb, 0, 1, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (!pvfc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return htons(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Look at IP version field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) switch (*pvfc >> 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return htons(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return htons(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static void gprs_writeable(struct gprs_dev *gp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct net_device *dev = gp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (pep_writeable(gp->sk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Socket callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static void gprs_state_change(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct gprs_dev *gp = sk->sk_user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (sk->sk_state == TCP_CLOSE_WAIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct net_device *dev = gp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static int gprs_recv(struct gprs_dev *gp, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct net_device *dev = gp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) __be16 protocol = gprs_type_trans(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (!protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (skb_headroom(skb) & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct sk_buff *rskb, *fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int flen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* Phonet Pipe data header may be misaligned (3 bytes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * so wrap the IP packet as a single fragment of an head-less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * socket buffer. The network stack will pull what it needs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * but at least, the whole IP payload is not memcpy'd. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) rskb = netdev_alloc_skb(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (!rskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) skb_shinfo(rskb)->frag_list = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) rskb->len += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) rskb->data_len += rskb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) rskb->truesize += rskb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Avoid nested fragments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) skb_walk_frags(skb, fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) flen += fs->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) skb->next = skb_shinfo(skb)->frag_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) skb_frag_list_init(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) skb->len -= flen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) skb->data_len -= flen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) skb->truesize -= flen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) skb = rskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) skb->protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (likely(dev->flags & IFF_UP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) dev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) dev->stats.rx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) dev->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static void gprs_data_ready(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct gprs_dev *gp = sk->sk_user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) while ((skb = pep_read(sk)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) skb_orphan(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) gprs_recv(gp, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static void gprs_write_space(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct gprs_dev *gp = sk->sk_user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (netif_running(gp->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) gprs_writeable(gp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * Network device callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static int gprs_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct gprs_dev *gp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) gprs_writeable(gp);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int gprs_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static netdev_tx_t gprs_xmit(struct sk_buff *skb, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct gprs_dev *gp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct sock *sk = gp->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int len, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) switch (skb->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) case htons(ETH_P_IP):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case htons(ETH_P_IPV6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) skb_orphan(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) skb_set_owner_w(skb, sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) err = pep_write(sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) net_dbg_ratelimited("%s: TX error (%d)\n", dev->name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) dev->stats.tx_aborted_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) dev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) dev->stats.tx_bytes += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (pep_writeable(sk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static const struct net_device_ops gprs_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .ndo_open = gprs_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .ndo_stop = gprs_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .ndo_start_xmit = gprs_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static void gprs_setup(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) dev->features = NETIF_F_FRAGLIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) dev->type = ARPHRD_PHONET_PIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) dev->flags = IFF_POINTOPOINT | IFF_NOARP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) dev->mtu = GPRS_DEFAULT_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) dev->min_mtu = 576;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) dev->max_mtu = (PHONET_MAX_MTU - 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) dev->hard_header_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) dev->addr_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) dev->tx_queue_len = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) dev->netdev_ops = &gprs_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) dev->needs_free_netdev = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * External interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Attach a GPRS interface to a datagram socket.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * Returns the interface index on success, negative error code on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int gprs_attach(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static const char ifname[] = "gprs%d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct gprs_dev *gp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (unlikely(sk->sk_type == SOCK_STREAM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return -EINVAL; /* need packet boundaries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Create net device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) dev = alloc_netdev(sizeof(*gp), ifname, NET_NAME_UNKNOWN, gprs_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) gp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) gp->sk = sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) gp->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) err = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (unlikely(sk->sk_user_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) goto out_rel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (unlikely((1 << sk->sk_state & (TCPF_CLOSE|TCPF_LISTEN)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) sock_flag(sk, SOCK_DEAD))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) goto out_rel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) sk->sk_user_data = gp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) gp->old_state_change = sk->sk_state_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) gp->old_data_ready = sk->sk_data_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) gp->old_write_space = sk->sk_write_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) sk->sk_state_change = gprs_state_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) sk->sk_data_ready = gprs_data_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) sk->sk_write_space = gprs_write_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) sock_hold(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) printk(KERN_DEBUG"%s: attached\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return dev->ifindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) out_rel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) unregister_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) void gprs_detach(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct gprs_dev *gp = sk->sk_user_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct net_device *dev = gp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) sk->sk_user_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) sk->sk_state_change = gp->old_state_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sk->sk_data_ready = gp->old_data_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) sk->sk_write_space = gp->old_write_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) printk(KERN_DEBUG"%s: detached\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) unregister_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) sock_put(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }