Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (22 commits)
  [PATCH] ibmveth: Fix index increment calculation
  [PATCH] Fix timer race
  [PATCH] Remove useless comment from sb1250
  [PATCH] ucc_geth: changes to ucc_geth driver as a result of qe_lib changes and bugfixes
  [PATCH] sky2: 88E803X transmit lockup
  [PATCH] e1000: Reset all functions after a PCI error
  [PATCH] WAN/pc300: handle, propagate minor errors
  [PATCH] Update smc91x driver with ARM Versatile board info
  [PATCH] wireless: WE-20 compatibility for ESSID and NICKN ioctls
  [PATCH] zd1211rw: fix build-break caused by association race fix
  [PATCH] sotftmac: fix a slab corruption in WEP restricted key association
  [PATCH] airo: check if need to freeze
  [PATCH] wireless: More WE-21 potential overflows...
  [PATCH] zd1201: Possible NULL dereference
  [PATCH] orinoco: fix WE-21 buffer overflow
  [PATCH] airo.c: check returned values
  [PATCH] bcm43xx-softmac: Fix system hang for x86-64 with >1GB RAM
  [PATCH] bcm43xx-softmac: check returned value from pci_enable_device
  [PATCH] softmac: Fix WX and association related races
  [PATCH] bcm43xx: fix race condition in periodic work handler
  ...
This commit is contained in:
Linus Torvalds 2006-10-21 13:40:29 -07:00
commit dcf234f3b0
29 changed files with 804 additions and 623 deletions

View file

@ -2288,7 +2288,7 @@ config UGETH_TX_ON_DEMOND
config UGETH_HAS_GIGA config UGETH_HAS_GIGA
bool bool
depends on UCC_GETH && MPC836x depends on UCC_GETH && PPC_MPC836x
config MV643XX_ETH config MV643XX_ETH
tristate "MV-643XX Ethernet support" tristate "MV-643XX Ethernet support"

View file

@ -4914,10 +4914,6 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0); pci_enable_wake(pdev, PCI_D3cold, 0);
/* Perform card reset only on one instance of the card */
if (PCI_FUNC (pdev->devfn) != 0)
return PCI_ERS_RESULT_RECOVERED;
e1000_reset(adapter); e1000_reset(adapter);
E1000_WRITE_REG(&adapter->hw, WUS, ~0); E1000_WRITE_REG(&adapter->hw, WUS, ~0);

View file

@ -1017,7 +1017,7 @@ static void ioc3_init(struct net_device *dev)
struct ioc3_private *ip = netdev_priv(dev); struct ioc3_private *ip = netdev_priv(dev);
struct ioc3 *ioc3 = ip->regs; struct ioc3 *ioc3 = ip->regs;
del_timer(&ip->ioc3_timer); /* Kill if running */ del_timer_sync(&ip->ioc3_timer); /* Kill if running */
ioc3_w_emcr(EMCR_RST); /* Reset */ ioc3_w_emcr(EMCR_RST); /* Reset */
(void) ioc3_r_emcr(); /* Flush WB */ (void) ioc3_r_emcr(); /* Flush WB */
@ -1081,7 +1081,7 @@ static int ioc3_close(struct net_device *dev)
{ {
struct ioc3_private *ip = netdev_priv(dev); struct ioc3_private *ip = netdev_priv(dev);
del_timer(&ip->ioc3_timer); del_timer_sync(&ip->ioc3_timer);
netif_stop_queue(dev); netif_stop_queue(dev);

View file

@ -214,6 +214,7 @@ static struct pci_device_id rtl8169_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_2 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_2 },
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 },
{ PCI_DEVICE(0x1259, 0xc107), 0, 0, RTL_CFG_0 },
{ PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 },
{ PCI_VENDOR_ID_LINKSYS, 0x1032, { PCI_VENDOR_ID_LINKSYS, 0x1032,
PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 },
@ -2700,6 +2701,7 @@ static void rtl8169_down(struct net_device *dev)
struct rtl8169_private *tp = netdev_priv(dev); struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
unsigned int poll_locked = 0; unsigned int poll_locked = 0;
unsigned int intrmask;
rtl8169_delete_timer(dev); rtl8169_delete_timer(dev);
@ -2738,8 +2740,11 @@ core_down:
* 2) dev->change_mtu * 2) dev->change_mtu
* -> rtl8169_poll can not be issued again and re-enable the * -> rtl8169_poll can not be issued again and re-enable the
* interruptions. Let's simply issue the IRQ down sequence again. * interruptions. Let's simply issue the IRQ down sequence again.
*
* No loop if hotpluged or major error (0xffff).
*/ */
if (RTL_R16(IntrMask)) intrmask = RTL_R16(IntrMask);
if (intrmask && (intrmask != 0xffff))
goto core_down; goto core_down;
rtl8169_tx_clear(tp); rtl8169_tx_clear(tp);

View file

@ -2903,7 +2903,7 @@ sbmac_init_module(void)
dev = alloc_etherdev(sizeof(struct sbmac_softc)); dev = alloc_etherdev(sizeof(struct sbmac_softc));
if (!dev) if (!dev)
return -ENOMEM; /* return ENOMEM */ return -ENOMEM;
printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port); printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port);

View file

