static int emac_sgmii_irq_clear(struct emac_adapter *adpt, u8 irq_bits) { struct emac_sgmii *phy = &adpt->phy; u8 status; writel_relaxed(irq_bits, phy->base + EMAC_SGMII_PHY_INTERRUPT_CLEAR); writel_relaxed(IRQ_GLOBAL_CLEAR, phy->base + EMAC_SGMII_PHY_IRQ_CMD); /* Ensure interrupt clear command is written to HW */ wmb(); /* After set the IRQ_GLOBAL_CLEAR bit, the status clearing must * be confirmed before clearing the bits in other registers. * It takes a few cycles for hw to clear the interrupt status. */ if (readl_poll_timeout_atomic(phy->base + EMAC_SGMII_PHY_INTERRUPT_STATUS, status, !(status & irq_bits), 1, SGMII_PHY_IRQ_CLR_WAIT_TIME)) { net_err_ratelimited("%s: failed to clear SGMII irq: status:0x%x bits:0x%x\n", adpt->netdev->name, status, irq_bits); return -EIO; } /* Finalize clearing procedure */ writel_relaxed(0, phy->base + EMAC_SGMII_PHY_IRQ_CMD); writel_relaxed(0, phy->base + EMAC_SGMII_PHY_INTERRUPT_CLEAR); /* Ensure that clearing procedure finalization is written to HW */ wmb(); return 0; }
int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned param) { struct sir_fsm *fsm = &dev->fsm; pr_debug("%s - state=0x%04x / param=%u\n", __func__, initial_state, param); if (down_trylock(&fsm->sem)) { if (in_interrupt() || in_atomic() || irqs_disabled()) { pr_debug("%s(), state machine busy!\n", __func__); return -EWOULDBLOCK; } else down(&fsm->sem); } if (fsm->state == SIRDEV_STATE_DEAD) { /* race with sirdev_close should never happen */ net_err_ratelimited("%s(), instance staled!\n", __func__); up(&fsm->sem); return -ESTALE; /* or better EPIPE? */ } netif_stop_queue(dev->netdev); atomic_set(&dev->enable_rx, 0); fsm->state = initial_state; fsm->param = param; fsm->result = 0; INIT_DELAYED_WORK(&fsm->work, sirdev_config_fsm); queue_delayed_work(irda_sir_wq, &fsm->work, 0); return 0; }
static unsigned int arpt_error(struct sk_buff *skb, const struct xt_action_param *par) { net_err_ratelimited("arp_tables: error: '%s'\n", (const char *)par->targinfo); return NF_DROP; }
static int internal_dev_change_mtu(struct net_device *dev, int new_mtu) { if (new_mtu < ETH_MIN_MTU) { net_err_ratelimited("%s: Invalid MTU %d requested, hw min %d\n", dev->name, new_mtu, ETH_MIN_MTU); return -EINVAL; } if (new_mtu > ETH_MAX_MTU) { net_err_ratelimited("%s: Invalid MTU %d requested, hw max %d\n", dev->name, new_mtu, ETH_MAX_MTU); return -EINVAL; } dev->mtu = new_mtu; return 0; }
static int sirdev_tx_complete_fsm(struct sir_dev *dev) { struct sir_fsm *fsm = &dev->fsm; unsigned next_state, delay; unsigned bytes_left; do { next_state = fsm->substate; /* default: stay in current substate */ delay = 0; switch(fsm->substate) { case SIRDEV_STATE_WAIT_XMIT: if (dev->drv->chars_in_buffer) bytes_left = dev->drv->chars_in_buffer(dev); else bytes_left = 0; if (!bytes_left) { next_state = SIRDEV_STATE_WAIT_UNTIL_SENT; break; } if (dev->speed > 115200) delay = (bytes_left*8*10000) / (dev->speed/100); else if (dev->speed > 0) delay = (bytes_left*10*10000) / (dev->speed/100); else delay = 0; /* expected delay (usec) until remaining bytes are sent */ if (delay < 100) { udelay(delay); delay = 0; break; } /* sleep some longer delay (msec) */ delay = (delay+999) / 1000; break; case SIRDEV_STATE_WAIT_UNTIL_SENT: /* block until underlaying hardware buffer are empty */ if (dev->drv->wait_until_sent) dev->drv->wait_until_sent(dev); next_state = SIRDEV_STATE_TX_DONE; break; case SIRDEV_STATE_TX_DONE: return 0; default: net_err_ratelimited("%s - undefined state\n", __func__); return -EINVAL; } fsm->substate = next_state; } while (delay == 0); return delay; }
/* * Function irda_device_is_receiving (dev) * * Check if the device driver is currently receiving data * */ int irda_device_is_receiving(struct net_device *dev) { struct if_irda_req req; int ret; if (!dev->netdev_ops->ndo_do_ioctl) { net_err_ratelimited("%s: do_ioctl not impl. by device driver\n", __func__); return -1; } ret = (dev->netdev_ops->ndo_do_ioctl)(dev, (struct ifreq *) &req, SIOCGRECEIVING); if (ret < 0) return ret; return req.ifr_receiving; }
/* * Function ali_ircc_open (int i, chipio_t *inf) * * Open driver instance * */ static int ali_ircc_open(int i, chipio_t *info) { struct net_device *dev; struct ali_ircc_cb *self; int dongle_id; int err; if (i >= ARRAY_SIZE(dev_self)) { net_err_ratelimited("%s(), maximum number of supported chips reached!\n", __func__); return -ENOMEM; } /* Set FIR FIFO and DMA Threshold */ if ((ali_ircc_setup(info)) == -1) return -1; dev = alloc_irdadev(sizeof(*self)); if (dev == NULL) { net_err_ratelimited("%s(), can't allocate memory for control block!\n", __func__); return -ENOMEM; } self = netdev_priv(dev); self->netdev = dev; spin_lock_init(&self->lock); /* Need to store self somewhere */ dev_self[i] = self; self->index = i; /* Initialize IO */ self->io.cfg_base = info->cfg_base; /* In ali_ircc_probe_53 assign */ self->io.fir_base = info->fir_base; /* info->sir_base = info->fir_base */ self->io.sir_base = info->sir_base; /* ALi SIR and FIR use the same address */ self->io.irq = info->irq; self->io.fir_ext = CHIP_IO_EXTENT; self->io.dma = info->dma; self->io.fifo_size = 16; /* SIR: 16, FIR: 32 Benjamin 2000/11/1 */ /* Reserve the ioports that we need */ if (!request_region(self->io.fir_base, self->io.fir_ext, ALI_IRCC_DRIVER_NAME)) { net_warn_ratelimited("%s(), can't get iobase of 0x%03x\n", __func__, self->io.fir_base); err = -ENODEV; goto err_out1; } /* Initialize QoS for this device */ irda_init_max_qos_capabilies(&self->qos); /* The only value we must override it the baudrate */ self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8); // benjamin 2000/11/8 05:27PM self->qos.min_turn_time.bits = qos_mtt_bits; irda_qos_bits_to_value(&self->qos); /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */ self->rx_buff.truesize = 14384; self->tx_buff.truesize = 14384; /* Allocate memory if needed */ self->rx_buff.head = dma_zalloc_coherent(NULL, self->rx_buff.truesize, &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto err_out2; } self->tx_buff.head = dma_zalloc_coherent(NULL, self->tx_buff.truesize, &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto err_out3; } self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; self->tx_buff.data = self->tx_buff.head; self->rx_buff.data = self->rx_buff.head; /* Reset Tx queue info */ self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0; self->tx_fifo.tail = self->tx_buff.head; /* Override the network functions we need to use */ dev->netdev_ops = &ali_ircc_sir_ops; err = register_netdev(dev); if (err) { net_err_ratelimited("%s(), register_netdev() failed!\n", __func__); goto err_out4; } net_info_ratelimited("IrDA: Registered device %s\n", dev->name); /* Check dongle id */ dongle_id = ali_ircc_read_dongle_id(i, info); net_info_ratelimited("%s(), %s, Found dongle: %s\n", __func__, ALI_IRCC_DRIVER_NAME, dongle_types[dongle_id]); self->io.dongle_id = dongle_id; return 0; err_out4: dma_free_coherent(NULL, self->tx_buff.truesize, self->tx_buff.head, self->tx_buff_dma); err_out3: dma_free_coherent(NULL, self->rx_buff.truesize, self->rx_buff.head, self->rx_buff_dma); err_out2: release_region(self->io.fir_base, self->io.fir_ext); err_out1: dev_self[i] = NULL; free_netdev(dev); return err; }
/* * Function ali_ircc_init () * * Initialize chip. Find out whay kinds of chips we are dealing with * and their configuration registers address */ static int __init ali_ircc_init(void) { ali_chip_t *chip; chipio_t info; int ret; int cfg, cfg_base; int reg, revision; int i = 0; ret = platform_driver_register(&ali_ircc_driver); if (ret) { net_err_ratelimited("%s, Can't register driver!\n", ALI_IRCC_DRIVER_NAME); return ret; } ret = -ENODEV; /* Probe for all the ALi chipsets we know about */ for (chip= chips; chip->name; chip++, i++) { pr_debug("%s(), Probing for %s ...\n", __func__, chip->name); /* Try all config registers for this chip */ for (cfg=0; cfg<2; cfg++) { cfg_base = chip->cfg[cfg]; if (!cfg_base) continue; memset(&info, 0, sizeof(chipio_t)); info.cfg_base = cfg_base; info.fir_base = io[i]; info.dma = dma[i]; info.irq = irq[i]; /* Enter Configuration */ outb(chip->entr1, cfg_base); outb(chip->entr2, cfg_base); /* Select Logical Device 5 Registers (UART2) */ outb(0x07, cfg_base); outb(0x05, cfg_base+1); /* Read Chip Identification Register */ outb(chip->cid_index, cfg_base); reg = inb(cfg_base+1); if (reg == chip->cid_value) { pr_debug("%s(), Chip found at 0x%03x\n", __func__, cfg_base); outb(0x1F, cfg_base); revision = inb(cfg_base+1); pr_debug("%s(), Found %s chip, revision=%d\n", __func__, chip->name, revision); /* * If the user supplies the base address, then * we init the chip, if not we probe the values * set by the BIOS */ if (io[i] < 2000) { chip->init(chip, &info); } else { chip->probe(chip, &info); } if (ali_ircc_open(i, &info) == 0) ret = 0; i++; } else { pr_debug("%s(), No %s chip at 0x%03x\n", __func__, chip->name, cfg_base); } /* Exit configuration */ outb(0xbb, cfg_base); } } if (ret) platform_driver_unregister(&ali_ircc_driver); return ret; }
/* Create a new IPv4 subflow. * * We are in user-context and meta-sock-lock is hold. */ int mptcp_init4_subsockets(struct sock *meta_sk, const struct mptcp_loc4 *loc, struct mptcp_rem4 *rem) { struct tcp_sock *tp; struct sock *sk; struct sockaddr_in loc_in, rem_in; struct socket_alloc sock_full; struct socket *sock = (struct socket *)&sock_full; int ret; /** First, create and prepare the new socket */ memcpy(&sock_full, meta_sk->sk_socket, sizeof(sock_full)); sock->state = SS_UNCONNECTED; sock->ops = NULL; ret = inet_create(sock_net(meta_sk), sock, IPPROTO_TCP, 1); if (unlikely(ret < 0)) { net_err_ratelimited("%s inet_create failed ret: %d\n", __func__, ret); return ret; } sk = sock->sk; tp = tcp_sk(sk); /* All subsockets need the MPTCP-lock-class */ lockdep_set_class_and_name(&(sk)->sk_lock.slock, &meta_slock_key, meta_slock_key_name); lockdep_init_map(&(sk)->sk_lock.dep_map, meta_key_name, &meta_key, 0); ret = mptcp_add_sock(meta_sk, sk, loc->loc4_id, rem->rem4_id, GFP_KERNEL); if (ret) { net_err_ratelimited("%s mptcp_add_sock failed ret: %d\n", __func__, ret); goto error; } tp->mptcp->slave_sk = 1; /* Initializing the timer for an MPTCP subflow */ timer_setup(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, 0); /** Then, connect the socket to the peer */ loc_in.sin_family = AF_INET; rem_in.sin_family = AF_INET; loc_in.sin_port = 0; if (rem->port) rem_in.sin_port = rem->port; else rem_in.sin_port = inet_sk(meta_sk)->inet_dport; loc_in.sin_addr = loc->addr; rem_in.sin_addr = rem->addr; if (loc->if_idx) sk->sk_bound_dev_if = loc->if_idx; ret = kernel_bind(sock, (struct sockaddr *)&loc_in, sizeof(struct sockaddr_in)); if (ret < 0) { net_err_ratelimited("%s: token %#x bind() to %pI4 index %d failed, error %d\n", __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, &loc_in.sin_addr, loc->if_idx, ret); goto error; } mptcp_debug("%s: token %#x pi %d src_addr:%pI4:%d dst_addr:%pI4:%d ifidx: %d\n", __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, tp->mptcp->path_index, &loc_in.sin_addr, ntohs(loc_in.sin_port), &rem_in.sin_addr, ntohs(rem_in.sin_port), loc->if_idx); ret = kernel_connect(sock, (struct sockaddr *)&rem_in, sizeof(struct sockaddr_in), O_NONBLOCK); if (ret < 0 && ret != -EINPROGRESS) { net_err_ratelimited("%s: MPTCP subsocket connect() failed, error %d\n", __func__, ret); goto error; } MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINSYNTX); sk_set_socket(sk, meta_sk->sk_socket); sk->sk_wq = meta_sk->sk_wq; return 0; error: /* May happen if mptcp_add_sock fails first */ if (!mptcp(tp)) { tcp_close(sk, 0); } else { local_bh_disable(); mptcp_sub_force_close(sk); local_bh_enable(); } return ret; }
static int tekram_change_speed(struct sir_dev *dev, unsigned speed) { unsigned state = dev->fsm.substate; unsigned delay = 0; u8 byte; static int ret = 0; switch(state) { case SIRDEV_STATE_DONGLE_SPEED: switch (speed) { default: speed = 9600; ret = -EINVAL; /* fall thru */ case 9600: byte = TEKRAM_PW|TEKRAM_9600; break; case 19200: byte = TEKRAM_PW|TEKRAM_19200; break; case 38400: byte = TEKRAM_PW|TEKRAM_38400; break; case 57600: byte = TEKRAM_PW|TEKRAM_57600; break; case 115200: byte = TEKRAM_115200; break; } /* Set DTR, Clear RTS */ sirdev_set_dtr_rts(dev, TRUE, FALSE); /* Wait at least 7us */ udelay(14); /* Write control byte */ sirdev_raw_write(dev, &byte, 1); dev->speed = speed; state = TEKRAM_STATE_WAIT_SPEED; delay = tekram_delay; break; case TEKRAM_STATE_WAIT_SPEED: /* Set DTR, Set RTS */ sirdev_set_dtr_rts(dev, TRUE, TRUE); udelay(50); break; default: net_err_ratelimited("%s - undefined state %d\n", __func__, state); ret = -EINVAL; break; } dev->fsm.substate = state; return (delay > 0) ? delay : ret; }
/* * Function w83977af_open (iobase, irq) * * Open driver instance * */ static int w83977af_open(int i, unsigned int iobase, unsigned int irq, unsigned int dma) { struct net_device *dev; struct w83977af_ir *self; int err; /* Lock the port that we need */ if (!request_region(iobase, CHIP_IO_EXTENT, driver_name)) { pr_debug("%s(), can't get iobase of 0x%03x\n", __func__ , iobase); return -ENODEV; } if (w83977af_probe(iobase, irq, dma) == -1) { err = -1; goto err_out; } /* * Allocate new instance of the driver */ dev = alloc_irdadev(sizeof(struct w83977af_ir)); if (dev == NULL) { printk( KERN_ERR "IrDA: Can't allocate memory for " "IrDA control block!\n"); err = -ENOMEM; goto err_out; } self = netdev_priv(dev); spin_lock_init(&self->lock); /* Initialize IO */ self->io.fir_base = iobase; self->io.irq = irq; self->io.fir_ext = CHIP_IO_EXTENT; self->io.dma = dma; self->io.fifo_size = 32; /* Initialize QoS for this device */ irda_init_max_qos_capabilies(&self->qos); /* The only value we must override it the baudrate */ /* FIXME: The HP HDLS-1100 does not support 1152000! */ self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8); /* The HP HDLS-1100 needs 1 ms according to the specs */ self->qos.min_turn_time.bits = qos_mtt_bits; irda_qos_bits_to_value(&self->qos); /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */ self->rx_buff.truesize = 14384; self->tx_buff.truesize = 4000; /* Allocate memory if needed */ self->rx_buff.head = dma_zalloc_coherent(NULL, self->rx_buff.truesize, &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; goto err_out1; } self->tx_buff.head = dma_zalloc_coherent(NULL, self->tx_buff.truesize, &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; goto err_out2; } self->rx_buff.in_frame = FALSE; self->rx_buff.state = OUTSIDE_FRAME; self->tx_buff.data = self->tx_buff.head; self->rx_buff.data = self->rx_buff.head; self->netdev = dev; dev->netdev_ops = &w83977_netdev_ops; err = register_netdev(dev); if (err) { net_err_ratelimited("%s(), register_netdevice() failed!\n", __func__); goto err_out3; } net_info_ratelimited("IrDA: Registered device %s\n", dev->name); /* Need to store self somewhere */ dev_self[i] = self; return 0; err_out3: dma_free_coherent(NULL, self->tx_buff.truesize, self->tx_buff.head, self->tx_buff_dma); err_out2: dma_free_coherent(NULL, self->rx_buff.truesize, self->rx_buff.head, self->rx_buff_dma); err_out1: free_netdev(dev); err_out: release_region(iobase, CHIP_IO_EXTENT); return err; }
static int tcpmss_mangle_packet(struct sk_buff *skb, const struct xt_action_param *par, unsigned int family, unsigned int tcphoff, unsigned int minlen) { const struct xt_tcpmss_info *info = par->targinfo; struct tcphdr *tcph; int len, tcp_hdrlen; unsigned int i; __be16 oldval; u16 newmss; u8 *opt; /* This is a fragment, no TCP header is available */ if (par->fragoff != 0) return 0; if (!skb_make_writable(skb, skb->len)) return -1; len = skb->len - tcphoff; if (len < (int)sizeof(struct tcphdr)) return -1; tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); tcp_hdrlen = tcph->doff * 4; if (len < tcp_hdrlen) return -1; if (info->mss == XT_TCPMSS_CLAMP_PMTU) { struct net *net = dev_net(par->in ? par->in : par->out); unsigned int in_mtu = tcpmss_reverse_mtu(net, skb, family); if (dst_mtu(skb_dst(skb)) <= minlen) { net_err_ratelimited("unknown or invalid path-MTU (%u)\n", dst_mtu(skb_dst(skb))); return -1; } if (in_mtu <= minlen) { net_err_ratelimited("unknown or invalid path-MTU (%u)\n", in_mtu); return -1; } newmss = min(dst_mtu(skb_dst(skb)), in_mtu) - minlen; } else newmss = info->mss; opt = (u_int8_t *)tcph; for (i = sizeof(struct tcphdr); i <= tcp_hdrlen - TCPOLEN_MSS; i += optlen(opt, i)) { if (opt[i] == TCPOPT_MSS && opt[i+1] == TCPOLEN_MSS) { u_int16_t oldmss; oldmss = (opt[i+2] << 8) | opt[i+3]; /* Never increase MSS, even when setting it, as * doing so results in problems for hosts that rely * on MSS being set correctly. */ if (oldmss <= newmss) return 0; opt[i+2] = (newmss & 0xff00) >> 8; opt[i+3] = newmss & 0x00ff; inet_proto_csum_replace2(&tcph->check, skb, htons(oldmss), htons(newmss), false); return 0; } }
void sirdev_write_complete(struct sir_dev *dev) { unsigned long flags; struct sk_buff *skb; int actual = 0; int err; spin_lock_irqsave(&dev->tx_lock, flags); pr_debug("%s() - dev->tx_buff.len = %d\n", __func__, dev->tx_buff.len); if (likely(dev->tx_buff.len > 0)) { /* Write data left in transmit buffer */ actual = dev->drv->do_write(dev, dev->tx_buff.data, dev->tx_buff.len); if (likely(actual>0)) { dev->tx_buff.data += actual; dev->tx_buff.len -= actual; } else if (unlikely(actual<0)) { /* could be dropped later when we have tx_timeout to recover */ net_err_ratelimited("%s: drv->do_write failed (%d)\n", __func__, actual); if ((skb=dev->tx_skb) != NULL) { dev->tx_skb = NULL; dev_kfree_skb_any(skb); dev->netdev->stats.tx_errors++; dev->netdev->stats.tx_dropped++; } dev->tx_buff.len = 0; } if (dev->tx_buff.len > 0) goto done; /* more data to send later */ } if (unlikely(dev->raw_tx != 0)) { /* in raw mode we are just done now after the buffer was sent * completely. Since this was requested by some dongle driver * running under the control of the irda-thread we must take * care here not to re-enable the queue. The queue will be * restarted when the irda-thread has completed the request. */ pr_debug("%s(), raw-tx done\n", __func__); dev->raw_tx = 0; goto done; /* no post-frame handling in raw mode */ } /* we have finished now sending this skb. * update statistics and free the skb. * finally we check and trigger a pending speed change, if any. * if not we switch to rx mode and wake the queue for further * packets. * note the scheduled speed request blocks until the lower * client driver and the corresponding hardware has really * finished sending all data (xmit fifo drained f.e.) * before the speed change gets finally done and the queue * re-activated. */ pr_debug("%s(), finished with frame!\n", __func__); if ((skb=dev->tx_skb) != NULL) { dev->tx_skb = NULL; dev->netdev->stats.tx_packets++; dev->netdev->stats.tx_bytes += skb->len; dev_kfree_skb_any(skb); } if (unlikely(dev->new_speed > 0)) { pr_debug("%s(), Changing speed!\n", __func__); err = sirdev_schedule_speed(dev, dev->new_speed); if (unlikely(err)) { /* should never happen * forget the speed change and hope the stack recovers */ net_err_ratelimited("%s - schedule speed change failed: %d\n", __func__, err); netif_wake_queue(dev->netdev); } /* else: success * speed change in progress now * on completion dev->new_speed gets cleared, * rx-reenabled and the queue restarted */ } else { sirdev_enable_rx(dev); netif_wake_queue(dev->netdev); } done: spin_unlock_irqrestore(&dev->tx_lock, flags); }
static void sirdev_config_fsm(struct work_struct *work) { struct sir_dev *dev = container_of(work, struct sir_dev, fsm.work.work); struct sir_fsm *fsm = &dev->fsm; int next_state; int ret = -1; unsigned delay; pr_debug("%s(), <%ld>\n", __func__, jiffies); do { pr_debug("%s - state=0x%04x / substate=0x%04x\n", __func__, fsm->state, fsm->substate); next_state = fsm->state; delay = 0; switch(fsm->state) { case SIRDEV_STATE_DONGLE_OPEN: if (dev->dongle_drv != NULL) { ret = sirdev_put_dongle(dev); if (ret) { fsm->result = -EINVAL; next_state = SIRDEV_STATE_ERROR; break; } } /* Initialize dongle */ ret = sirdev_get_dongle(dev, fsm->param); if (ret) { fsm->result = ret; next_state = SIRDEV_STATE_ERROR; break; } /* Dongles are powered through the modem control lines which * were just set during open. Before resetting, let's wait for * the power to stabilize. This is what some dongle drivers did * in open before, while others didn't - should be safe anyway. */ delay = 50; fsm->substate = SIRDEV_STATE_DONGLE_RESET; next_state = SIRDEV_STATE_DONGLE_RESET; fsm->param = 9600; break; case SIRDEV_STATE_DONGLE_CLOSE: /* shouldn't we just treat this as success=? */ if (dev->dongle_drv == NULL) { fsm->result = -EINVAL; next_state = SIRDEV_STATE_ERROR; break; } ret = sirdev_put_dongle(dev); if (ret) { fsm->result = ret; next_state = SIRDEV_STATE_ERROR; break; } next_state = SIRDEV_STATE_DONE; break; case SIRDEV_STATE_SET_DTR_RTS: ret = sirdev_set_dtr_rts(dev, (fsm->param&0x02) ? TRUE : FALSE, (fsm->param&0x01) ? TRUE : FALSE); next_state = SIRDEV_STATE_DONE; break; case SIRDEV_STATE_SET_SPEED: fsm->substate = SIRDEV_STATE_WAIT_XMIT; next_state = SIRDEV_STATE_DONGLE_CHECK; break; case SIRDEV_STATE_DONGLE_CHECK: ret = sirdev_tx_complete_fsm(dev); if (ret < 0) { fsm->result = ret; next_state = SIRDEV_STATE_ERROR; break; } if ((delay=ret) != 0) break; if (dev->dongle_drv) { fsm->substate = SIRDEV_STATE_DONGLE_RESET; next_state = SIRDEV_STATE_DONGLE_RESET; } else { dev->speed = fsm->param; next_state = SIRDEV_STATE_PORT_SPEED; } break; case SIRDEV_STATE_DONGLE_RESET: if (dev->dongle_drv->reset) { ret = dev->dongle_drv->reset(dev); if (ret < 0) { fsm->result = ret; next_state = SIRDEV_STATE_ERROR; break; } } else ret = 0; if ((delay=ret) == 0) { /* set serial port according to dongle default speed */ if (dev->drv->set_speed) dev->drv->set_speed(dev, dev->speed); fsm->substate = SIRDEV_STATE_DONGLE_SPEED; next_state = SIRDEV_STATE_DONGLE_SPEED; } break; case SIRDEV_STATE_DONGLE_SPEED: if (dev->dongle_drv->set_speed) { ret = dev->dongle_drv->set_speed(dev, fsm->param); if (ret < 0) { fsm->result = ret; next_state = SIRDEV_STATE_ERROR; break; } } else ret = 0; if ((delay=ret) == 0) next_state = SIRDEV_STATE_PORT_SPEED; break; case SIRDEV_STATE_PORT_SPEED: /* Finally we are ready to change the serial port speed */ if (dev->drv->set_speed) dev->drv->set_speed(dev, dev->speed); dev->new_speed = 0; next_state = SIRDEV_STATE_DONE; break; case SIRDEV_STATE_DONE: /* Signal network layer so it can send more frames */ netif_wake_queue(dev->netdev); next_state = SIRDEV_STATE_COMPLETE; break; default: net_err_ratelimited("%s - undefined state\n", __func__); fsm->result = -EINVAL; /* fall thru */ case SIRDEV_STATE_ERROR: net_err_ratelimited("%s - error: %d\n", __func__, fsm->result); #if 0 /* don't enable this before we have netdev->tx_timeout to recover */ netif_stop_queue(dev->netdev); #else netif_wake_queue(dev->netdev); #endif /* fall thru */ case SIRDEV_STATE_COMPLETE: /* config change finished, so we are not busy any longer */ sirdev_enable_rx(dev); up(&fsm->sem); return; } fsm->state = next_state; } while(!delay); queue_delayed_work(irda_sir_wq, &fsm->work, msecs_to_jiffies(delay)); }