@ -699,16 +699,10 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
} }
/* Assign Ram Buffer allocation. /* Assign Ram Buffer allocation in units of 64bit (8 bytes) */
* start and end are in units of 4k bytes static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end)
* ram registers are in units of 64bit words
*/
static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk)
{ {
u32 start, end; pr_debug(PFX "q %d %#x %#x\n", q, start, end);
start = startk * 4096/8;
end = (endk * 4096/8) - 1;
sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
sky2_write32(hw, RB_ADDR(q, RB_START), start); sky2_write32(hw, RB_ADDR(q, RB_START), start);
@ -717,7 +711,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk)
sky2_write32(hw, RB_ADDR(q, RB_RP), start); sky2_write32(hw, RB_ADDR(q, RB_RP), start);
if (q == Q_R1 || q == Q_R2) { if (q == Q_R1 || q == Q_R2) {
u32 space = (endk - startk) * 4096/8; u32 space = end - start + 1;
u32 tp = space - space/4; u32 tp = space - space/4;
/* On receive queue's set the thresholds /* On receive queue's set the thresholds
@ -1199,19 +1193,16 @@ static int sky2_up(struct net_device *dev)
sky2_mac_init(hw, port); sky2_mac_init(hw, port);
/* Determine available ram buffer space (in 4K blocks). /* Determine available ram buffer space in qwords. */
* Note: not sure about the FE setting below yet ramsize = sky2_read8(hw, B2_E_0) * 4096/8;
*/
if (hw->chip_id == CHIP_ID_YUKON_FE)
ramsize = 4;
else
ramsize = sky2_read8(hw, B2_E_0);
/* Give transmitter one third (rounded up) */ if (ramsize > 6*1024/8)
rxspace = ramsize - (ramsize + 2) / 3; rxspace = ramsize - (ramsize + 2) / 3;
else
rxspace = ramsize / 2;
sky2_ramset(hw, rxqaddr[port], 0, rxspace); sky2_ramset(hw, rxqaddr[port], 0, rxspace-1);
sky2_ramset(hw, txqaddr[port], rxspace, ramsize); sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1);
/* Make sure SyncQ is disabled */ /* Make sure SyncQ is disabled */
sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),

View file

@ -416,6 +416,24 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#define SMC_IRQ_FLAGS (0) #define SMC_IRQ_FLAGS (0)
#elif defined(CONFIG_ARCH_VERSATILE)
#define SMC_CAN_USE_8BIT 1
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 1
#define SMC_NOWAIT 1
#define SMC_inb(a, r) readb((a) + (r))
#define SMC_inw(a, r) readw((a) + (r))
#define SMC_inl(a, r) readl((a) + (r))
#define SMC_outb(v, a, r) writeb(v, (a) + (r))
#define SMC_outw(v, a, r) writew(v, (a) + (r))
#define SMC_outl(v, a, r) writel(v, (a) + (r))
#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
#define SMC_IRQ_FLAGS (0)
#else #else
#define SMC_CAN_USE_8BIT 1 #define SMC_CAN_USE_8BIT 1

File diff suppressed because it is too large Load diff

View file

@ -36,24 +36,24 @@
#define ENET_INIT_PARAM_MAX_ENTRIES_RX 9 #define ENET_INIT_PARAM_MAX_ENTRIES_RX 9
#define ENET_INIT_PARAM_MAX_ENTRIES_TX 8 #define ENET_INIT_PARAM_MAX_ENTRIES_TX 8
typedef struct ucc_mii_mng { struct ucc_mii_mng {
u32 miimcfg; /* MII management configuration reg */ u32 miimcfg; /* MII management configuration reg */
u32 miimcom; /* MII management command reg */ u32 miimcom; /* MII management command reg */
u32 miimadd; /* MII management address reg */ u32 miimadd; /* MII management address reg */
u32 miimcon; /* MII management control reg */ u32 miimcon; /* MII management control reg */
u32 miimstat; /* MII management status reg */ u32 miimstat; /* MII management status reg */
u32 miimind; /* MII management indication reg */ u32 miimind; /* MII management indication reg */
} __attribute__ ((packed)) ucc_mii_mng_t; } __attribute__ ((packed));
typedef struct ucc_geth { struct ucc_geth {
ucc_fast_t uccf; struct ucc_fast uccf;
u32 maccfg1; /* mac configuration reg. 1 */ u32 maccfg1; /* mac configuration reg. 1 */
u32 maccfg2; /* mac configuration reg. 2 */ u32 maccfg2; /* mac configuration reg. 2 */
u32 ipgifg; /* interframe gap reg. */ u32 ipgifg; /* interframe gap reg. */
u32 hafdup; /* half-duplex reg. */ u32 hafdup; /* half-duplex reg. */
u8 res1[0x10]; u8 res1[0x10];
ucc_mii_mng_t miimng; /* MII management structure */ struct ucc_mii_mng miimng; /* MII management structure */
u32 ifctl; /* interface control reg */ u32 ifctl; /* interface control reg */
u32 ifstat; /* interface statux reg */ u32 ifstat; /* interface statux reg */
u32 macstnaddr1; /* mac station address part 1 reg */ u32 macstnaddr1; /* mac station address part 1 reg */
@ -111,7 +111,7 @@ typedef struct ucc_geth {
u32 scar; /* Statistics carry register */ u32 scar; /* Statistics carry register */
u32 scam; /* Statistics caryy mask register */ u32 scam; /* Statistics caryy mask register */
u8 res5[0x200 - 0x1c4]; u8 res5[0x200 - 0x1c4];
} __attribute__ ((packed)) ucc_geth_t; } __attribute__ ((packed));
/* UCC GETH TEMODR Register */ /* UCC GETH TEMODR Register */
#define TEMODER_TX_RMON_STATISTICS_ENABLE 0x0100 /* enable Tx statistics #define TEMODER_TX_RMON_STATISTICS_ENABLE 0x0100 /* enable Tx statistics
@ -508,39 +508,39 @@ typedef struct ucc_geth {
/* UCC GETH UDSR (Data Synchronization Register) */ /* UCC GETH UDSR (Data Synchronization Register) */
#define UDSR_MAGIC 0x067E #define UDSR_MAGIC 0x067E
typedef struct ucc_geth_thread_data_tx { struct ucc_geth_thread_data_tx {
u8 res0[104]; u8 res0[104];
} __attribute__ ((packed)) ucc_geth_thread_data_tx_t; } __attribute__ ((packed));
typedef struct ucc_geth_thread_data_rx { struct ucc_geth_thread_data_rx {
u8 res0[40]; u8 res0[40];
} __attribute__ ((packed)) ucc_geth_thread_data_rx_t; } __attribute__ ((packed));
/* Send Queue Queue-Descriptor */ /* Send Queue Queue-Descriptor */
typedef struct ucc_geth_send_queue_qd { struct ucc_geth_send_queue_qd {
u32 bd_ring_base; /* pointer to BD ring base address */ u32 bd_ring_base; /* pointer to BD ring base address */
u8 res0[0x8]; u8 res0[0x8];
u32 last_bd_completed_address;/* initialize to last entry in BD ring */ u32 last_bd_completed_address;/* initialize to last entry in BD ring */
u8 res1[0x30]; u8 res1[0x30];
} __attribute__ ((packed)) ucc_geth_send_queue_qd_t; } __attribute__ ((packed));
typedef struct ucc_geth_send_queue_mem_region { struct ucc_geth_send_queue_mem_region {
ucc_geth_send_queue_qd_t sqqd[NUM_TX_QUEUES]; struct ucc_geth_send_queue_qd sqqd[NUM_TX_QUEUES];
} __attribute__ ((packed)) ucc_geth_send_queue_mem_region_t; } __attribute__ ((packed));
typedef struct ucc_geth_thread_tx_pram { struct ucc_geth_thread_tx_pram {
u8 res0[64]; u8 res0[64];
} __attribute__ ((packed)) ucc_geth_thread_tx_pram_t; } __attribute__ ((packed));
typedef struct ucc_geth_thread_rx_pram { struct ucc_geth_thread_rx_pram {
u8 res0[128]; u8 res0[128];
} __attribute__ ((packed)) ucc_geth_thread_rx_pram_t; } __attribute__ ((packed));
#define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING 64 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING 64
#define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8 64 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8 64
#define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16 96 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16 96
typedef struct ucc_geth_scheduler { struct ucc_geth_scheduler {
u16 cpucount0; /* CPU packet counter */ u16 cpucount0; /* CPU packet counter */
u16 cpucount1; /* CPU packet counter */ u16 cpucount1; /* CPU packet counter */
u16 cecount0; /* QE packet counter */ u16 cecount0; /* QE packet counter */
@ -574,9 +574,9 @@ typedef struct ucc_geth_scheduler {
/**< weight factor for queues */ /**< weight factor for queues */
u32 minw; /* temporary variable handled by QE */ u32 minw; /* temporary variable handled by QE */
u8 res1[0x70 - 0x64]; u8 res1[0x70 - 0x64];
} __attribute__ ((packed)) ucc_geth_scheduler_t; } __attribute__ ((packed));
typedef struct ucc_geth_tx_firmware_statistics_pram { struct ucc_geth_tx_firmware_statistics_pram {
u32 sicoltx; /* single collision */ u32 sicoltx; /* single collision */
u32 mulcoltx; /* multiple collision */ u32 mulcoltx; /* multiple collision */
u32 latecoltxfr; /* late collision */ u32 latecoltxfr; /* late collision */
@ -596,9 +596,9 @@ typedef struct ucc_geth_tx_firmware_statistics_pram {
and 1518 octets */ and 1518 octets */
u32 txpktsjumbo; /* total packets (including bad) between 1024 u32 txpktsjumbo; /* total packets (including bad) between 1024
and MAXLength octets */ and MAXLength octets */
} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_pram_t; } __attribute__ ((packed));
typedef struct ucc_geth_rx_firmware_statistics_pram { struct ucc_geth_rx_firmware_statistics_pram {
u32 frrxfcser; /* frames with crc error */ u32 frrxfcser; /* frames with crc error */
u32 fraligner; /* frames with alignment error */ u32 fraligner; /* frames with alignment error */
u32 inrangelenrxer; /* in range length error */ u32 inrangelenrxer; /* in range length error */
@ -630,33 +630,33 @@ typedef struct ucc_geth_rx_firmware_statistics_pram {
replaced */ replaced */
u32 insertvlan; /* total frames that had their VLAN tag u32 insertvlan; /* total frames that had their VLAN tag
inserted */ inserted */
} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_pram_t; } __attribute__ ((packed));
typedef struct ucc_geth_rx_interrupt_coalescing_entry { struct ucc_geth_rx_interrupt_coalescing_entry {
u32 interruptcoalescingmaxvalue; /* interrupt coalescing max u32 interruptcoalescingmaxvalue; /* interrupt coalescing max
value */ value */
u32 interruptcoalescingcounter; /* interrupt coalescing counter, u32 interruptcoalescingcounter; /* interrupt coalescing counter,
initialize to initialize to
interruptcoalescingmaxvalue */ interruptcoalescingmaxvalue */
} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_entry_t; } __attribute__ ((packed));
typedef struct ucc_geth_rx_interrupt_coalescing_table { struct ucc_geth_rx_interrupt_coalescing_table {
ucc_geth_rx_interrupt_coalescing_entry_t coalescingentry[NUM_RX_QUEUES]; struct ucc_geth_rx_interrupt_coalescing_entry coalescingentry[NUM_RX_QUEUES];
/**< interrupt coalescing entry */ /**< interrupt coalescing entry */
} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_table_t; } __attribute__ ((packed));
typedef struct ucc_geth_rx_prefetched_bds { struct ucc_geth_rx_prefetched_bds {
qe_bd_t bd[NUM_BDS_IN_PREFETCHED_BDS]; /* prefetched bd */ struct qe_bd bd[NUM_BDS_IN_PREFETCHED_BDS]; /* prefetched bd */
} __attribute__ ((packed)) ucc_geth_rx_prefetched_bds_t; } __attribute__ ((packed));
typedef struct ucc_geth_rx_bd_queues_entry { struct ucc_geth_rx_bd_queues_entry {
u32 bdbaseptr; /* BD base pointer */ u32 bdbaseptr; /* BD base pointer */
u32 bdptr; /* BD pointer */ u32 bdptr; /* BD pointer */
u32 externalbdbaseptr; /* external BD base pointer */ u32 externalbdbaseptr; /* external BD base pointer */
u32 externalbdptr; /* external BD pointer */ u32 externalbdptr; /* external BD pointer */
} __attribute__ ((packed)) ucc_geth_rx_bd_queues_entry_t; } __attribute__ ((packed));
typedef struct ucc_geth_tx_global_pram { struct ucc_geth_tx_global_pram {
u16 temoder; u16 temoder;
u8 res0[0x38 - 0x02]; u8 res0[0x38 - 0x02];
u32 sqptr; /* a base pointer to send queue memory region */ u32 sqptr; /* a base pointer to send queue memory region */
@ -670,15 +670,15 @@ typedef struct ucc_geth_tx_global_pram {
u32 tqptr; /* a base pointer to the Tx Queues Memory u32 tqptr; /* a base pointer to the Tx Queues Memory
Region */ Region */
u8 res2[0x80 - 0x74]; u8 res2[0x80 - 0x74];
} __attribute__ ((packed)) ucc_geth_tx_global_pram_t; } __attribute__ ((packed));
/* structure representing Extended Filtering Global Parameters in PRAM */ /* structure representing Extended Filtering Global Parameters in PRAM */
typedef struct ucc_geth_exf_global_pram { struct ucc_geth_exf_global_pram {
u32 l2pcdptr; /* individual address filter, high */ u32 l2pcdptr; /* individual address filter, high */
u8 res0[0x10 - 0x04]; u8 res0[0x10 - 0x04];
} __attribute__ ((packed)) ucc_geth_exf_global_pram_t; } __attribute__ ((packed));
typedef struct ucc_geth_rx_global_pram { struct ucc_geth_rx_global_pram {
u32 remoder; /* ethernet mode reg. */ u32 remoder; /* ethernet mode reg. */
u32 rqptr; /* base pointer to the Rx Queues Memory Region*/ u32 rqptr; /* base pointer to the Rx Queues Memory Region*/
u32 res0[0x1]; u32 res0[0x1];
@ -710,12 +710,12 @@ typedef struct ucc_geth_rx_global_pram {
u32 exfGlobalParam; /* base address for extended filtering global u32 exfGlobalParam; /* base address for extended filtering global
parameters */ parameters */
u8 res6[0x100 - 0xC4]; /* Initialize to zero */ u8 res6[0x100 - 0xC4]; /* Initialize to zero */
} __attribute__ ((packed)) ucc_geth_rx_global_pram_t; } __attribute__ ((packed));
#define GRACEFUL_STOP_ACKNOWLEDGE_RX 0x01 #define GRACEFUL_STOP_ACKNOWLEDGE_RX 0x01
/* structure representing InitEnet command */ /* structure representing InitEnet command */
typedef struct ucc_geth_init_pram { struct ucc_geth_init_pram {
u8 resinit1; u8 resinit1;
u8 resinit2; u8 resinit2;
u8 resinit3; u8 resinit3;
@ -729,7 +729,7 @@ typedef struct ucc_geth_init_pram {
u32 txglobal; /* tx global */ u32 txglobal; /* tx global */
u32 txthread[ENET_INIT_PARAM_MAX_ENTRIES_TX]; /* tx threads */ u32 txthread[ENET_INIT_PARAM_MAX_ENTRIES_TX]; /* tx threads */
u8 res3[0x1]; u8 res3[0x1];
} __attribute__ ((packed)) ucc_geth_init_pram_t; } __attribute__ ((packed));
#define ENET_INIT_PARAM_RGF_SHIFT (32 - 4) #define ENET_INIT_PARAM_RGF_SHIFT (32 - 4)
#define ENET_INIT_PARAM_TGF_SHIFT (32 - 8) #define ENET_INIT_PARAM_TGF_SHIFT (32 - 8)
@ -746,27 +746,27 @@ typedef struct ucc_geth_init_pram {
#define ENET_INIT_PARAM_MAGIC_RES_INIT5 0x0400 #define ENET_INIT_PARAM_MAGIC_RES_INIT5 0x0400
/* structure representing 82xx Address Filtering Enet Address in PRAM */ /* structure representing 82xx Address Filtering Enet Address in PRAM */
typedef struct ucc_geth_82xx_enet_address { struct ucc_geth_82xx_enet_address {
u8 res1[0x2]; u8 res1[0x2];
u16 h; /* address (MSB) */ u16 h; /* address (MSB) */
u16 m; /* address */ u16 m; /* address */
u16 l; /* address (LSB) */ u16 l; /* address (LSB) */
} __attribute__ ((packed)) ucc_geth_82xx_enet_address_t; } __attribute__ ((packed));
/* structure representing 82xx Address Filtering PRAM */ /* structure representing 82xx Address Filtering PRAM */
typedef struct ucc_geth_82xx_address_filtering_pram { struct ucc_geth_82xx_address_filtering_pram {
u32 iaddr_h; /* individual address filter, high */ u32 iaddr_h; /* individual address filter, high */
u32 iaddr_l; /* individual address filter, low */ u32 iaddr_l; /* individual address filter, low */
u32 gaddr_h; /* group address filter, high */ u32 gaddr_h; /* group address filter, high */
u32 gaddr_l; /* group address filter, low */ u32 gaddr_l; /* group address filter, low */
ucc_geth_82xx_enet_address_t taddr; struct ucc_geth_82xx_enet_address taddr;
ucc_geth_82xx_enet_address_t paddr[NUM_OF_PADDRS]; struct ucc_geth_82xx_enet_address paddr[NUM_OF_PADDRS];
u8 res0[0x40 - 0x38]; u8 res0[0x40 - 0x38];
} __attribute__ ((packed)) ucc_geth_82xx_address_filtering_pram_t; } __attribute__ ((packed));
/* GETH Tx firmware statistics structure, used when calling /* GETH Tx firmware statistics structure, used when calling
UCC_GETH_GetStatistics. */ UCC_GETH_GetStatistics. */
typedef struct ucc_geth_tx_firmware_statistics { struct ucc_geth_tx_firmware_statistics {
u32 sicoltx; /* single collision */ u32 sicoltx; /* single collision */
u32 mulcoltx; /* multiple collision */ u32 mulcoltx; /* multiple collision */
u32 latecoltxfr; /* late collision */ u32 latecoltxfr; /* late collision */
@ -786,11 +786,11 @@ typedef struct ucc_geth_tx_firmware_statistics {
and 1518 octets */ and 1518 octets */
u32 txpktsjumbo; /* total packets (including bad) between 1024 u32 txpktsjumbo; /* total packets (including bad) between 1024
and MAXLength octets */ and MAXLength octets */
} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_t; } __attribute__ ((packed));
/* GETH Rx firmware statistics structure, used when calling /* GETH Rx firmware statistics structure, used when calling
UCC_GETH_GetStatistics. */ UCC_GETH_GetStatistics. */
typedef struct ucc_geth_rx_firmware_statistics { struct ucc_geth_rx_firmware_statistics {
u32 frrxfcser; /* frames with crc error */ u32 frrxfcser; /* frames with crc error */
u32 fraligner; /* frames with alignment error */ u32 fraligner; /* frames with alignment error */
u32 inrangelenrxer; /* in range length error */ u32 inrangelenrxer; /* in range length error */
@ -822,11 +822,11 @@ typedef struct ucc_geth_rx_firmware_statistics {
replaced */ replaced */
u32 insertvlan; /* total frames that had their VLAN tag u32 insertvlan; /* total frames that had their VLAN tag
inserted */ inserted */
} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_t; } __attribute__ ((packed));
/* GETH hardware statistics structure, used when calling /* GETH hardware statistics structure, used when calling
UCC_GETH_GetStatistics. */ UCC_GETH_GetStatistics. */
typedef struct ucc_geth_hardware_statistics { struct ucc_geth_hardware_statistics {
u32 tx64; /* Total number of frames (including bad u32 tx64; /* Total number of frames (including bad
frames) transmitted that were exactly of the frames) transmitted that were exactly of the
minimal length (64 for un tagged, 68 for minimal length (64 for un tagged, 68 for
@ -871,7 +871,7 @@ typedef struct ucc_geth_hardware_statistics {
u32 rbca; /* Total number of frames received succesfully u32 rbca; /* Total number of frames received succesfully
that had destination address equal to the that had destination address equal to the
broadcast address */ broadcast address */
} __attribute__ ((packed)) ucc_geth_hardware_statistics_t; } __attribute__ ((packed));
/* UCC GETH Tx errors returned via TxConf callback */ /* UCC GETH Tx errors returned via TxConf callback */
#define TX_ERRORS_DEF 0x0200 #define TX_ERRORS_DEF 0x0200
@ -1013,21 +1013,21 @@ typedef struct ucc_geth_hardware_statistics {
(MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112) (MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112)
/* Ethernet speed */ /* Ethernet speed */
typedef enum enet_speed { enum enet_speed {
ENET_SPEED_10BT, /* 10 Base T */ ENET_SPEED_10BT, /* 10 Base T */
ENET_SPEED_100BT, /* 100 Base T */ ENET_SPEED_100BT, /* 100 Base T */
ENET_SPEED_1000BT /* 1000 Base T */ ENET_SPEED_1000BT /* 1000 Base T */
} enet_speed_e; };
/* Ethernet Address Type. */ /* Ethernet Address Type. */
typedef enum enet_addr_type { enum enet_addr_type {
ENET_ADDR_TYPE_INDIVIDUAL, ENET_ADDR_TYPE_INDIVIDUAL,
ENET_ADDR_TYPE_GROUP, ENET_ADDR_TYPE_GROUP,
ENET_ADDR_TYPE_BROADCAST ENET_ADDR_TYPE_BROADCAST
} enet_addr_type_e; };
/* TBI / MII Set Register */ /* TBI / MII Set Register */
typedef enum enet_tbi_mii_reg { enum enet_tbi_mii_reg {
ENET_TBI_MII_CR = 0x00, /* Control (CR ) */ ENET_TBI_MII_CR = 0x00, /* Control (CR ) */
ENET_TBI_MII_SR = 0x01, /* Status (SR ) */ ENET_TBI_MII_SR = 0x01, /* Status (SR ) */
ENET_TBI_MII_ANA = 0x04, /* AN advertisement (ANA ) */ ENET_TBI_MII_ANA = 0x04, /* AN advertisement (ANA ) */
@ -1040,10 +1040,10 @@ typedef enum enet_tbi_mii_reg {
ENET_TBI_MII_EXST = 0x0F, /* Extended status (EXST ) */ ENET_TBI_MII_EXST = 0x0F, /* Extended status (EXST ) */
ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics (JD ) */ ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics (JD ) */
ENET_TBI_MII_TBICON = 0x11 /* TBI control (TBICON ) */ ENET_TBI_MII_TBICON = 0x11 /* TBI control (TBICON ) */
} enet_tbi_mii_reg_e; };
/* UCC GETH 82xx Ethernet Address Recognition Location */ /* UCC GETH 82xx Ethernet Address Recognition Location */
typedef enum ucc_geth_enet_address_recognition_location { enum ucc_geth_enet_address_recognition_location {
UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station
address */ address */
UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_FIRST, /* additional UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_FIRST, /* additional
@ -1065,10 +1065,10 @@ typedef enum ucc_geth_enet_address_recognition_location {
UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH, /* group hash */ UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH, /* group hash */
UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH /* individual UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH /* individual
hash */ hash */
} ucc_geth_enet_address_recognition_location_e; };
/* UCC GETH vlan operation tagged */ /* UCC GETH vlan operation tagged */
typedef enum ucc_geth_vlan_operation_tagged { enum ucc_geth_vlan_operation_tagged {
UCC_GETH_VLAN_OPERATION_TAGGED_NOP = 0x0, /* Tagged - nop */ UCC_GETH_VLAN_OPERATION_TAGGED_NOP = 0x0, /* Tagged - nop */
UCC_GETH_VLAN_OPERATION_TAGGED_REPLACE_VID_PORTION_OF_Q_TAG UCC_GETH_VLAN_OPERATION_TAGGED_REPLACE_VID_PORTION_OF_Q_TAG
= 0x1, /* Tagged - replace vid portion of q tag */ = 0x1, /* Tagged - replace vid portion of q tag */
@ -1076,18 +1076,18 @@ typedef enum ucc_geth_vlan_operation_tagged {
= 0x2, /* Tagged - if vid0 replace vid with default value */ = 0x2, /* Tagged - if vid0 replace vid with default value */
UCC_GETH_VLAN_OPERATION_TAGGED_EXTRACT_Q_TAG_FROM_FRAME UCC_GETH_VLAN_OPERATION_TAGGED_EXTRACT_Q_TAG_FROM_FRAME
= 0x3 /* Tagged - extract q tag from frame */ = 0x3 /* Tagged - extract q tag from frame */
} ucc_geth_vlan_operation_tagged_e; };
/* UCC GETH vlan operation non-tagged */ /* UCC GETH vlan operation non-tagged */
typedef enum ucc_geth_vlan_operation_non_tagged { enum ucc_geth_vlan_operation_non_tagged {
UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP = 0x0, /* Non tagged - nop */ UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP = 0x0, /* Non tagged - nop */
UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT = 0x1 /* Non tagged - UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT = 0x1 /* Non tagged -
q tag insert q tag insert
*/ */
} ucc_geth_vlan_operation_non_tagged_e; };
/* UCC GETH Rx Quality of Service Mode */ /* UCC GETH Rx Quality of Service Mode */
typedef enum ucc_geth_qos_mode { enum ucc_geth_qos_mode {
UCC_GETH_QOS_MODE_DEFAULT = 0x0, /* default queue */ UCC_GETH_QOS_MODE_DEFAULT = 0x0, /* default queue */
UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L2_CRITERIA = 0x1, /* queue UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L2_CRITERIA = 0x1, /* queue
determined determined
@ -1097,11 +1097,11 @@ typedef enum ucc_geth_qos_mode {
determined determined
by L3 by L3
criteria */ criteria */
} ucc_geth_qos_mode_e; };
/* UCC GETH Statistics Gathering Mode - These are bit flags, 'or' them together /* UCC GETH Statistics Gathering Mode - These are bit flags, 'or' them together
for combined functionality */ for combined functionality */
typedef enum ucc_geth_statistics_gathering_mode { enum ucc_geth_statistics_gathering_mode {
UCC_GETH_STATISTICS_GATHERING_MODE_NONE = 0x00000000, /* No UCC_GETH_STATISTICS_GATHERING_MODE_NONE = 0x00000000, /* No
statistics statistics
gathering */ gathering */
@ -1122,10 +1122,10 @@ typedef enum ucc_geth_statistics_gathering_mode {
statistics statistics
gathering gathering
*/ */
} ucc_geth_statistics_gathering_mode_e; };
/* UCC GETH Pad and CRC Mode - Note, Padding without CRC is not possible */ /* UCC GETH Pad and CRC Mode - Note, Padding without CRC is not possible */
typedef enum ucc_geth_maccfg2_pad_and_crc_mode { enum ucc_geth_maccfg2_pad_and_crc_mode {
UCC_GETH_PAD_AND_CRC_MODE_NONE UCC_GETH_PAD_AND_CRC_MODE_NONE
= MACCFG2_PAD_AND_CRC_MODE_NONE, /* Neither Padding = MACCFG2_PAD_AND_CRC_MODE_NONE, /* Neither Padding
short frames short frames
@ -1135,61 +1135,59 @@ typedef enum ucc_geth_maccfg2_pad_and_crc_mode {
CRC only */ CRC only */
UCC_GETH_PAD_AND_CRC_MODE_PAD_AND_CRC = UCC_GETH_PAD_AND_CRC_MODE_PAD_AND_CRC =
MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC
} ucc_geth_maccfg2_pad_and_crc_mode_e; };
/* UCC GETH upsmr Flow Control Mode */ /* UCC GETH upsmr Flow Control Mode */
typedef enum ucc_geth_flow_control_mode { enum ucc_geth_flow_control_mode {
UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE = 0x00000000, /* No automatic UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE = 0x00000000, /* No automatic
flow control flow control
*/ */
UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_PAUSE_WHEN_EMERGENCY UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_PAUSE_WHEN_EMERGENCY
= 0x00004000 /* Send pause frame when RxFIFO reaches its = 0x00004000 /* Send pause frame when RxFIFO reaches its
emergency threshold */ emergency threshold */
} ucc_geth_flow_control_mode_e; };
/* UCC GETH number of threads */ /* UCC GETH number of threads */
typedef enum ucc_geth_num_of_threads { enum ucc_geth_num_of_threads {
UCC_GETH_NUM_OF_THREADS_1 = 0x1, /* 1 */ UCC_GETH_NUM_OF_THREADS_1 = 0x1, /* 1 */
UCC_GETH_NUM_OF_THREADS_2 = 0x2, /* 2 */ UCC_GETH_NUM_OF_THREADS_2 = 0x2, /* 2 */
UCC_GETH_NUM_OF_THREADS_4 = 0x0, /* 4 */ UCC_GETH_NUM_OF_THREADS_4 = 0x0, /* 4 */
UCC_GETH_NUM_OF_THREADS_6 = 0x3, /* 6 */ UCC_GETH_NUM_OF_THREADS_6 = 0x3, /* 6 */
UCC_GETH_NUM_OF_THREADS_8 = 0x4 /* 8 */ UCC_GETH_NUM_OF_THREADS_8 = 0x4 /* 8 */
} ucc_geth_num_of_threads_e; };
/* UCC GETH number of station addresses */ /* UCC GETH number of station addresses */
typedef enum ucc_geth_num_of_station_addresses { enum ucc_geth_num_of_station_addresses {
UCC_GETH_NUM_OF_STATION_ADDRESSES_1, /* 1 */ UCC_GETH_NUM_OF_STATION_ADDRESSES_1, /* 1 */
UCC_GETH_NUM_OF_STATION_ADDRESSES_5 /* 5 */ UCC_GETH_NUM_OF_STATION_ADDRESSES_5 /* 5 */
} ucc_geth_num_of_station_addresses_e; };
typedef u8 enet_addr_t[ENET_NUM_OCTETS_PER_ADDRESS];
/* UCC GETH 82xx Ethernet Address Container */ /* UCC GETH 82xx Ethernet Address Container */
typedef struct enet_addr_container { struct enet_addr_container {
enet_addr_t address; /* ethernet address */ u8 address[ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */
ucc_geth_enet_address_recognition_location_e location; /* location in enum ucc_geth_enet_address_recognition_location location; /* location in
82xx address 82xx address
recognition recognition
hardware */ hardware */
struct list_head node; struct list_head node;
} enet_addr_container_t; };
#define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, enet_addr_container_t, node) #define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, struct enet_addr_container, node)
/* UCC GETH Termination Action Descriptor (TAD) structure. */ /* UCC GETH Termination Action Descriptor (TAD) structure. */
typedef struct ucc_geth_tad_params { struct ucc_geth_tad_params {
int rx_non_dynamic_extended_features_mode; int rx_non_dynamic_extended_features_mode;
int reject_frame; int reject_frame;
ucc_geth_vlan_operation_tagged_e vtag_op; enum ucc_geth_vlan_operation_tagged vtag_op;
ucc_geth_vlan_operation_non_tagged_e vnontag_op; enum ucc_geth_vlan_operation_non_tagged vnontag_op;
ucc_geth_qos_mode_e rqos; enum ucc_geth_qos_mode rqos;
u8 vpri; u8 vpri;
u16 vid; u16 vid;
} ucc_geth_tad_params_t; };
/* GETH protocol initialization structure */ /* GETH protocol initialization structure */
typedef struct ucc_geth_info { struct ucc_geth_info {
ucc_fast_info_t uf_info; struct ucc_fast_info uf_info;
u8 numQueuesTx; u8 numQueuesTx;
u8 numQueuesRx; u8 numQueuesRx;
int ipCheckSumCheck; int ipCheckSumCheck;
@ -1251,51 +1249,51 @@ typedef struct ucc_geth_info {
u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX]; u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX];
u16 bdRingLenTx[NUM_TX_QUEUES]; u16 bdRingLenTx[NUM_TX_QUEUES];
u16 bdRingLenRx[NUM_RX_QUEUES]; u16 bdRingLenRx[NUM_RX_QUEUES];
enet_interface_e enet_interface; enum enet_interface enet_interface;
ucc_geth_num_of_station_addresses_e numStationAddresses; enum ucc_geth_num_of_station_addresses numStationAddresses;
qe_fltr_largest_external_tbl_lookup_key_size_e enum qe_fltr_largest_external_tbl_lookup_key_size
largestexternallookupkeysize; largestexternallookupkeysize;
ucc_geth_statistics_gathering_mode_e statisticsMode; enum ucc_geth_statistics_gathering_mode statisticsMode;
ucc_geth_vlan_operation_tagged_e vlanOperationTagged; enum ucc_geth_vlan_operation_tagged vlanOperationTagged;
ucc_geth_vlan_operation_non_tagged_e vlanOperationNonTagged; enum ucc_geth_vlan_operation_non_tagged vlanOperationNonTagged;
ucc_geth_qos_mode_e rxQoSMode; enum ucc_geth_qos_mode rxQoSMode;
ucc_geth_flow_control_mode_e aufc; enum ucc_geth_flow_control_mode aufc;
ucc_geth_maccfg2_pad_and_crc_mode_e padAndCrc; enum ucc_geth_maccfg2_pad_and_crc_mode padAndCrc;
ucc_geth_num_of_threads_e numThreadsTx; enum ucc_geth_num_of_threads numThreadsTx;
ucc_geth_num_of_threads_e numThreadsRx; enum ucc_geth_num_of_threads numThreadsRx;
qe_risc_allocation_e riscTx; enum qe_risc_allocation riscTx;
qe_risc_allocation_e riscRx; enum qe_risc_allocation riscRx;
} ucc_geth_info_t; };
/* structure representing UCC GETH */ /* structure representing UCC GETH */
typedef struct ucc_geth_private { struct ucc_geth_private {
ucc_geth_info_t *ug_info; struct ucc_geth_info *ug_info;
ucc_fast_private_t *uccf; struct ucc_fast_private *uccf;
struct net_device *dev; struct net_device *dev;
struct net_device_stats stats; /* linux network statistics */ struct net_device_stats stats; /* linux network statistics */
ucc_geth_t *ug_regs; struct ucc_geth *ug_regs;
ucc_geth_init_pram_t *p_init_enet_param_shadow; struct ucc_geth_init_pram *p_init_enet_param_shadow;
ucc_geth_exf_global_pram_t *p_exf_glbl_param; struct ucc_geth_exf_global_pram *p_exf_glbl_param;
u32 exf_glbl_param_offset; u32 exf_glbl_param_offset;
ucc_geth_rx_global_pram_t *p_rx_glbl_pram; struct ucc_geth_rx_global_pram *p_rx_glbl_pram;
u32 rx_glbl_pram_offset; u32 rx_glbl_pram_offset;
ucc_geth_tx_global_pram_t *p_tx_glbl_pram; struct ucc_geth_tx_global_pram *p_tx_glbl_pram;
u32 tx_glbl_pram_offset; u32 tx_glbl_pram_offset;
ucc_geth_send_queue_mem_region_t *p_send_q_mem_reg; struct ucc_geth_send_queue_mem_region *p_send_q_mem_reg;
u32 send_q_mem_reg_offset; u32 send_q_mem_reg_offset;
ucc_geth_thread_data_tx_t *p_thread_data_tx; struct ucc_geth_thread_data_tx *p_thread_data_tx;
u32 thread_dat_tx_offset; u32 thread_dat_tx_offset;
ucc_geth_thread_data_rx_t *p_thread_data_rx; struct ucc_geth_thread_data_rx *p_thread_data_rx;
u32 thread_dat_rx_offset; u32 thread_dat_rx_offset;
ucc_geth_scheduler_t *p_scheduler; struct ucc_geth_scheduler *p_scheduler;
u32 scheduler_offset; u32 scheduler_offset;
ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram; struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram;
u32 tx_fw_statistics_pram_offset; u32 tx_fw_statistics_pram_offset;
ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram; struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram;
u32 rx_fw_statistics_pram_offset; u32 rx_fw_statistics_pram_offset;
ucc_geth_rx_interrupt_coalescing_table_t *p_rx_irq_coalescing_tbl; struct ucc_geth_rx_interrupt_coalescing_table *p_rx_irq_coalescing_tbl;
u32 rx_irq_coalescing_tbl_offset; u32 rx_irq_coalescing_tbl_offset;
ucc_geth_rx_bd_queues_entry_t *p_rx_bd_qs_tbl; struct ucc_geth_rx_bd_queues_entry *p_rx_bd_qs_tbl;
u32 rx_bd_qs_tbl_offset; u32 rx_bd_qs_tbl_offset;
u8 *p_tx_bd_ring[NUM_TX_QUEUES]; u8 *p_tx_bd_ring[NUM_TX_QUEUES];
u32 tx_bd_ring_offset[NUM_TX_QUEUES]; u32 tx_bd_ring_offset[NUM_TX_QUEUES];
@ -1308,7 +1306,7 @@ typedef struct ucc_geth_private {
u16 cpucount[NUM_TX_QUEUES]; u16 cpucount[NUM_TX_QUEUES];
volatile u16 *p_cpucount[NUM_TX_QUEUES]; volatile u16 *p_cpucount[NUM_TX_QUEUES];
int indAddrRegUsed[NUM_OF_PADDRS]; int indAddrRegUsed[NUM_OF_PADDRS];
enet_addr_t paddr[NUM_OF_PADDRS]; u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS]; /* ethernet address */
u8 numGroupAddrInHash; u8 numGroupAddrInHash;
u8 numIndAddrInHash; u8 numIndAddrInHash;
u8 numIndAddrInReg; u8 numIndAddrInReg;
@ -1334,6 +1332,6 @@ typedef struct ucc_geth_private {
int oldspeed; int oldspeed;
int oldduplex; int oldduplex;
int oldlink; int oldlink;
} ucc_geth_private_t; };
#endif /* __UCC_GETH_H__ */ #endif /* __UCC_GETH_H__ */

View file

@ -42,7 +42,6 @@
#include "ucc_geth.h" #include "ucc_geth.h"
#include "ucc_geth_phy.h" #include "ucc_geth_phy.h"
#include <platforms/83xx/mpc8360e_pb.h>
#define ugphy_printk(level, format, arg...) \ #define ugphy_printk(level, format, arg...) \
printk(level format "\n", ## arg) printk(level format "\n", ## arg)
@ -72,16 +71,14 @@ static int genmii_read_status(struct ugeth_mii_info *mii_info);
u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum); u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum);
void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val); void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val);
static u8 *bcsr_regs = NULL;
/* Write value to the PHY for this device to the register at regnum, */ /* Write value to the PHY for this device to the register at regnum, */
/* waiting until the write is done before it returns. All PHY */ /* waiting until the write is done before it returns. All PHY */
/* configuration has to be done through the TSEC1 MIIM regs */ /* configuration has to be done through the TSEC1 MIIM regs */
void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
{ {
ucc_geth_private_t *ugeth = netdev_priv(dev); struct ucc_geth_private *ugeth = netdev_priv(dev);
ucc_mii_mng_t *mii_regs; struct ucc_mii_mng *mii_regs;
enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum;
u32 tmp_reg; u32 tmp_reg;
ugphy_vdbg("%s: IN", __FUNCTION__); ugphy_vdbg("%s: IN", __FUNCTION__);
@ -116,9 +113,9 @@ void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
/* configuration has to be done through the TSEC1 MIIM regs */ /* configuration has to be done through the TSEC1 MIIM regs */
int read_phy_reg(struct net_device *dev, int mii_id, int regnum) int read_phy_reg(struct net_device *dev, int mii_id, int regnum)
{ {
ucc_geth_private_t *ugeth = netdev_priv(dev); struct ucc_geth_private *ugeth = netdev_priv(dev);
ucc_mii_mng_t *mii_regs; struct ucc_mii_mng *mii_regs;
enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum; enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum;
u32 tmp_reg; u32 tmp_reg;
u16 value; u16 value;
@ -634,11 +631,6 @@ static void dm9161_close(struct ugeth_mii_info *mii_info)
static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info) static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info)
{ {
/* FIXME: This lines are for BUG fixing in the mpc8325.
Remove this from here when it's fixed */
if (bcsr_regs == NULL)
bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
bcsr_regs[14] |= 0x40;
ugphy_vdbg("%s: IN", __FUNCTION__); ugphy_vdbg("%s: IN", __FUNCTION__);
/* Clear the interrupts by reading the reg */ /* Clear the interrupts by reading the reg */
@ -650,12 +642,6 @@ Remove this from here when it's fixed */
static int dm9161_config_intr(struct ugeth_mii_info *mii_info) static int dm9161_config_intr(struct ugeth_mii_info *mii_info)
{ {
/* FIXME: This lines are for BUG fixing in the mpc8325.
Remove this from here when it's fixed */
if (bcsr_regs == NULL) {
bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
bcsr_regs[14] &= ~0x40;
}
ugphy_vdbg("%s: IN", __FUNCTION__); ugphy_vdbg("%s: IN", __FUNCTION__);
if (mii_info->interrupts == MII_INTERRUPT_ENABLED) if (mii_info->interrupts == MII_INTERRUPT_ENABLED)

View file

@ -126,7 +126,7 @@ struct ugeth_mii_info {
/* And management functions */ /* And management functions */
struct phy_info *phyinfo; struct phy_info *phyinfo;
ucc_mii_mng_t *mii_regs; struct ucc_mii_mng *mii_regs;
/* forced speed & duplex (no autoneg) /* forced speed & duplex (no autoneg)
* partner speed & duplex & pause (autoneg) * partner speed & duplex & pause (autoneg)

View file

@ -2867,7 +2867,6 @@ static int ch_config(pc300dev_t * d)
uclong clktype = chan->conf.phys_settings.clock_type; uclong clktype = chan->conf.phys_settings.clock_type;
ucshort encoding = chan->conf.proto_settings.encoding; ucshort encoding = chan->conf.proto_settings.encoding;
ucshort parity = chan->conf.proto_settings.parity; ucshort parity = chan->conf.proto_settings.parity;
int tmc, br;
ucchar md0, md2; ucchar md0, md2;
/* Reset the channel */ /* Reset the channel */
@ -2940,8 +2939,12 @@ static int ch_config(pc300dev_t * d)
case PC300_RSV: case PC300_RSV:
case PC300_X21: case PC300_X21:
if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) { if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) {
int tmc, br;
/* Calculate the clkrate parameters */ /* Calculate the clkrate parameters */
tmc = clock_rate_calc(clkrate, card->hw.clock, &br); tmc = clock_rate_calc(clkrate, card->hw.clock, &br);
if (tmc < 0)
return -EIO;
cpc_writeb(scabase + M_REG(TMCT, ch), tmc); cpc_writeb(scabase + M_REG(TMCT, ch), tmc);
cpc_writeb(scabase + M_REG(TXS, ch), cpc_writeb(scabase + M_REG(TXS, ch),
(TXS_DTRXC | TXS_IBRG | br)); (TXS_DTRXC | TXS_IBRG | br));
@ -3097,14 +3100,16 @@ static int cpc_attach(struct net_device *dev, unsigned short encoding,
return 0; return 0;
} }
static void cpc_opench(pc300dev_t * d) static int cpc_opench(pc300dev_t * d)
{ {
pc300ch_t *chan = (pc300ch_t *) d->chan; pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card; pc300_t *card = (pc300_t *) chan->card;
int ch = chan->channel; int ch = chan->channel, rc;
void __iomem *scabase = card->hw.scabase; void __iomem *scabase = card->hw.scabase;
ch_config(d); rc = ch_config(d);
if (rc)
return rc;
rx_config(d); rx_config(d);
@ -3113,6 +3118,8 @@ static void cpc_opench(pc300dev_t * d)
/* Assert RTS and DTR */ /* Assert RTS and DTR */
cpc_writeb(scabase + M_REG(CTL, ch), cpc_writeb(scabase + M_REG(CTL, ch),
cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR)); cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR));
return 0;
} }
static void cpc_closech(pc300dev_t * d) static void cpc_closech(pc300dev_t * d)
@ -3168,9 +3175,16 @@ int cpc_open(struct net_device *dev)
} }
sprintf(ifr.ifr_name, "%s", dev->name); sprintf(ifr.ifr_name, "%s", dev->name);
cpc_opench(d); result = cpc_opench(d);
if (result)
goto err_out;
netif_start_queue(dev); netif_start_queue(dev);
return 0; return 0;
err_out:
hdlc_close(dev);
return result;
} }
static int cpc_close(struct net_device *dev) static int cpc_close(struct net_device *dev)

View file

@ -2897,6 +2897,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
goto err_out_map; goto err_out_map;
} }
ai->wifidev = init_wifidev(ai, dev); ai->wifidev = init_wifidev(ai, dev);
if (!ai->wifidev)
goto err_out_reg;
set_bit(FLAG_REGISTERED,&ai->flags); set_bit(FLAG_REGISTERED,&ai->flags);
airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x", airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x",
@ -2908,11 +2910,18 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
for( i = 0; i < MAX_FIDS; i++ ) for( i = 0; i < MAX_FIDS; i++ )
ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2); ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
setup_proc_entry( dev, dev->priv ); /* XXX check for failure */ if (setup_proc_entry(dev, dev->priv) < 0)
goto err_out_wifi;
netif_start_queue(dev); netif_start_queue(dev);
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
return dev; return dev;
err_out_wifi:
unregister_netdev(ai->wifidev);
free_netdev(ai->wifidev);
err_out_reg:
unregister_netdev(dev);
err_out_map: err_out_map:
if (test_bit(FLAG_MPI,&ai->flags) && pci) { if (test_bit(FLAG_MPI,&ai->flags) && pci) {
pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma); pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
@ -3089,7 +3098,8 @@ static int airo_thread(void *data) {
set_bit(JOB_AUTOWEP, &ai->jobs); set_bit(JOB_AUTOWEP, &ai->jobs);
break; break;
} }
if (!kthread_should_stop()) { if (!kthread_should_stop() &&
!freezing(current)) {
unsigned long wake_at; unsigned long wake_at;
if (!ai->expires || !ai->scan_timeout) { if (!ai->expires || !ai->scan_timeout) {
wake_at = max(ai->expires, wake_at = max(ai->expires,
@ -3101,7 +3111,8 @@ static int airo_thread(void *data) {
schedule_timeout(wake_at - jiffies); schedule_timeout(wake_at - jiffies);
continue; continue;
} }
} else if (!kthread_should_stop()) { } else if (!kthread_should_stop() &&
!freezing(current)) {
schedule(); schedule();
continue; continue;
} }
@ -4495,6 +4506,8 @@ static int setup_proc_entry( struct net_device *dev,
apriv->proc_entry = create_proc_entry(apriv->proc_name, apriv->proc_entry = create_proc_entry(apriv->proc_name,
S_IFDIR|airo_perm, S_IFDIR|airo_perm,
airo_entry); airo_entry);
if (!apriv->proc_entry)
goto fail;
apriv->proc_entry->uid = proc_uid; apriv->proc_entry->uid = proc_uid;
apriv->proc_entry->gid = proc_gid; apriv->proc_entry->gid = proc_gid;
apriv->proc_entry->owner = THIS_MODULE; apriv->proc_entry->owner = THIS_MODULE;
@ -4503,6 +4516,8 @@ static int setup_proc_entry( struct net_device *dev,
entry = create_proc_entry("StatsDelta", entry = create_proc_entry("StatsDelta",
S_IFREG | (S_IRUGO&proc_perm), S_IFREG | (S_IRUGO&proc_perm),
apriv->proc_entry); apriv->proc_entry);
if (!entry)
goto fail_stats_delta;
entry->uid = proc_uid; entry->uid = proc_uid;
entry->gid = proc_gid; entry->gid = proc_gid;
entry->data = dev; entry->data = dev;
@ -4513,6 +4528,8 @@ static int setup_proc_entry( struct net_device *dev,
entry = create_proc_entry("Stats", entry = create_proc_entry("Stats",
S_IFREG | (S_IRUGO&proc_perm), S_IFREG | (S_IRUGO&proc_perm),
apriv->proc_entry); apriv->proc_entry);
if (!entry)
goto fail_stats;
entry->uid = proc_uid; entry->uid = proc_uid;
entry->gid = proc_gid; entry->gid = proc_gid;
entry->data = dev; entry->data = dev;
@ -4523,6 +4540,8 @@ static int setup_proc_entry( struct net_device *dev,
entry = create_proc_entry("Status", entry = create_proc_entry("Status",
S_IFREG | (S_IRUGO&proc_perm), S_IFREG | (S_IRUGO&proc_perm),
apriv->proc_entry); apriv->proc_entry);
if (!entry)
goto fail_status;
entry->uid = proc_uid; entry->uid = proc_uid;
entry->gid = proc_gid; entry->gid = proc_gid;
entry->data = dev; entry->data = dev;
@ -4533,6 +4552,8 @@ static int setup_proc_entry( struct net_device *dev,
entry = create_proc_entry("Config", entry = create_proc_entry("Config",
S_IFREG | proc_perm, S_IFREG | proc_perm,
apriv->proc_entry); apriv->proc_entry);
if (!entry)
goto fail_config;
entry->uid = proc_uid; entry->uid = proc_uid;
entry->gid = proc_gid; entry->gid = proc_gid;
entry->data = dev; entry->data = dev;
@ -4543,6 +4564,8 @@ static int setup_proc_entry( struct net_device *dev,
entry = create_proc_entry("SSID", entry = create_proc_entry("SSID",
S_IFREG | proc_perm, S_IFREG | proc_perm,
apriv->proc_entry); apriv->proc_entry);
if (!entry)
goto fail_ssid;
entry->uid = proc_uid; entry->uid = proc_uid;
entry->gid = proc_gid; entry->gid = proc_gid;
entry->data = dev; entry->data = dev;
@ -4553,6 +4576,8 @@ static int setup_proc_entry( struct net_device *dev,
entry = create_proc_entry("APList", entry = create_proc_entry("APList",
S_IFREG | proc_perm, S_IFREG | proc_perm,
apriv->proc_entry); apriv->proc_entry);
if (!entry)
goto fail_aplist;
entry->uid = proc_uid; entry->uid = proc_uid;
entry->gid = proc_gid; entry->gid = proc_gid;
entry->data = dev; entry->data = dev;
@ -4563,6 +4588,8 @@ static int setup_proc_entry( struct net_device *dev,
entry = create_proc_entry("BSSList", entry = create_proc_entry("BSSList",
S_IFREG | proc_perm, S_IFREG | proc_perm,
apriv->proc_entry); apriv->proc_entry);
if (!entry)
goto fail_bsslist;
entry->uid = proc_uid; entry->uid = proc_uid;
entry->gid = proc_gid; entry->gid = proc_gid;
entry->data = dev; entry->data = dev;
@ -4573,6 +4600,8 @@ static int setup_proc_entry( struct net_device *dev,
entry = create_proc_entry("WepKey", entry = create_proc_entry("WepKey",
S_IFREG | proc_perm, S_IFREG | proc_perm,
apriv->proc_entry); apriv->proc_entry);
if (!entry)
goto fail_wepkey;
entry->uid = proc_uid; entry->uid = proc_uid;
entry->gid = proc_gid; entry->gid = proc_gid;
entry->data = dev; entry->data = dev;
@ -4580,6 +4609,25 @@ static int setup_proc_entry( struct net_device *dev,
SETPROC_OPS(entry, proc_wepkey_ops); SETPROC_OPS(entry, proc_wepkey_ops);
return 0; return 0;
fail_wepkey:
remove_proc_entry("BSSList", apriv->proc_entry);
fail_bsslist:
remove_proc_entry("APList", apriv->proc_entry);
fail_aplist:
remove_proc_entry("SSID", apriv->proc_entry);
fail_ssid:
remove_proc_entry("Config", apriv->proc_entry);
fail_config:
remove_proc_entry("Status", apriv->proc_entry);
fail_status:
remove_proc_entry("Stats", apriv->proc_entry);
fail_stats:
remove_proc_entry("StatsDelta", apriv->proc_entry);
fail_stats_delta:
remove_proc_entry(apriv->proc_name, airo_entry);
fail:
return -ENOMEM;
} }
static int takedown_proc_entry( struct net_device *dev, static int takedown_proc_entry( struct net_device *dev,
@ -5924,7 +5972,6 @@ static int airo_get_essid(struct net_device *dev,
/* Get the current SSID */ /* Get the current SSID */
memcpy(extra, status_rid.SSID, status_rid.SSIDlen); memcpy(extra, status_rid.SSID, status_rid.SSIDlen);
extra[status_rid.SSIDlen] = '\0';
/* If none, we may want to get the one that was set */ /* If none, we may want to get the one that was set */
/* Push it out ! */ /* Push it out ! */

View file

@ -1678,11 +1678,9 @@ static int atmel_get_essid(struct net_device *dev,
/* Get the current SSID */ /* Get the current SSID */
if (priv->new_SSID_size != 0) { if (priv->new_SSID_size != 0) {
memcpy(extra, priv->new_SSID, priv->new_SSID_size); memcpy(extra, priv->new_SSID, priv->new_SSID_size);
extra[priv->new_SSID_size] = '\0';
dwrq->length = priv->new_SSID_size; dwrq->length = priv->new_SSID_size;
} else { } else {
memcpy(extra, priv->SSID, priv->SSID_size); memcpy(extra, priv->SSID, priv->SSID_size);
extra[priv->SSID_size] = '\0';
dwrq->length = priv->SSID_size; dwrq->length = priv->SSID_size;
} }

View file

@ -705,11 +705,30 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
struct bcm43xx_dmaring *ring; struct bcm43xx_dmaring *ring;
int err = -ENOMEM; int err = -ENOMEM;
int dma64 = 0; int dma64 = 0;
u32 sbtmstatehi; u64 mask = bcm43xx_get_supported_dma_mask(bcm);
int nobits;
sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); if (mask == DMA_64BIT_MASK) {
if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT)
dma64 = 1; dma64 = 1;
nobits = 64;
} else if (mask == DMA_32BIT_MASK)
nobits = 32;
else
nobits = 30;
err = pci_set_dma_mask(bcm->pci_dev, mask);
err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask);
if (err) {
#ifdef CONFIG_BCM43XX_PIO
printk(KERN_WARNING PFX "DMA not supported on this device."
" Falling back to PIO.\n");
bcm->__using_pio = 1;
return -ENOSYS;
#else
printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
"Please recompile the driver with PIO support.\n");
return -ENODEV;
#endif /* CONFIG_BCM43XX_PIO */
}
/* setup TX DMA channels. */ /* setup TX DMA channels. */
ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64); ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
@ -755,8 +774,7 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
dma->rx_ring3 = ring; dma->rx_ring3 = ring;
} }
dprintk(KERN_INFO PFX "%s DMA initialized\n", dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits);
dma64 ? "64-bit" : "32-bit");
err = 0; err = 0;
out: out:
return err; return err;

View file

@ -314,6 +314,23 @@ int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
struct ieee80211_txb *txb); struct ieee80211_txb *txb);
void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
/* Helper function that returns the dma mask for this device. */
static inline
u64 bcm43xx_get_supported_dma_mask(struct bcm43xx_private *bcm)
{
int dma64 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH) &
BCM43xx_SBTMSTATEHIGH_DMA64BIT;
u16 mmio_base = bcm43xx_dmacontroller_base(dma64, 0);
u32 mask = BCM43xx_DMA32_TXADDREXT_MASK;
if (dma64)
return DMA_64BIT_MASK;
bcm43xx_write32(bcm, mmio_base + BCM43xx_DMA32_TXCTL, mask);
if (bcm43xx_read32(bcm, mmio_base + BCM43xx_DMA32_TXCTL) & mask)
return DMA_32BIT_MASK;
return DMA_30BIT_MASK;
}
#else /* CONFIG_BCM43XX_DMA */ #else /* CONFIG_BCM43XX_DMA */

View file

@ -242,7 +242,7 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
//TODO //TODO
break; break;
case BCM43xx_LED_ASSOC: case BCM43xx_LED_ASSOC:
if (bcm->softmac->associated) if (bcm->softmac->associnfo.associated)
turn_on = 1; turn_on = 1;
break; break;
#ifdef CONFIG_BCM43XX_DEBUG #ifdef CONFIG_BCM43XX_DEBUG

View file

@ -2925,10 +2925,13 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
bcm43xx_write16(bcm, 0x043C, 0x000C); bcm43xx_write16(bcm, 0x043C, 0x000C);
if (active_wlcore) { if (active_wlcore) {
if (bcm43xx_using_pio(bcm)) if (bcm43xx_using_pio(bcm)) {
err = bcm43xx_pio_init(bcm); err = bcm43xx_pio_init(bcm);
else } else {
err = bcm43xx_dma_init(bcm); err = bcm43xx_dma_init(bcm);
if (err == -ENOSYS)
err = bcm43xx_pio_init(bcm);
}
if (err) if (err)
goto err_chip_cleanup; goto err_chip_cleanup;
} }
@ -3164,12 +3167,12 @@ static void bcm43xx_periodic_work_handler(void *d)
u32 savedirqs = 0; u32 savedirqs = 0;
int badness; int badness;
mutex_lock(&bcm->mutex);
badness = estimate_periodic_work_badness(bcm->periodic_state); badness = estimate_periodic_work_badness(bcm->periodic_state);
if (badness > BADNESS_LIMIT) { if (badness > BADNESS_LIMIT) {
/* Periodic work will take a long time, so we want it to /* Periodic work will take a long time, so we want it to
* be preemtible. * be preemtible.
*/ */
mutex_lock(&bcm->mutex);
netif_tx_disable(bcm->net_dev); netif_tx_disable(bcm->net_dev);
spin_lock_irqsave(&bcm->irq_lock, flags); spin_lock_irqsave(&bcm->irq_lock, flags);
bcm43xx_mac_suspend(bcm); bcm43xx_mac_suspend(bcm);
@ -3182,7 +3185,6 @@ static void bcm43xx_periodic_work_handler(void *d)
/* Periodic work should take short time, so we want low /* Periodic work should take short time, so we want low
* locking overhead. * locking overhead.
*/ */
mutex_lock(&bcm->mutex);
spin_lock_irqsave(&bcm->irq_lock, flags); spin_lock_irqsave(&bcm->irq_lock, flags);
} }
@ -3993,8 +3995,6 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
struct net_device *net_dev, struct net_device *net_dev,
struct pci_dev *pci_dev) struct pci_dev *pci_dev)
{ {
int err;
bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
bcm->ieee = netdev_priv(net_dev); bcm->ieee = netdev_priv(net_dev);
bcm->softmac = ieee80211_priv(net_dev); bcm->softmac = ieee80211_priv(net_dev);
@ -4012,22 +4012,8 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
(void (*)(unsigned long))bcm43xx_interrupt_tasklet, (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
(unsigned long)bcm); (unsigned long)bcm);
tasklet_disable_nosync(&bcm->isr_tasklet); tasklet_disable_nosync(&bcm->isr_tasklet);
if (modparam_pio) { if (modparam_pio)
bcm->__using_pio = 1; bcm->__using_pio = 1;
} else {
err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK);
err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK);
if (err) {
#ifdef CONFIG_BCM43XX_PIO
printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
bcm->__using_pio = 1;
#else
printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
"Recompile the driver with PIO support, please.\n");
return -ENODEV;
#endif /* CONFIG_BCM43XX_PIO */
}
}
bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD; bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
/* default to sw encryption for now */ /* default to sw encryption for now */
@ -4208,7 +4194,11 @@ static int bcm43xx_resume(struct pci_dev *pdev)
dprintk(KERN_INFO PFX "Resuming...\n"); dprintk(KERN_INFO PFX "Resuming...\n");
pci_set_power_state(pdev, 0); pci_set_power_state(pdev, 0);
pci_enable_device(pdev); err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR PFX "Failure with pci_enable_device!\n");
return err;
}
pci_restore_state(pdev); pci_restore_state(pdev);
bcm43xx_chipset_attach(bcm); bcm43xx_chipset_attach(bcm);

View file

@ -847,7 +847,7 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d
unsigned long flags; unsigned long flags;
wstats = &bcm->stats.wstats; wstats = &bcm->stats.wstats;
if (!mac->associated) { if (!mac->associnfo.associated) {
wstats->miss.beacon = 0; wstats->miss.beacon = 0;
// bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? // bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here?
wstats->discard.retries = 0; wstats->discard.retries = 0;

View file

@ -2457,6 +2457,7 @@ void free_orinocodev(struct net_device *dev)
/* Wireless extensions */ /* Wireless extensions */
/********************************************************************/ /********************************************************************/
/* Return : < 0 -> error code ; >= 0 -> length */
static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
char buf[IW_ESSID_MAX_SIZE+1]) char buf[IW_ESSID_MAX_SIZE+1])
{ {
@ -2501,9 +2502,9 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
len = le16_to_cpu(essidbuf.len); len = le16_to_cpu(essidbuf.len);
BUG_ON(len > IW_ESSID_MAX_SIZE); BUG_ON(len > IW_ESSID_MAX_SIZE);
memset(buf, 0, IW_ESSID_MAX_SIZE+1); memset(buf, 0, IW_ESSID_MAX_SIZE);
memcpy(buf, p, len); memcpy(buf, p, len);
buf[len] = '\0'; err = len;
fail_unlock: fail_unlock:
orinoco_unlock(priv, &flags); orinoco_unlock(priv, &flags);
@ -3027,17 +3028,18 @@ static int orinoco_ioctl_getessid(struct net_device *dev,
if (netif_running(dev)) { if (netif_running(dev)) {
err = orinoco_hw_get_essid(priv, &active, essidbuf); err = orinoco_hw_get_essid(priv, &active, essidbuf);
if (err) if (err < 0)
return err; return err;
erq->length = err;
} else { } else {
if (orinoco_lock(priv, &flags) != 0) if (orinoco_lock(priv, &flags) != 0)
return -EBUSY; return -EBUSY;
memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1); memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
erq->length = strlen(priv->desired_essid);
orinoco_unlock(priv, &flags); orinoco_unlock(priv, &flags);
} }
erq->flags = 1; erq->flags = 1;
erq->length = strlen(essidbuf);
return 0; return 0;
} }
@ -3075,10 +3077,10 @@ static int orinoco_ioctl_getnick(struct net_device *dev,
if (orinoco_lock(priv, &flags) != 0) if (orinoco_lock(priv, &flags) != 0)
return -EBUSY; return -EBUSY;
memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1); memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
orinoco_unlock(priv, &flags); orinoco_unlock(priv, &flags);
nrq->length = strlen(nickbuf); nrq->length = strlen(priv->nick);
return 0; return 0;
} }

View file

@ -1198,7 +1198,6 @@ static int ray_get_essid(struct net_device *dev,
/* Get the essid that was set */ /* Get the essid that was set */
memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
extra[IW_ESSID_MAX_SIZE] = '\0';
/* Push it out ! */ /* Push it out ! */
dwrq->length = strlen(extra); dwrq->length = strlen(extra);

View file

@ -193,10 +193,8 @@ static void zd1201_usbrx(struct urb *urb)
struct sk_buff *skb; struct sk_buff *skb;
unsigned char type; unsigned char type;
if (!zd) { if (!zd)
free = 1; return;
goto exit;
}
switch(urb->status) { switch(urb->status) {
case -EILSEQ: case -EILSEQ:

View file

@ -1099,7 +1099,7 @@ static void link_led_handler(void *p)
int r; int r;
spin_lock_irq(&mac->lock); spin_lock_irq(&mac->lock);
is_associated = sm->associated != 0; is_associated = sm->associnfo.associated != 0;
spin_unlock_irq(&mac->lock); spin_unlock_irq(&mac->lock);
r = zd_chip_control_leds(chip, r = zd_chip_control_leds(chip,

View file

@ -63,13 +63,11 @@ struct ieee80211softmac_wpa {
/* /*
* Information about association * Information about association
*
* Do we need a lock for this?
* We only ever use this structure inlined
* into our global struct. I've used its lock,
* but maybe we need a local one here?
*/ */
struct ieee80211softmac_assoc_info { struct ieee80211softmac_assoc_info {
struct mutex mutex;
/* /*
* This is the requested ESSID. It is written * This is the requested ESSID. It is written
* only by the WX handlers. * only by the WX handlers.
@ -99,12 +97,13 @@ struct ieee80211softmac_assoc_info {
* *
* bssfixed is used for SIOCSIWAP. * bssfixed is used for SIOCSIWAP.
*/ */
u8 static_essid:1, u8 static_essid;
short_preamble_available:1, u8 short_preamble_available;
associating:1, u8 associating;
assoc_wait:1, u8 associated;
bssvalid:1, u8 assoc_wait;
bssfixed:1; u8 bssvalid;
u8 bssfixed;
/* Scan retries remaining */ /* Scan retries remaining */
int scan_retry; int scan_retry;
@ -230,10 +229,8 @@ struct ieee80211softmac_device {
/* this lock protects this structure */ /* this lock protects this structure */
spinlock_t lock; spinlock_t lock;
/* couple of flags */ u8 running; /* SoftMAC started? */
u8 scanning:1, /* protects scanning from being done multiple times at once */ u8 scanning;
associated:1,
running:1;
struct ieee80211softmac_scaninfo *scaninfo; struct ieee80211softmac_scaninfo *scaninfo;
struct ieee80211softmac_assoc_info associnfo; struct ieee80211softmac_assoc_info associnfo;
@ -295,7 +292,7 @@ static inline u8 ieee80211softmac_suggest_txrate(struct ieee80211softmac_device
{ {
struct ieee80211softmac_txrates *txrates = &mac->txrates; struct ieee80211softmac_txrates *txrates = &mac->txrates;
if (!mac->associated) if (!mac->associnfo.associated)
return txrates->mgt_mcast_rate; return txrates->mgt_mcast_rate;
/* We are associated, sending unicast frame */ /* We are associated, sending unicast frame */

View file

@ -748,11 +748,39 @@ static int ioctl_standard_call(struct net_device * dev,
int extra_size; int extra_size;
int user_length = 0; int user_length = 0;
int err; int err;
int essid_compat = 0;
/* Calculate space needed by arguments. Always allocate /* Calculate space needed by arguments. Always allocate
* for max space. Easier, and won't last long... */ * for max space. Easier, and won't last long... */
extra_size = descr->max_tokens * descr->token_size; extra_size = descr->max_tokens * descr->token_size;
/* Check need for ESSID compatibility for WE < 21 */
switch (cmd) {
case SIOCSIWESSID:
case SIOCGIWESSID:
case SIOCSIWNICKN:
case SIOCGIWNICKN:
if (iwr->u.data.length == descr->max_tokens + 1)
essid_compat = 1;
else if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
char essid[IW_ESSID_MAX_SIZE + 1];
err = copy_from_user(essid, iwr->u.data.pointer,
iwr->u.data.length *
descr->token_size);
if (err)
return -EFAULT;
if (essid[iwr->u.data.length - 1] == '\0')
essid_compat = 1;
}
break;
default:
break;
}
iwr->u.data.length -= essid_compat;
/* Check what user space is giving us */ /* Check what user space is giving us */
if(IW_IS_SET(cmd)) { if(IW_IS_SET(cmd)) {
/* Check NULL pointer */ /* Check NULL pointer */
@ -795,7 +823,8 @@ static int ioctl_standard_call(struct net_device * dev,
#endif /* WE_IOCTL_DEBUG */ #endif /* WE_IOCTL_DEBUG */
/* Create the kernel buffer */ /* Create the kernel buffer */
extra = kmalloc(extra_size, GFP_KERNEL); /* kzalloc ensures NULL-termination for essid_compat */
extra = kzalloc(extra_size, GFP_KERNEL);
if (extra == NULL) { if (extra == NULL) {
return -ENOMEM; return -ENOMEM;
} }
@ -819,6 +848,8 @@ static int ioctl_standard_call(struct net_device * dev,
/* Call the handler */ /* Call the handler */
ret = handler(dev, &info, &(iwr->u), extra); ret = handler(dev, &info, &(iwr->u), extra);
iwr->u.data.length += essid_compat;
/* If we have something to return to the user */ /* If we have something to return to the user */
if (!ret && IW_IS_GET(cmd)) { if (!ret && IW_IS_GET(cmd)) {
/* Check if there is enough buffer up there */ /* Check if there is enough buffer up there */

View file

@ -48,7 +48,7 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft
dprintk(KERN_INFO PFX "sent association request!\n"); dprintk(KERN_INFO PFX "sent association request!\n");
spin_lock_irqsave(&mac->lock, flags); spin_lock_irqsave(&mac->lock, flags);
mac->associated = 0; /* just to make sure */ mac->associnfo.associated = 0; /* just to make sure */
/* Set a timer for timeout */ /* Set a timer for timeout */
/* FIXME: make timeout configurable */ /* FIXME: make timeout configurable */
@ -62,24 +62,22 @@ ieee80211softmac_assoc_timeout(void *d)
{ {
struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
struct ieee80211softmac_network *n; struct ieee80211softmac_network *n;
unsigned long flags;
spin_lock_irqsave(&mac->lock, flags); mutex_lock(&mac->associnfo.mutex);
/* we might race against ieee80211softmac_handle_assoc_response, /* we might race against ieee80211softmac_handle_assoc_response,
* so make sure only one of us does something */ * so make sure only one of us does something */
if (!mac->associnfo.associating) { if (!mac->associnfo.associating)
spin_unlock_irqrestore(&mac->lock, flags); goto out;
return;
}
mac->associnfo.associating = 0; mac->associnfo.associating = 0;
mac->associnfo.bssvalid = 0; mac->associnfo.bssvalid = 0;
mac->associated = 0; mac->associnfo.associated = 0;
n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid); n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid);
spin_unlock_irqrestore(&mac->lock, flags);
dprintk(KERN_INFO PFX "assoc request timed out!\n"); dprintk(KERN_INFO PFX "assoc request timed out!\n");
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n); ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n);
out:
mutex_unlock(&mac->associnfo.mutex);
} }
void void
@ -93,7 +91,7 @@ ieee80211softmac_disassoc(struct ieee80211softmac_device *mac)
netif_carrier_off(mac->dev); netif_carrier_off(mac->dev);
mac->associated = 0; mac->associnfo.associated = 0;
mac->associnfo.bssvalid = 0; mac->associnfo.bssvalid = 0;
mac->associnfo.associating = 0; mac->associnfo.associating = 0;
ieee80211softmac_init_bss(mac); ieee80211softmac_init_bss(mac);
@ -107,7 +105,7 @@ ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reas
{ {
struct ieee80211softmac_network *found; struct ieee80211softmac_network *found;
if (mac->associnfo.bssvalid && mac->associated) { if (mac->associnfo.bssvalid && mac->associnfo.associated) {
found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
if (found) if (found)
ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason); ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason);
@ -196,17 +194,18 @@ ieee80211softmac_assoc_work(void *d)
int bssvalid; int bssvalid;
unsigned long flags; unsigned long flags;
mutex_lock(&mac->associnfo.mutex);
if (!mac->associnfo.associating)
goto out;
/* ieee80211_disassoc might clear this */ /* ieee80211_disassoc might clear this */
bssvalid = mac->associnfo.bssvalid; bssvalid = mac->associnfo.bssvalid;
/* meh */ /* meh */
if (mac->associated) if (mac->associnfo.associated)
ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
spin_lock_irqsave(&mac->lock, flags);
mac->associnfo.associating = 1;
spin_unlock_irqrestore(&mac->lock, flags);
/* try to find the requested network in our list, if we found one already */ /* try to find the requested network in our list, if we found one already */
if (bssvalid || mac->associnfo.bssfixed) if (bssvalid || mac->associnfo.bssfixed)
found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
@ -260,9 +259,7 @@ ieee80211softmac_assoc_work(void *d)
if (!found) { if (!found) {
if (mac->associnfo.scan_retry > 0) { if (mac->associnfo.scan_retry > 0) {
spin_lock_irqsave(&mac->lock, flags);
mac->associnfo.scan_retry--; mac->associnfo.scan_retry--;
spin_unlock_irqrestore(&mac->lock, flags);
/* We know of no such network. Let's scan. /* We know of no such network. Let's scan.
* NB: this also happens if we had no memory to copy the network info... * NB: this also happens if we had no memory to copy the network info...
@ -272,19 +269,17 @@ ieee80211softmac_assoc_work(void *d)
ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL); ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
if (ieee80211softmac_start_scan(mac)) if (ieee80211softmac_start_scan(mac))
dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
return; goto out;
} else { } else {
spin_lock_irqsave(&mac->lock, flags);
mac->associnfo.associating = 0; mac->associnfo.associating = 0;
mac->associated = 0; mac->associnfo.associated = 0;
spin_unlock_irqrestore(&mac->lock, flags);
dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n");
/* reset the retry counter for the next user request since we /* reset the retry counter for the next user request since we
* break out and don't reschedule ourselves after this point. */ * break out and don't reschedule ourselves after this point. */
mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL);
return; goto out;
} }
} }
@ -305,7 +300,7 @@ ieee80211softmac_assoc_work(void *d)
mac->associnfo.assoc_wait = 1; mac->associnfo.assoc_wait = 1;
ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL); ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
} }
return; goto out;
} }
if (!found->authenticated && !found->authenticating) { if (!found->authenticated && !found->authenticating) {
/* This relies on the fact that _auth_req only queues the work, /* This relies on the fact that _auth_req only queues the work,
@ -321,11 +316,14 @@ ieee80211softmac_assoc_work(void *d)
mac->associnfo.assoc_wait = 0; mac->associnfo.assoc_wait = 0;
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
} }
return; goto out;
} }
/* finally! now we can start associating */ /* finally! now we can start associating */
mac->associnfo.assoc_wait = 0; mac->associnfo.assoc_wait = 0;
ieee80211softmac_assoc(mac, found); ieee80211softmac_assoc(mac, found);
out:
mutex_unlock(&mac->associnfo.mutex);
} }
/* call this to do whatever is necessary when we're associated */ /* call this to do whatever is necessary when we're associated */
@ -341,7 +339,7 @@ ieee80211softmac_associated(struct ieee80211softmac_device *mac,
mac->bssinfo.supported_rates = net->supported_rates; mac->bssinfo.supported_rates = net->supported_rates;
ieee80211softmac_recalc_txrates(mac); ieee80211softmac_recalc_txrates(mac);
mac->associated = 1; mac->associnfo.associated = 1;
mac->associnfo.short_preamble_available = mac->associnfo.short_preamble_available =
(cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0; (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0;
@ -421,7 +419,7 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev,
dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status); dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status);
mac->associnfo.associating = 0; mac->associnfo.associating = 0;
mac->associnfo.bssvalid = 0; mac->associnfo.bssvalid = 0;
mac->associated = 0; mac->associnfo.associated = 0;
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network); ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network);
} }

View file

@ -304,7 +304,7 @@ ieee80211softmac_auth(struct ieee80211_auth **pkt,
2 + /* Auth Transaction Seq */ 2 + /* Auth Transaction Seq */
2 + /* Status Code */ 2 + /* Status Code */
/* Challenge Text IE */ /* Challenge Text IE */
is_shared_response ? 0 : 1 + 1 + net->challenge_len (is_shared_response ? 1 + 1 + net->challenge_len : 0)
); );
if (unlikely((*pkt) == NULL)) if (unlikely((*pkt) == NULL))
return 0; return 0;
@ -475,8 +475,13 @@ int ieee80211softmac_handle_beacon(struct net_device *dev,
{ {
struct ieee80211softmac_device *mac = ieee80211_priv(dev); struct ieee80211softmac_device *mac = ieee80211_priv(dev);
if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) /* This might race, but we don't really care and it's not worth
* adding heavyweight locking in this fastpath.
*/
if (mac->associnfo.associated) {
if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
ieee80211softmac_process_erp(mac, network->erp_value); ieee80211softmac_process_erp(mac, network->erp_value);
}
return 0; return 0;
} }

View file

@ -57,6 +57,7 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv)
INIT_LIST_HEAD(&softmac->network_list); INIT_LIST_HEAD(&softmac->network_list);
INIT_LIST_HEAD(&softmac->events); INIT_LIST_HEAD(&softmac->events);
mutex_init(&softmac->associnfo.mutex);
INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac); INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac);
INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac); INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac);
softmac->start_scan = ieee80211softmac_start_scan_implementation; softmac->start_scan = ieee80211softmac_start_scan_implementation;

View file

@ -73,13 +73,14 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
struct ieee80211softmac_network *n; struct ieee80211softmac_network *n;
struct ieee80211softmac_auth_queue_item *authptr; struct ieee80211softmac_auth_queue_item *authptr;
int length = 0; int length = 0;
unsigned long flags;
mutex_lock(&sm->associnfo.mutex);
/* Check if we're already associating to this or another network /* Check if we're already associating to this or another network
* If it's another network, cancel and start over with our new network * If it's another network, cancel and start over with our new network
* If it's our network, ignore the change, we're already doing it! * If it's our network, ignore the change, we're already doing it!
*/ */
if((sm->associnfo.associating || sm->associated) && if((sm->associnfo.associating || sm->associnfo.associated) &&
(data->essid.flags && data->essid.length)) { (data->essid.flags && data->essid.length)) {
/* Get the associating network */ /* Get the associating network */
n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
@ -87,10 +88,9 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
!memcmp(n->essid.data, extra, n->essid.len)) { !memcmp(n->essid.data, extra, n->essid.len)) {
dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n",
MAC_ARG(sm->associnfo.bssid)); MAC_ARG(sm->associnfo.bssid));
return 0; goto out;
} else { } else {
dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
spin_lock_irqsave(&sm->lock,flags);
/* Cancel assoc work */ /* Cancel assoc work */
cancel_delayed_work(&sm->associnfo.work); cancel_delayed_work(&sm->associnfo.work);
/* We don't have to do this, but it's a little cleaner */ /* We don't have to do this, but it's a little cleaner */
@ -98,14 +98,13 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
cancel_delayed_work(&authptr->work); cancel_delayed_work(&authptr->work);
sm->associnfo.bssvalid = 0; sm->associnfo.bssvalid = 0;
sm->associnfo.bssfixed = 0; sm->associnfo.bssfixed = 0;
spin_unlock_irqrestore(&sm->lock,flags);
flush_scheduled_work(); flush_scheduled_work();
sm->associnfo.associating = 0;
sm->associnfo.associated = 0;
} }
} }
spin_lock_irqsave(&sm->lock, flags);
sm->associnfo.static_essid = 0; sm->associnfo.static_essid = 0;
sm->associnfo.assoc_wait = 0; sm->associnfo.assoc_wait = 0;
@ -121,10 +120,12 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
* If applicable, we have already copied the data in */ * If applicable, we have already copied the data in */
sm->associnfo.req_essid.len = length; sm->associnfo.req_essid.len = length;
sm->associnfo.associating = 1;
/* queue lower level code to do work (if necessary) */ /* queue lower level code to do work (if necessary) */
schedule_work(&sm->associnfo.work); schedule_work(&sm->associnfo.work);
out:
mutex_unlock(&sm->associnfo.mutex);
spin_unlock_irqrestore(&sm->lock, flags);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid);
@ -136,10 +137,8 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev,
char *extra) char *extra)
{ {
struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
unsigned long flags;
/* avoid getting inconsistent information */ mutex_lock(&sm->associnfo.mutex);
spin_lock_irqsave(&sm->lock, flags);
/* If all fails, return ANY (empty) */ /* If all fails, return ANY (empty) */
data->essid.length = 0; data->essid.length = 0;
data->essid.flags = 0; /* active */ data->essid.flags = 0; /* active */
@ -152,12 +151,13 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev,
} }
/* If we're associating/associated, return that */ /* If we're associating/associated, return that */
if (sm->associated || sm->associnfo.associating) { if (sm->associnfo.associated || sm->associnfo.associating) {
data->essid.length = sm->associnfo.associate_essid.len; data->essid.length = sm->associnfo.associate_essid.len;
data->essid.flags = 1; /* active */ data->essid.flags = 1; /* active */
memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len);
} }
spin_unlock_irqrestore(&sm->lock, flags); mutex_unlock(&sm->associnfo.mutex);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid);
@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_device *net_dev,
{ {
struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
int err = 0; int err = 0;
unsigned long flags;
spin_lock_irqsave(&mac->lock, flags); mutex_lock(&mac->associnfo.mutex);
if (mac->associnfo.bssvalid) if (mac->associnfo.bssvalid)
memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN);
else else
memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); memset(data->ap_addr.sa_data, 0xff, ETH_ALEN);
data->ap_addr.sa_family = ARPHRD_ETHER; data->ap_addr.sa_family = ARPHRD_ETHER;
spin_unlock_irqrestore(&mac->lock, flags); mutex_unlock(&mac->associnfo.mutex);
return err; return err;
} }
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap);
@ -342,28 +342,27 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
char *extra) char *extra)
{ {
struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
unsigned long flags;
/* sanity check */ /* sanity check */
if (data->ap_addr.sa_family != ARPHRD_ETHER) { if (data->ap_addr.sa_family != ARPHRD_ETHER) {
return -EINVAL; return -EINVAL;
} }
spin_lock_irqsave(&mac->lock, flags); mutex_lock(&mac->associnfo.mutex);
if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { if (is_broadcast_ether_addr(data->ap_addr.sa_data)) {
/* the bssid we have is not to be fixed any longer, /* the bssid we have is not to be fixed any longer,
* and we should reassociate to the best AP. */ * and we should reassociate to the best AP. */
mac->associnfo.bssfixed = 0; mac->associnfo.bssfixed = 0;
/* force reassociation */ /* force reassociation */
mac->associnfo.bssvalid = 0; mac->associnfo.bssvalid = 0;
if (mac->associated) if (mac->associnfo.associated)
schedule_work(&mac->associnfo.work); schedule_work(&mac->associnfo.work);
} else if (is_zero_ether_addr(data->ap_addr.sa_data)) { } else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
/* the bssid we have is no longer fixed */ /* the bssid we have is no longer fixed */
mac->associnfo.bssfixed = 0; mac->associnfo.bssfixed = 0;
} else { } else {
if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) {
if (mac->associnfo.associating || mac->associated) { if (mac->associnfo.associating || mac->associnfo.associated) {
/* bssid unchanged and associated or associating - just return */ /* bssid unchanged and associated or associating - just return */
goto out; goto out;
} }
@ -378,7 +377,8 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
} }
out: out:
spin_unlock_irqrestore(&mac->lock, flags); mutex_unlock(&mac->associnfo.mutex);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap);
@ -395,6 +395,7 @@ ieee80211softmac_wx_set_genie(struct net_device *dev,
char *buf; char *buf;
int i; int i;
mutex_lock(&mac->associnfo.mutex);
spin_lock_irqsave(&mac->lock, flags); spin_lock_irqsave(&mac->lock, flags);
/* bleh. shouldn't be locked for that kmalloc... */ /* bleh. shouldn't be locked for that kmalloc... */
@ -432,6 +433,8 @@ ieee80211softmac_wx_set_genie(struct net_device *dev,
out: out:
spin_unlock_irqrestore(&mac->lock, flags); spin_unlock_irqrestore(&mac->lock, flags);
mutex_unlock(&mac->associnfo.mutex);
return err; return err;
} }
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie);
@ -447,6 +450,7 @@ ieee80211softmac_wx_get_genie(struct net_device *dev,
int err = 0; int err = 0;
int space = wrqu->data.length; int space = wrqu->data.length;
mutex_lock(&mac->associnfo.mutex);
spin_lock_irqsave(&mac->lock, flags); spin_lock_irqsave(&mac->lock, flags);
wrqu->data.length = 0; wrqu->data.length = 0;
@ -459,6 +463,8 @@ ieee80211softmac_wx_get_genie(struct net_device *dev,
err = -E2BIG; err = -E2BIG;
} }
spin_unlock_irqrestore(&mac->lock, flags); spin_unlock_irqrestore(&mac->lock, flags);
mutex_lock(&mac->associnfo.mutex);
return err; return err;
} }
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie);
@ -473,10 +479,13 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
struct iw_mlme *mlme = (struct iw_mlme *)extra; struct iw_mlme *mlme = (struct iw_mlme *)extra;
u16 reason = cpu_to_le16(mlme->reason_code); u16 reason = cpu_to_le16(mlme->reason_code);
struct ieee80211softmac_network *net; struct ieee80211softmac_network *net;
int err = -EINVAL;
mutex_lock(&mac->associnfo.mutex);
if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) {
printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n"); printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n");
return -EINVAL; goto out;
} }
switch (mlme->cmd) { switch (mlme->cmd) {
@ -484,14 +493,22 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data); net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data);
if (!net) { if (!net) {
printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
return -EINVAL; goto out;
} }
return ieee80211softmac_deauth_req(mac, net, reason); return ieee80211softmac_deauth_req(mac, net, reason);
case IW_MLME_DISASSOC: case IW_MLME_DISASSOC:
ieee80211softmac_send_disassoc_req(mac, reason); ieee80211softmac_send_disassoc_req(mac, reason);
return 0; mac->associnfo.associated = 0;
mac->associnfo.associating = 0;
err = 0;
goto out;
default: default:
return -EOPNOTSUPP; err = -EOPNOTSUPP;
} }
out:
mutex_unlock(&mac->associnfo.mutex);
return err;
} }
EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme);